消息与事件 ========================================= 杰理玩具系列SDK支持的消息见下图1: .. image:: 0-1-msg.png :alt: "图1 消息列表图“ :align: center .. centered:: 图1 消息列表图 杰理玩具系列SDK目前支持的事件见下图2,事件最多支持32种,系统已经定义的事件如图2。如果用户要增加其它事件需同时在msg.h和msg.c的event2msg[]同样顺序下加入事件。 .. image:: 0-2-event.png :alt: "图2 已有事件列表图“ :align: center .. centered:: 图2 已有事件列表图 消息与事件的目录位于:apps/include_lib/msg/msg.h。 其中主要的函数有: :: void event_init(void); void message_init(); static u32 event2msg_api(u32 event); bool get_event_status(u32 event); void clear_one_event(u32 event); int get_msg(int len , int *msg); int post_event(int event); int post_msg(inc argc , ...); void clear_all_message(void); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 消息与事件使用一般流程 ################################ 在开机时先调用event_init()、message_init()对消息系统初始化,主要初始化一些消息列表相关变量及事件状态变量。初始化后有用到消息的地方就可以设置消息或获取消息。 - a.开机调用event_init()及message_init()完成对事件和消息的初始化; - b.调用post_event(int event)标记事件,调用post_msg(int argc, ...)标记消息; - c.调用get_msg(int len, int \*msg)获取事件消息或其他消息; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 消息(msg)函数 ################################ 这是一种基于FIFO结构循环池的消息机制。当消息池累计太多消息,导致消息池满后,会写不进消息。 函数void message_init() **************************************************************************************************** 此函数会初始化消息信息,将msg_cbuf结构体消息状态清空,这一步一般在开机时进行。 函数int post_msg(int argc, ...) **************************************************************************************************** 当某个消息发生时,本函数实现将消息放入消息列表: :: 1、argc:后面可变参数(...)的数量; 2、. . .:可变参数,参数个数可变,可带入一个或多个文件; 可变参数(...)有参考下表; 3、返回值:MSG_NO_ERROR无实际作用; ======================= ================================================== 消息 详情 ======================= ================================================== MSG_500MS ticktime时钟到500ms消息 MSG_PRIV_FILE 播放前一个文件消息 MSG_NEXT_FILE 播放下一个文件消息 MSG_NEXT_DIR 播放下一个文件夹消息 MSG_PLAY_FILE1, 播放文件1消息 MSG_PLAY_FILE2, 播放文件2消息 MSG_PP, 播放文件1暂停消息 MSG_PP_2, 播放文件2暂停消息 MSG_VOL_UP 播放声音增大消息 MSG_VOL_DOWN 播放声音减小消息 MSG_A_PLAY 播放文件A消息 MSG_REC_MODE_SWITCH 开始录音与开始播放录音切换消息 MSG_REC_SPEED_EN 录音速率模式使能消息 MSG_MIDI_MODE_SWITCH midi模式切换消息 MSG_MIDI_OKON_GOON midi one key one note mode下一音节消息 MSG_NEXT_MODE app模式切换消息 MSG_RECODE_START 重新编码开始消息 MSG_RECODE_END 重新编码结束消息 MSG_LOW_POWER 低电消息 MSG_ENTER_IDLE cpu进入空闲消息 MSG_POWER_OFF 关机消息 ======================= ================================================== 函数int get_msg(int len, int \*msg) **************************************************************************************************** 本函数实现获取事件对应的消息信息以及消息列表中消息的功能当获取到事件消息时,不在获取消息列表中消息,当没有事件消息时,查询消息列表,如果有消息,这保存消息信息到形参msg。形参msg需要自定义。 :: 1、len:形参msg的长度 长度由实际要获取的消息长度决定,msg长度小于要获取的消息长度时返回MSG_BUF_NOT_ENOUGH错误信息; 2、msg:保存获取到的消息信息(可获取到的消息如图1 消息列表图); 3、返回值: MSG_NO_ERROR:获取消息无误 MSG_BUF_NOT_ENOUGH:形参len长度小于实际消息长度 可获取到的消息如图1 消息列表图 函数void clear_all_message(void) **************************************************************************************************** 本函数实现清除所有消息的功能,清除后消息列表为空,没有消息可获取。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 事件(EVENT)函数 ################################ 这是一种基于位图的事件机制。 - 每个事件占一个比特,当写入某个事件时,对应比特位会被置一; - 当读取某个事件,对应比特位如果为一,那么返回时间并清除对应比特位;否者返回空事件; - 由于上述两点的原因,所以某个事件在读取之前被多次写入后,也仅会响应一次。 以下代码段是所有事件的定义: :: #define NO_EVENT 0xffff #define EVENT_F1A1_END 0 #define EVENT_F1A1_ERR 1 #define EVENT_F1A1_LOOP 2 #define EVENT_F1A2_END 3 #define EVENT_F1A2_ERR 4 #define EVENT_F1A2_LOOP 5 #define EVENT_MIDI_END 6 #define EVENT_MIDI_ERR 7 // --8 #define EVENT_A_END 9 #define EVENT_A_ERR 10 #define EVENT_A_LOOP 11 #define EVENT_MP3_END 12 #define EVENT_MP3_ERR 13 #define EVENT_MP3_LOOP 14 #define EVENT_WAV_END 15 #define EVENT_WAV_ERR 16 #define EVENT_WAV_LOOP 17 #define EVENT_APP_SW_ACTIVE 18 #define EVENT_WFILE_FULL 19 #define EVENT_OTG_IN 20 #define EVENT_OTG_OUT 21 #define EVENT_UDISK_IN 22 #define EVENT_UDISK_OUT 23 #define EVENT_PC_IN 24 #define EVENT_PC_OUT 25 #define EVENT_PC_SPK 26 #define EVENT_PC_MIC 27 #define EVENT_SD0_IN 28 #define EVENT_SD0_OUT 29 #define EVENT_AUX_IN 30 #define EVENT_AUX_OUT 31 #define EVENT_EXTFLSH_IN 32 #define EVENT_HALF_SECOND 31 .. centered:: 代码段1 事件定义列表 下表为事件列表: ====================== =========================================== 事件列表 含义 ====================== =========================================== EVENT_F1A1_END F1A1文件播放结束事件 EVENT_F1A1_ERR F1A1文件播放错误事件 EVENT_F1A1_LOOP F1A1文件播放循环事件 EVENT_F1A2_END F1A2文件播放结束事件 EVENT_F1A2_ERR F1A2文件播放错误事件 EVENT_F1A2_LOOP F1A2文件播放循环事件 EVENT_MIDI_END MIDI文件播放结束事件 EVENT_MIDI_ERR MIDI文件播放错误事件 EVENT_A_END A文件播放结束事件 EVENT_A_ERR A文件播放错误事件 EVENT_A_LOOP A文件播放循环事件 EVENT_MP3_END MP3文件播放结束事件 EVENT_MP3_ERR MP3文件播放错误事件 EVENT_MP3_LOOP MP3文件播放循环事件 EVENT_WAV_END WAV文件播放结束事件 EVENT_WAV_ERR WAV文件播放错误事件 EVENT_WAV_LOOP WAV文件播放循环事件 EVENT_APP_SW_ACTIVE APP切换活跃事件 EVENT_WFILE_FULL 空间已满事件 EVENT_OTG_IN OTG插入事件 EVENT_OTG_OUT OTG拔出事件 EVENT_UDISK_IN U盘插入事件 EVENT_UDISK_OUT U盘拔出事件 EVENT_PC_IN PC插入事件 EVENT_PC_OUT PC拔出事件 EVENT_PC_SPK 音箱插入事件 EVENT_PC_MIC 麦克风插入事件 EVENT_SD0_IN SD卡插入事件 EVENT_SD0_OUT SD卡拔出事件 EVENT_AUX_IN 音频接口接入事件 EVENT_AUX_OUT 音频接口拔出事件 EVENT_EXTFLSH_IN 外部FLASH插入事件 NO_EVENT 无事件发生 ====================== =========================================== .. centered:: 表3.1 事件列表 函数void event_init(void) **************************************************************************************************** 此函数会初始化事件状态信息,将event_buf事件状态清空(清楚整个事件表),这一步一般在开机时进行。 函数u32 event2msg_api(u32 event) **************************************************************************************************** 此函数实现根据事件event信息获取对应的消息信息的功能。 :: 1、event:事件编号,定义在“代码段1 事件定义列表”; 2、返回值:与事件对应的消息信息; 事件与消息翻译表如下代码段: :: static const u16 event2msg[] = { MSG_F1A1_FILE_END, /* 0 */ MSG_F1A1_FILE_ERR, /* 1 */ MSG_F1A1_LOOP, MSG_F1A2_FILE_END, MSG_F1A2_FILE_ERR, MSG_F1A2_LOOP, /* 5 */ MSG_MIDI_FILE_END, MSG_MIDI_FILE_ERR, NO_MSG, MSG_A_FILE_END, MSG_A_FILE_ERR, /* 10 */ MSG_A_LOOP, MSG_MP3_FILE_END, MSG_MP3_FILE_ERR, MSG_MP3_LOOP, MSG_WAV_FILE_END, /* 15 */ MSG_WAV_FILE_ERR, MSG_WAV_LOOP, MSG_APP_SWITCH_ACTIVE, MSG_WFILE_FULL, MSG_OTG_IN, /* 20 */ MSG_OTG_OUT, MSG_USB_DISK_IN, MSG_USB_DISK_OUT, MSG_PC_IN, MSG_PC_OUT, /* 25 */ MSG_PC_SPK, /* 26 */ MSG_PC_MIC, /* 27 */ MSG_SDMMCA_IN, MSG_SDMMCA_OUT, MSG_AUX_IN, MSG_AUX_OUT, MSG_EXTFLSH_IN, NO_MSG, }; .. centered:: 代码段2 事件翻译到消息的列表 函数int post_event(int event) **************************************************************************************************** 当某个事件event发生时,本函数实现将事件event对应的事件状态标号(event_buf里相应的位)设置为1。只有事件event状态位被置1后,消息获取函数get_msg才能获取到与事件对应的消息。 事件最多支持32种,系统已经定义的事件如图2。事件发生与不发生的状态32位的变量event_buf表示; 其中变量的每个位表示一个事件的状态(1:事件发生;0:事件未发生)。 当某个事件event发生时对应的位将被置1,其它位状态不变。 如果用户需求事件量高于32,其事件可类似定义变量和事件宏,用变量位表示其状态,并修改文件中本函数post_event、get_event函数及事件消息对照数组event2msg[EVENT_TOTAL]等使其支持高于32种事件的事件。 :: 1、event:事件列表中的某个事件,位置见上“表3.1 事件列表”,可选事件: 2、返回值:返回无误信息MSG_NO_ERROR,返回值无作用; 函数bool get_event_status(u32 event) **************************************************************************************************** 本函数实现获取事件event状态的功能。 :: 1、event:事件序号,位置见上“表3.1 事件列表”为可选事件: 2、返回值: 1:事件进行中 0:事件未执行