OSAL的运行机理
事件表
函数表
使用查表法来取得事件所对应函数
taskCnt 任务总数
taskEvents 指向事件表首地址的指针
taskArr 事件处理函数数组,每一项都是一个函数指针
由此可以看出,osal是一种基于事件驱动 的轮询式操作系统
在使用共享变量时需要保证变量不被其他变量访问,常用关中断的方法,示例
在OSAL.C文件的osal_start_system()方法中可以看到
HAL_ENTER_CRITICAL_SECTION(intState);//关中断
....
HAL_EXIT_CRITICAL_SECTION(intState);//恢复中断
//osal_start_system()函数的示例代码如下:
void osal_start_system( void )
{
for(;;) // Forever Loop
{
osal_run_system();
}
}
osal_run_system()函数的示例代码如下:
void osal_run_system( void )
{
/*事件表中索引*/
uint8 idx = 0;
#ifndef HAL_BOARD_CC2538
/*更新定时器*/
osalTimeUpdate();
#endif
/*查看硬件方法是否有事件发生*/
Hal_ProcessPoll();
/*循环查看事件表是否有事件发生 */
/*每个二进制位表示一个事件*/
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
if (idx < tasksCnt)
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
/*读取事件*/
events = tasksEvents[idx];
/*事件标志清零*/
tasksEvents[idx] = 0; // Clear the Events for this task.
HAL_EXIT_CRITICAL_SECTION(intState);
/*调用事件处理函数处理*/
activeTaskID = idx;
events = (tasksArr[idx])( idx, events );
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);
/*将未处理的事件重新放到事件表中*/
/*如何在事件处理函数中返回未处理事件?*/
/*SimpleBLEPeripheral_ProcessEvent*/
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
#if defined( POWER_SAVING )
else // Complete pass through all task events with no activity?
{
osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
}
#endif
/* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
{
osal_task_yield();
}
#endif
}
如何在事件处理函数中返回未处理的事件
查看SimpleBLEPeripheral.c文件中的SimpleBLEPeripheral_ProcessEvent()函数,原型如下
uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
VOID t