大家好,欢迎来到IT知识分享网。
目录
2.电源管理:osal_pwrmgr_device( PWRMGR_BATTERY );
前言
学习SOAL操作系统笔记。
一、OSAL是什么?
OSAL主要是这样一种机制,一种任务分配资源的机制,从而形成了一个简单多任务的操作系统。首先,osal初始化系统,包括软件系统初始化和资源初始化.其中软件系统初始化就是初始化一些变量,比如osal重要的组成部分任务表,任务结构体和序列号.资源初始化主要包括内存,中断,NV等各种设备模块资源.这就和我们嵌入式系统中的RTOS操作系统μC/OS-II有了很大的相似处。μC/OS-II中也是通过建立任务把一个问题进行分解,任务之间可以通过消息队列的方式进行通信。
接着,osal通过osal_add_task添加任务到任务表中,形成一个任务链表.这个任务链表是以任务的优先级先后排序的.优先级高的排在前,低者排于后.
最后,开始运行系统,系统是以一个死循环的形式工作的.在循环体当中不断地检测各个任务,看是否要运行等.这就相当于我们平时用的linux和window等多任务系统,把CPU分成N个时间片(有多少任务就分成多少时间片),只要处理频率高,就相当于多任务同时运行了 。
启动操作系统
int app_main(void) { /* Initialize the operating system */ osal_init_system(); osal_pwrmgr_device( PWRMGR_BATTERY ); /* Start OSAL */ osal_start_system(); // No Return from here return 0; }
1.初始化操作系统:osal_init_system();
//通过创建定义在任务表【OSAL_Tasks.h】中的任务来初始化任务系统【OSAL.c】 byte osal_init_system( void ) { //初始化内存分配系统【OSAL_Memory.c】 osal_mem_init(); //初始化消息队列,其实就是一个指针 osal_qHead = NULL; //初始化系统定时器【OSAL_Timers.c】 osalTimerInit(); //初始化电源管理系统 osal_pwrmgr_init(); //初始化系统任务,为每个任务调用初始化函数 osalInitTasks(); //Setup efficient search for the first free block of heap. //跳过第一个块 osal_mem_kick(); return ( ZSUCCESS ); }
- osal_init_system(); //初始化操作系统,主要是堆栈,时钟,电源模式,任务号分配
- osalInitTasks函数:每个任务调用初始化函数,且需要与任务处理函数数组表tasksArr对应
// The order in this table must be identical to the task initialization calls below in osalInitTask. const pTaskEventHandlerFn tasksArr[] = { LL_ProcessEvent, // task 0 HCI_ProcessEvent, // task 1 #if defined ( OSAL_CBTIMER_NUM_TASKS ) OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 3 #endif L2CAP_ProcessEvent, // task 2 SM_ProcessEvent, // task 3 GAP_ProcessEvent, // task 4 GATT_ProcessEvent, // task 5 GAPRole_ProcessEvent, // task 6 #if (DEF_GAPBOND_MGR_ENABLE==1) GAPBondMgr_ProcessEvent, // task , add 2017-11-15 #endif GATTServApp_ProcessEvent, // task 7 SimpleBLEPeripheral_ProcessEvent, // task 8 NBUartProcessEvent, // task 9 NBTSLProcessEvent, // task 10 NB_ALProcessEvent, // task 11 APP_UsrProcessEvent, // task 12 }; /* @fn osalInitTasks @brief This function invokes the initialization function for each task. @param void @return none */ 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++ ); /* 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++ ); /* SM Task */ SM_Init( taskID++ ); /* GAP Task */ GAP_Init( taskID++ ); /* GATT Task */ GATT_Init( taskID++ ); /* Profiles */ GAPRole_Init( taskID++ ); #if(DEF_GAPBOND_MGR_ENABLE==1) GAPBondMgr_Init( taskID++ ); // 2017-11-15 #endif GATTServApp_Init( taskID++ ); /* Application */ SimpleBLEPeripheral_Init( taskID++ ); NBUartInit( taskID++ ,NBReceiveMSGCheack); NBTSL_Init( taskID++ ); NB_AL_Init( taskID++ ); APP_UsrInit( taskID++ ); }
2.电源管理:osal_pwrmgr_device( PWRMGR_BATTERY );
设置是否允许进入低功耗状态。
3.任务轮训处理: osal_start_system();
轮训扫描待处理的时间,查找任务索引号,按顺序查找故索引号小的先处理。由此可见任务优先级和索引号相关,索引号越小优先级越高。然后通过索引调用对应的任务处理函数。
void osal_start_system( void ) { #if !defined ( ZBIT ) && !defined ( UBIT ) for(;;) // Forever Loop #endif { uint8 idx = 0; osalTimeUpdate(); //扫描哪个事件被触发了,然后置相应的标志位 Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer(). do { if (tasksEvents[idx]) // Task is highest priority that is ready. { break; //得到待处理的最高优先级任务索引号 idx } } 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); //退出临界区 events = (tasksArr[idx])( idx, events ); ///通过指针调用任务处理函数,关键 HAL_ENTER_CRITICAL_SECTION(intState); ///进入临界区 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 } }
事件处理函数
1.设置任务事件:
uint8 osal_set_event( uint8 task_id, uint16 event_flag );
为任务号为task_id的任务设置一个ID为event_flag的事件。下次轮训到此任务时立即处理此事件。
2.创建一个定时器事件:
uint8 osal_start_timerEx( uint8 task_id, uint16 event_id, uint32 timeout_value );
在timeout_value毫秒后,为任务号为task_id的任务设置一个ID为event_flag的事件。下次轮训到此任务时立即处理此事件。
总结
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/137981.html