一、总流程
1.main函数
int main ( )
{
RegisterAssertCback ( AssertHandler) ;
初始化硬件GPIO
Board_initGeneral ( ) ;
VIMSConfigure ( VIMS_BASE, TRUE, TRUE) ;
VIMSModeSet ( VIMS_BASE, VIMS_MODE_ENABLED) ;
# if ! defined ( POWER_SAVING )
Power_setConstraint ( PowerCC26XX_SB_DISALLOW) ;
Power_setConstraint ( PowerCC26XX_IDLE_PD_DISALLOW) ;
# endif
user0Cfg. appServiceInfo-> timerTickPeriod = Clock_tickPeriod;
user0Cfg. appServiceInfo-> timerMaxMillisecond = ICall_getMaxMSecs ( ) ;
初始化ICall软件模块,用于app和stack之间的通信
ICall_init ( ) ;
启动远程任务,对应的ICall的入口点,包含stack任务,优先级5
ICall_createRemoteTasks ( ) ;
初始化app任务,用户要添加一个自定义任务
SimplePeripheral_createTask ( ) ;
开启操作系统,永不返回
BIOS_start ( ) ;
return 0 ;
}
2.app任务创建
2.1创建流程
1. 任务创建函数
void SimplePeripheral_createTask ( void )
{
Task_Params taskParams;
Task_Params_init ( & taskParams) ;
taskParams. stack = spTaskStack;
taskParams. stackSize = SP_TASK_STACK_SIZE;
taskParams. priority = SP_TASK_PRIORITY;
Task_construct ( & spTask, SimplePeripheral_taskFxn, & taskParams, NULL ) ;
}
2. 外设应用任务的入口函数
static void SimplePeripheral_taskFxn ( UArg a0, UArg a1)
{
SimpleBLEPeripheral_init ( ) ;
for ( ; ; )
{
. . . .
这里是处理收到(消息) 事件与定时器事件的地方
. . . .
}
}
3. 外设初始化函数,在此函数里写
SimplePeripheral_init ( void )
2.2周期性事件创建流程
1. 定义时钟结构体
static Clock_Struct clkVeriSion;
2. 创建周期性事件ID和周期的时间(单位毫秒)
# define SP_VERISION_PERIODIC_EVT 11
# define SP_VERISION_PERIOD 2000
3. 将周期性事件ID传递给时钟处理程序的内存
spClockEventData_t argVeriSion =
{ . event = SP_VERISION_PERIODIC_EVT } ;
4.我们的事件,都是用定时器触发,所以,定义定时器时间结构体和事件ID后,注册定时器,通过调用Util_constructClock函数,给事件赋值参数
Util_constructClock ( & clkVeriSion, SimplePeripheral_clockHandler,
SP_VERISION_PERIOD, 0 , false, ( UArg) & argVeriSion) ;
Util_constructClock ( Clock_Struct * pClock,
Clock_FuncPtr clockCB,
uint32_t clockDuration,
uint32_t clockPeriod,
uint8_t startFlag,
UArg arg)
* @param pClock - pointer to clock instance structure. 时钟结构体
* @param clockCB - callback function upon clock expiration. 时钟到期时的回调函数
* @param clockDuration - longevity of clock timer in milliseconds, 时钟的周期时间
* @param clockPeriod - 如果设置为0 以外的值,第一个到期时间由clockDuration决定。
* 所有后使用时钟周期值。
* @param startFlag - TRUE to start immediately, FALSE to wait.
* @param arg - argument passed to callback function. 传递给回调函数的参数,
* 也就是序号3 定义的变量,传递给定时时间到了后的回调函数
* SimplePeripheral_clockHandler ( UArg arg) ,
* 此函数会创建一条消息并将该消息放入RTOS队列
clockPeriod 参数说明:
设置为0 的话是单次定时器,不为0 的话是周期定时器的周期;其区别是单次定时器执行一次完成结束以后就挂了
周期性定时器只要开启一次,会一直执行,除非关掉它。并且当该参数为0 时,定时器的时间分辨率按照
DEFAULT_DISCOVERY_DELAY的设定执行,若非0 ,则定时器第一次运行时的时间分辨率按照
DEFAULT_DISCOVERY_DELAY定时,之后的就按照配置的clockPeriod来执行定时。
再TI给的demo代码中不能显示单次和周期定时器的区别,因为每次循环中执行中断函数时都开启了一次定时器,
所以,看不出区别,只能从Clock的创建函数中的第五个参数区别。
5.消息入队
当定时器时间到了后,进入时钟超时的处理函数SimplePeripheral_clockHandler ( UArg arg)
在此函数中,加入消息入队判断语句,当事件产生后,由函数SimplePeripheral_enqueueMsg入队
else if ( pData-> event == SP_VERISION_PERIODIC_EVT)
{
SimplePeripheral_enqueueMsg ( SP_VERISION_PERIODIC_EVT, NULL ) ;
}
6. app任务循环,处理事件
static void SimplePeripheral_taskFxn ( UArg a0, UArg a1)
{
SimpleBLEPeripheral_init ( ) ;
for ( ; ; )
{
. . . .
这里是处理收到(消息) 事件与定时器事件的地方
. . . .
}
}
在函数内部,判断事件
if ( events & SP_QUEUE_EVT)
{
while ( ! Queue_empty ( appMsgQueueHandle) )
{
spEvt_t * pMsg = ( spEvt_t * ) Util_dequeueMsg ( appMsgQueueHandle) ;
if ( pMsg)
{
在此函数中添加消息处理函数
SimplePeripheral_processAppMsg ( pMsg) ;
ICall_free ( pMsg) ;
}
}
}
比如:
case SP_LED_REVERSE_EVT:
LedStatus = 1 ;
SimplePeripheral_LedReverse_performPeriodicTask ( ) ;
break ;