Huawei_LiteOS——初始化配置

举报
i小龙 发表于 2018/12/28 19:16:48 2018/12/28
【摘要】 介绍了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,实现多任务的处理。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。