本篇博文最后修改时间:2016年4月7日,13:16。
一、简介
本篇介绍如何在SimpleBLEPeripheral工程中,添加一个香瓜任务。
(香瓜任务与工程原有任务相互独立,互不影响)
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF(主芯片CC2541)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.net/feilusia
联系方式:[email protected]
技术交流QQ群(香瓜BLE之CC2541):127442605
四、基础知识
1、任务、事件、消息的区别是什么?答:
1)简述
1台设备中有多个任务,1个任务有16个事件,消息用于不同任务之间的传递。
2)详述
任务:SimpleBLEPeripheral工程中从底层的LL层到应用的Application层,一共分为有12个任务,每个任务会分配一个事件管理的变量,变量统一存在:
uint16 *tasksEvents;其中,越底层的优先级越高,应用层的优先级是最低的,也就是此层中的事件是最后才会处理。
事件:1个任务中有16个事件,也就是上面tasksEvents的16位每一位都对应一个事件,0x0001意味着第0位的事件需要被执行。
注意,每个任务的第15位事件(0x8000)是用于不同任务之间的消息传递的,此事件不可被我们编程使用!!!!
消息:用于不同任务之间的传递。
比如,当按键按下时,HAL层检测到了按键,osal会将按键的信息打包,通过消息的形式发往应用层,最终在应用层做按键的处理。
下面举个例子,加强理解。
例如,tasksEvents[11] = 0x0002,那么就意味着,第11个任务的第1位事件需要被执行。
首先,在OSAL_SimpleBLEPeripheral.c中,可以看到第11个任务是应用层。
const pTaskEventHandlerFn tasksArr[] = { LL_ProcessEvent, // task 0 Hal_ProcessEvent, // task 1 HCI_ProcessEvent, // task 2 #if defined ( OSAL_CBTIMER_NUM_TASKS ) OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 3 #endif L2CAP_ProcessEvent, // task 4 GAP_ProcessEvent, // task 5 GATT_ProcessEvent, // task 6 SM_ProcessEvent, // task 7 GAPRole_ProcessEvent, // task 8 GAPBondMgr_ProcessEvent, // task 9 GATTServApp_ProcessEvent, // task 10 SimpleBLEPeripheral_ProcessEvent // task 11 };
// Simple BLE Peripheral Task Events #define SBP_START_DEVICE_EVT 0x0001 #define SBP_PERIODIC_EVT 0x0002
2、是否一定需要添加自己的任务、事件、消息?
答:SimpleBLEPeripheral工程中已经给每个层分配了任务,而osal也把消息机制做好了,因此并不一定要添加自己的任务、消息。
而应用层的事件往往是需要被改动的,比如添加按键事件、通信事件、定时事件、采集事件……
当应用层的16个事件都被你使用完了,这时候才需要考虑新增一个任务,这样又多16个事件可使用。
五、修改代码
1、添加香瓜任务的初始化调用
1)调用香瓜任务的初始化函数(OSAL_SimpleBLEPeripheral.c的osalInitTasks中)
void osalInitTasks( void ) { uint8 taskID = 0; tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); /* LL Task */ LL_Init( taskID++ ); /* Hal Task */ Hal_Init( taskID++ ); /* HCI Task */ HCI_Init( taskID++ ); #if defined ( OSAL_CBTIMER_NUM_TASKS ) /* Callback Timer Tasks */ osal_CbTimerInit( taskID ); taskID += OSAL_CBTIMER_NUM_TASKS; #endif /* L2CAP Task */ L2CAP_Init( taskID++ ); /* GAP Task */ GAP_Init( taskID++ ); /* GATT Task */ GATT_Init( taskID++ ); /* SM Task */ SM_Init( taskID++ ); /* Profiles */ GAPRole_Init( taskID++ ); GAPBondMgr_Init( taskID++ ); GATTServApp_Init( taskID++ ); //香瓜 /* Application */ SimpleBLEPeripheral_Init( taskID++ ); /* 香瓜应用 */ GUA_Init( taskID ); //香瓜 }注意SimpleBLEPeripheral_Init任务的括号中,taskID需要增加。而香瓜任务为最后一个任务,不需要再增加。
2)注册香瓜任务的事件(OSAL_SimpleBLEPeripheral.c中)
const pTaskEventHandlerFn tasksArr[] = { LL_ProcessEvent, // task 0 Hal_ProcessEvent, // task 1 HCI_ProcessEvent, // task 2 #if defined ( OSAL_CBTIMER_NUM_TASKS ) OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 3 #endif L2CAP_ProcessEvent, // task 4 GAP_ProcessEvent, // task 5 GATT_ProcessEvent, // task 6 SM_ProcessEvent, // task 7 GAPRole_ProcessEvent, // task 8 GAPBondMgr_ProcessEvent, // task 9 GATTServApp_ProcessEvent, // task 10 SimpleBLEPeripheral_ProcessEvent, // task 11 //香瓜 GUA_ProcessEvent // task 12 //香瓜 };将香瓜任务中的事件处理函数名称,写到tasksArr中,当osal轮询到有香瓜任务的事件需要执行时,就会执行GUA_ProcessEvent函数。
3)添加香瓜任务的头文件(OSAL_SimpleBLEPeripheral.c中)
//香瓜 #include "GUA.h" //香瓜
2、编写并添加香瓜任务
1)写一个GUA.c(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//****************************************************************************** //name: GUA.c //introduce: 香瓜任务 //author: 甜甜的大香瓜 //changetime: 2016.04.07 //email: [email protected] //****************************************************************************** /*********************头文件************************/ #include "GUA.h" #include "OSAL.h" #include "ioCC2541.h" /*********************宏定义************************/ #define VOID (void) #define GUA_LED_TEST_EVT_PERIOD 1000 /***************内部变量声明************************/ static uint8 GUA_TaskID; // Task ID for internal task/event processing /***************内部函数声明************************/ static void GUA_ProcessOSALMsg( osal_event_hdr_t *pMsg ); //****************************************************************************** //name: GUA_Init //introduce: 香瓜任务的初始化 //parameter: task_id:任务的ID //return: none //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.07 //****************************************************************************** void GUA_Init( uint8 task_id ) { GUA_TaskID = task_id; //执行香瓜任务的启动事件 osal_set_event( GUA_TaskID, GUA_START_DEVICE_EVT ); } //****************************************************************************** //name: GUA_ProcessEvent //introduce: 香瓜任务的事件处理 //parameter: task_id:任务的ID, // events:事件 //return: 返回执行后的事件状态 //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.07 //****************************************************************************** uint16 GUA_ProcessEvent( uint8 task_id, uint16 events ) { VOID task_id; //系统事件 if ( events & SYS_EVENT_MSG ) { uint8 *pMsg; if ( (pMsg = osal_msg_receive( GUA_TaskID )) != NULL ) { GUA_ProcessOSALMsg( (osal_event_hdr_t *)pMsg ); VOID osal_msg_deallocate( pMsg ); } return (events ^ SYS_EVENT_MSG); } //香瓜任务的启动事件 if ( events & GUA_START_DEVICE_EVT ) { osal_start_timerEx( GUA_TaskID, GUA_LED_TEST_EVT, GUA_LED_TEST_EVT_PERIOD ); return ( events ^ GUA_START_DEVICE_EVT ); } //香瓜任务的LED点灯事件 if ( events & GUA_LED_TEST_EVT ) { //test P1_1 = ~P1_1; //这里测试按一次长按键按键,就取反一次P1_1,方便观察P1_1对应的led P1SEL &= ~(1 << 1); //设置为IO口 P1DIR |= (1 << 1); //设置为输出 osal_start_timerEx( GUA_TaskID, GUA_LED_TEST_EVT, GUA_LED_TEST_EVT_PERIOD ); //test return ( events ^ GUA_LED_TEST_EVT ); } return 0; } //****************************************************************************** //name: GUA_ProcessOSALMsg //introduce: 香瓜任务的消息处理 //parameter: pMsg:消息 //return: none //author: 甜甜的大香瓜 //email: [email protected] //changetime: 2016.04.07 //****************************************************************************** static void GUA_ProcessOSALMsg( osal_event_hdr_t *pMsg ) { switch ( pMsg->event ) { default: break; } }
//****************************************************************************** //name: GUA.c //introduce: 香瓜任务头文件 //author: 甜甜的大香瓜 //changetime: 2016.04.07 //email: [email protected] //****************************************************************************** #ifndef GUA_H #define GUA_H #ifdef __cplusplus extern "C" { #endif /*********************头文件************************/ #include "bcomdef.h" /*********************宏定义************************/ #define GUA_START_DEVICE_EVT 0x0001 #define GUA_LED_TEST_EVT 0x0002 /*******************香瓜函数************************/ extern void GUA_Init( uint8 task_id ); extern uint16 GUA_ProcessEvent( uint8 task_id, uint16 events ); #ifdef __cplusplus } #endif #endif
4)在IAR设置中添加香瓜任务的源文件路径
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
六、实验结果
代码下进Smart RF之后,板子上P11引脚对应的LED2会一秒变换一次亮、灭状态。
这个LED2亮灭的测试代码即在香瓜任务中实现的,所以香瓜任务添加成功。