CH57x 的蓝牙中,为了方便其协议栈自身的管理,以及用户的使用,使用一个非常轻量级的操作系统"TMOS",
TMOS 实际上就是OSAL的简化版本,
[一些常用的API]
//tmosTaskID taskID //以不同的taskid 来区分不同的任务,越小优先级越高 //tmosEvents event //每个task 下拥有的event,16bit,每bit代表一个event,对于同一个task,一共16个event,其中0x8000为系统使用,剩下15个为用户使用 //注册task id,一般用于注册任务时候,首先执行的 tmosTaskID TMOS_ProcessEventRegister( pTaskEventHandlerFn eventCb ); //设置一个event,,根据taskid 和event 来决定具体的事件 bStatus_t tmos_set_event( tmosTaskID taskID, tmosEvents event ); //清理一个已经超时的event,不能在自己的event 函数内执行 tmos_clear_event( tmosTaskID taskID, tmosEvents event ); //开始一个定时事件,只执行一次, //tmosTimer具体是 1600 = 1s bStatus_t tmos_start_task( tmosTaskID taskID, tmosEvents event, tmosTimer time ); //开始一个定时事件,不断的执行,除非运行tmos_stop_task关掉, //tmosTimer具体是 1600 = 1s bStatus_t tmos_start_reload_task( tmosTaskID taskID, tmosEvents event, tmosTimer time ); //停止一个定时事件 bStatus_t tmos_stop_task( tmosTaskID taskID, tmosEvents event ); //获取对应taskid 和event 的最后一个周期时常,返回0是没有找到. tmosTimer tmos_get_task_timer( tmosTaskID taskID, tmosEvents event ); bStatus_t tmos_msg_send( tmosTaskID taskID, uint8_t *msg_ptr ); uint8_t *tmos_msg_receive( tmosTaskID taskID ); uint8_t *tmos_msg_allocate( uint16_t len ); bStatus_t tmos_msg_deallocate( uint8_t *msg_ptr ); uint8_t tmos_snv_read( uint8_t id, uint8_t len, void *pBuf); //tmos的系统处理函数,需要不断在主函数中运行 void TMOS_SystemProcess( void ); //返回tmos系统运行的clock,1600=1s uint32_t TMOS_GetSystemClock( void ); uint32_t tmos_rand( void ); // pseudo-random number bool tmos_memcmp( const void *src1, const void *src2, uint32_t len ); // TRUE - same, FALSE - different bool tmos_isbufset( uint8_t *buf, uint8_t val, uint32_t len ); // TRUE if all "val",FALSE otherwise uint32_t tmos_strlen( char *pString ); uint32_t tmos_memset( void * pDst, uint8_t Value, uint32_t len ); void tmos_memcpy( void *dst, const void *src, uint32_t len ); // Generic memory copy.
[示例代码]
"tmos_demo_task.h"
#include "CH57x_common.h" #include "CH57xBLE_LIB.H" #include "stdint.h" #define DEMO_TASK_TMOS_EVT_TEST_1 (0x01<<0) #define DEMO_TASK_TMOS_EVT_TEST_2 (0x01<<1) #define DEMO_TASK_TMOS_EVT_TEST_3 (0x01<<2) #define DEMO_TASK_TMOS_EVT_TEST_4 (0x01<<3) #define DEMO_TASK_TMOS_EVT_TEST_5 (0x01<<4) void demo_task_init(void);
"tmos_demo_task.c"
#include "tmos_demo_task.h" //存储 当前task id 的全局变量 tmosTaskID demo_task_id = INVALID_TASK_ID; //系统消息处理的函数 static void demo_task_process_TMOSMsg( tmos_event_hdr_t *pMsg ){ switch ( pMsg->event ) { default: PRINT("pMsg->event %04x\r\n",pMsg->event); break; } } //task的event处理回调函数,需要在注册task时候,传进去 static tmosTaskID demo_task_process_event( uint8_t task_id, uint16_t events ){ if ( events & SYS_EVENT_MSG ) { uint8_t *pMsg; if ( (pMsg = tmos_msg_receive( demo_task_id )) != NULL ) { demo_task_process_TMOSMsg( (tmos_event_hdr_t *)pMsg ); // Release the TMOS message tmos_msg_deallocate( pMsg ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } //event 处理 if(events & DEMO_TASK_TMOS_EVT_TEST_1){ PRINT("DEMO_TASK_TMOS_EVT_TEST_1 evt test \r\n"); return (events ^ DEMO_TASK_TMOS_EVT_TEST_1); } //event 处理 if(events & DEMO_TASK_TMOS_EVT_TEST_2){ tmos_start_task(demo_task_id,DEMO_TASK_TMOS_EVT_TEST_3,1600); PRINT("DEMO_TASK_TMOS_EVT_TEST_2 evt test \r\n"); return (events ^ DEMO_TASK_TMOS_EVT_TEST_2); } //event 处理 if(events & DEMO_TASK_TMOS_EVT_TEST_3){ tmos_start_task(demo_task_id,DEMO_TASK_TMOS_EVT_TEST_3,1600); PRINT("DEMO_TASK_TMOS_EVT_TEST_3 evt test \r\n"); return (events ^ DEMO_TASK_TMOS_EVT_TEST_3); } // Discard unknown events return 0; } //初始化task, //包括注册函数,可以注册后去开启event void demo_task_init( void ){ //注册task id,同事把该task的event处理函数传进去 demo_task_id = TMOS_ProcessEventRegister( demo_task_process_event ); //立即开始一个event tmos_set_event(demo_task_id,DEMO_TASK_TMOS_EVT_TEST_1); //开始一个定时event,1s后产生,当前语句只会产生一次event //可以在event产生后去开启event,可以是别的task的,也可以是当前task的event tmos_start_task(demo_task_id,DEMO_TASK_TMOS_EVT_TEST_2,1600); }
[注意事项]
- 禁止在中断服务函数里面去处理tmos的任何event之类的的开始停止,之类的, 由于tmos的event操作,实际上就是状态机的操作,会产生全局变量修改,
- tmos的event 里面是阻塞执行的,直到return 后才会释放,所以通常不建议在event 里面处理太多东西