Huawei_LiteOS——初始化配置
软件环境:Keil 5
Huawei_LiteOS版本:2018年11月21日
完成Startup文件的工作后,代码将从main()函数开始,下面将逐一对其中的函数进行讲解。
int main(void) { UINT32 uwRet = LOS_OK; HardWare_Init(); uwRet = LOS_KernelInit(); if (uwRet != LOS_OK) { return LOS_NOK; } LOS_Inspect_Entry(); LOS_Start(); }
1. HardWare_Init()
这里进行的工作是硬件初始化,可以根据不同的板级驱动进行不同设置。
2. LOS_KernelInit()
内核的初始化的工作就是进行各种函数的初始化。
osRegister()
g_uwTskMaxNum = LOSCFG_BASE_CORE_TSK_LIMIT + 1; /* 设置最大任务数量,+1给空闲任务。 */
osMemSystemInit()
函数内部代码不少,但是真正有用的只有一个osHeapInit()函数,负责初始化堆栈。
osHwiInit()
for(uwIndex = OS_SYS_VECTOR_CNT; uwIndex < OS_VECTOR_CNT; uwIndex++) { m_pstHwiForm[uwIndex] = (HWI_PROC_FUNC)osHwiDefaultHandler; } /* Interrupt vector table location */ SCB->VTOR = (UINT32)m_pstHwiForm;#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */ NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP);#endif
中断向量表重定位,上面定义的是中断向量表的第17(数组下标16)到第257(数组下标为256)。前16个如下所示,定义在文件los_hwi.c中:
HWI_PROC_FUNC m_pstHwiForm[OS_VECTOR_CNT] = { (HWI_PROC_FUNC)0, // [0] Top of Stack (HWI_PROC_FUNC)Reset_Handler, // [1] reset (HWI_PROC_FUNC)osHwiDefaultHandler, // [2] NMI Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [3] Hard Fault Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [4] MPU Fault Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [5] Bus Fault Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [6] Usage Fault Handler (HWI_PROC_FUNC)0, // [7] Reserved (HWI_PROC_FUNC)0, // [8] Reserved (HWI_PROC_FUNC)0, // [9] Reserved (HWI_PROC_FUNC)0, // [10] Reserved (HWI_PROC_FUNC)osHwiDefaultHandler, // [11] SVCall Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [12] Debug Monitor Handler (HWI_PROC_FUNC)0, // [13] Reserved (HWI_PROC_FUNC)osPendSV, // [14] PendSV Handler (HWI_PROC_FUNC)osHwiDefaultHandler, // [15] SysTick Handler};
osTaskInit()
首先,给所有任务分配内存并初始化,按顺序插入到空闲任务链表g_stLosFreeTask中:
for (uwIndex = 0; uwIndex <= LOSCFG_BASE_CORE_TSK_LIMIT; uwIndex++) { g_pstTaskCBArray[uwIndex].usTaskStatus = OS_TASK_STATUS_UNUSED; g_pstTaskCBArray[uwIndex].uwTaskID = uwIndex; LOS_ListTailInsert(&g_stLosFreeTask, &g_pstTaskCBArray[uwIndex].stPendList); }
然后,对全局变量g_stLosTask中记录运行中的任务初始化:
g_stLosTask.pstRunTask = &g_pstTaskCBArray[g_uwTskMaxNum]; g_stLosTask.pstRunTask->uwTaskID = uwIndex; g_stLosTask.pstRunTask->usTaskStatus = (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_RUNNING); g_stLosTask.pstRunTask->usPriority = OS_TASK_PRIORITY_LOWEST + 1;
然后,osPriqueueInit()函数初始化优先级数组g_pstLosPriorityQueueList[OS_PRIORITY_QUEUE_PRIORITYNUM],最多32个优先级,同一优先级的任务以链表形式相连接:
uwSize = OS_PRIORITY_QUEUE_PRIORITYNUM * sizeof(LOS_DL_LIST); g_pstLosPriorityQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, uwSize); for (uwPri = 0; uwPri < OS_PRIORITY_QUEUE_PRIORITYNUM; ++uwPri) { LOS_ListInit(&g_pstLosPriorityQueueList[uwPri]); }
最后,对全局变量g_stTskSortLink进行初始化(这个变量作用没搞清楚):
(VOID)memset((VOID *)pstListObject, 0, uwSize); g_stTskSortLink.pstSortLink = pstListObject; g_stTskSortLink.usCursor = 0; for (uwIndex = 0; uwIndex < OS_TSK_SORTLINK_LEN; uwIndex++, pstListObject++) { LOS_ListInit(pstListObject); }
osTaskMonInit()
其主要工作对g_astTskSwitchInfo这一结构体进行初始化设置,其主要作用是通过任务切换钩子指向的osTaskSwitchCheck函数多任务(堆栈)进行检测,查看是否越界或存在错误。
osSemInit()、osMuxInit()、osQueueInit()
主要的工作是初始化IPC通信。给所有的信号量(信号量的数量最高为20个)分配内存并初始化,按顺序插入至空闲信号量链表g_stUnusedSemList中;给所有的互斥量(互斥量的数量最高为15个)分配内存并初始化,按顺序插入至空闲互斥量链表g_stUnusedMuxList中。给所有的队列(队列的数量最高为10个)分配内存并初始化,按顺序插入至空闲队列链表g_stFreeQueueList中。
osSwTmrInit()
首先,初始化定时器,共16个:
pstSwtmr->usTimerID = 0; pstTemp = pstSwtmr; pstSwtmr++; for (usIndex = 1; usIndex < LOSCFG_BASE_CORE_SWTMR_LIMIT; usIndex++, pstSwtmr++) { pstSwtmr->usTimerID = usIndex; pstTemp->pstNext = pstSwtmr; pstTemp = pstSwtmr; }
然后,创建了定时器消息队列,其队列ID保存在全局变量m_uwSwTmrHandlerQueue中:
uwRet = LOS_QueueCreate((CHAR *)NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &m_uwSwTmrHandlerQueue, 0, sizeof(SWTMR_HANDLER_ITEM_S));
最后,创建了定时器任务,任务执行的函数为osSwTmrTask():
stSwTmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)osSwTmrTask; stSwTmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_SWTMR_STACK_SIZE; stSwTmrTask.pcName = "Swt_Task"; stSwTmrTask.usTaskPrio = 0; uwRet = LOS_TaskCreate(&g_uwSwtmrTaskID, &stSwTmrTask);
osTimesliceInit()
时间片初始化,用于相同优先级任务的切换。
g_stTaskTimeSlice.pstTask = (LOS_TASK_CB *)NULL; g_stTaskTimeSlice.usTout = LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT;
osIdleTaskCreate()
用于创建空闲任务,这个任务在没有其它任务进入就绪态时投入运行,在osIdleTask()无限循环什么都不做。
(VOID)memset((VOID *)(&stTaskInitParam), 0, sizeof(TSK_INIT_PARAM_S)); stTaskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)osIdleTask; stTaskInitParam.uwStackSize = LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE; stTaskInitParam.pcName = "IdleCore000"; stTaskInitParam.usTaskPrio = OS_TASK_PRIORITY_LOWEST; uwRet = LOS_TaskCreate(&g_uwIdleTaskID, &stTaskInitParam);
3. LOS_Inspect_Entry()
在入口中创建了例程任务,任务的执行函数为LOS_Inspect_TskDeal()。在任务执行时,执行LOS_Inspect_TskDeal()函数,创建各种示例:
static osInspect_Def gInspect[LOS_INSPECT_BUFF] = { {LOS_INSPECT_TASK,LOS_INSPECT_STU_START,Example_TskCaseEntry,"TASK"}, {LOS_INSPECT_EVENT,LOS_INSPECT_STU_START,Example_SndRcvEvent,"EVENT"}, {LOS_INSPECT_MSG,LOS_INSPECT_STU_START,Example_MsgQueue,"MSG"}, {LOS_INSPECT_SEM,LOS_INSPECT_STU_START,Example_Semphore,"SEM"}, {LOS_INSPECT_MUTEX,LOS_INSPECT_STU_START,Example_MutexLock,"MUTEX"}, {LOS_INSPECT_SYSTIC,LOS_INSPECT_STU_START,Example_GetTick,"SYSTIC"}, {LOS_INSPECT_TIMER,LOS_INSPECT_STU_START,Example_swTimer,"TIMER"}, {LOS_INSPECT_LIST,LOS_INSPECT_STU_START,Example_list,"LIST"}, {LOS_INSPECT_SMEM,LOS_INSPECT_STU_START,Example_StaticMem,"S_MEM"}, {LOS_INSPECT_DMEM,LOS_INSPECT_STU_START,Example_Dyn_Mem,"D_MEM"}, }
在自己编辑程序时可注释掉此函数。
4. LOS_Start()
首先,使用osTickStart()函数进行嘀嗒时钟的配置,时钟频率选择72MHz的系统时钟,1ms一次中断:
/** * @ingroup los_config * System clock (unit: HZ) */#define OS_SYS_CLOCK (SystemCoreClock)/** * @ingroup los_config * Number of Ticks in one second */#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
最后,通过LOS_StartToRun()函数,将系统的控制权交给OS,实现多任务的处理。
- 点赞
- 收藏
- 关注作者
评论(0)