新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM學習筆記--初識uC/OS(一)

        ARM學習筆記--初識uC/OS(一)

        作者: 時間:2016-11-10 來源:網絡 收藏
        下面就直接進程序看吧,首先看mian函數

        int main(void)
        {
        INT8U os_err;//OS error
        Bsp_init();//Embedded development board Initialization//開發板初始化
        OSInit();//uC/OS initialization//系統初始化
        os_err = OSTaskCreateExt((void (*)(void *)) App_Task_LCD,//創建任務
        (void * ) 0,
        (OS_STK * )&App_TaskLCDStk[APP_TASK_LCD_STK_SIZE-1],
        (INT8U ) APP_TASK_LCD_PRIO,
        (INT16U ) APP_TASK_LCD_PRIO,
        (OS_STK * )&App_TaskLCDStk[0],
        (INT32U ) APP_TASK_LCD_STK_SIZE,
        (void * ) 0,
        (INT16U )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK));

        OSStart(); //uC/OS start multitasking//開始任務運行
        }

        本文引用地址:http://www.104case.com/article/201611/317283.htm開發板的初始化就是對arm單片機的引腳和時鐘等等運行必要條件進行初始化,這里就不看了,我們來看看OSInit()

        /*
        *********************************************************************************************************
        * INITIALIZATION
        * 初始化
        *
        * Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
        * creating any uC/OS-II object and, prior to calling OSStart().
        × 描述:該函數用于uC/OS-II系統的內部初始化,它必須在調用uC/OS-II系統的任何創建對象之前,也必須在
        * 函數OSStart()之前執行。也就是說使用uC/OS-II系統的第一步就是執行這個函數,這是一個約定。
        *
        * Arguments : none
        × 傳參 : 無
        *
        * Returns : none
        × 返回值 : 無
        *********************************************************************************************************
        */

        void OSInit (void)
        {
        OSInitHookBegin(); /* Call port specific initialization code */

        OS_InitMisc(); /* Initialize miscellaneous variables */

        OS_InitRdyList(); /* Initialize the Ready List */

        OS_InitTCBList(); /* Initialize the free list of OS_TCBs */

        OS_InitEventList(); /* Initialize the free list of OS_EVENTs */

        #if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
        OS_FlagInit(); /* Initialize the event flag structures */
        #endif

        #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
        OS_MemInit(); /* Initialize the memory manager */
        #endif

        #if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
        OS_QInit(); /* Initialize the message queue structures */
        #endif

        OS_InitTaskIdle(); /* Create the Idle Task */
        #if OS_TASK_STAT_EN > 0
        OS_InitTaskStat(); /* Create the Statistic Task */
        #endif

        #if OS_TMR_EN > 0
        OSTmr_Init(); /* Initialize the Timer Manager */
        #endif

        OSInitHookEnd(); /* Call port specific init. code */

        #if OS_DEBUG_EN > 0
        OSDebugInit();
        #endif
        }

        我們學習的時候不用管這個函數里面到底執行了什么,但是我們必須要學會一點:知道這個函數是在使用uC/OS系統前的第一個需要調用的函數,只要知道這個我們就算知道怎么用它了。
        看下一個函數OSTaskCreateExt

        /*
        *********************************************************************************************************
        * CREATE A TASK (Extended Version)
        * 創建任務(擴展版本)
        *
        * Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either
        * be created prior to the start of multitasking or by a running task. A task cannot be
        * created by an ISR. This function is similar to OSTaskCreate() except that it allows
        * additional information about a task to be specified.
        * 描述: 該函數用于創建一個 uC/OS-II管理的可執行任務.它不是在多個任務執行前被創建就是在一個運行
        * 的任務中被創建.在中斷服務函數中不能創建任務(也就是說在ISR中不能調用該函數). 除了該函數允許一
        *個任務的附加信息被列出外,該函數類同于函數OSTaskCreate().
        *
        * Arguments : task is a pointer to the tasks code
        *
        * p_arg is a pointer to an optional data area which can be used to pass parameters to
        * the task when the task first executes. Where the task is concerned it thinks
        * it was invoked and passed the argument p_arg as follows:
        *
        * void Task (void *p_arg)
        * {
        * for (;;) {
        * Task code;
        * }
        * }
        *
        * ptos is a pointer to the tasks top of stack. If the configuration constant
        * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
        * memory to low memory). ptos will thus point to the highest (valid) memory
        * location of the stack. If OS_STK_GROWTH is set to 0, ptos will point to the
        * lowest memory location of the stack and the stack will grow with increasing
        * memory locations. ptos MUST point to a valid free data item.
        *
        * prio is the tasks priority. A unique priority MUST be assigned to each task and the
        * lower the number, the higher the priority.
        *
        * id is the tasks ID (0..65535)
        *
        * pbos is a pointer to the tasks bottom of stack. If the configuration constant
        * OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high
        * memory to low memory). pbos will thus point to the LOWEST (valid) memory
        * location of the stack. If OS_STK_GROWTH is set to 0, pbos will point to the
        * HIGHEST memory location of the stack and the stack will grow with increasing
        * memory locations. pbos MUST point to a valid free data item.
        *
        * stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,
        * stk_size corresponds to the number of bytes available. If OS_STK is set to
        * INT16U, stk_size contains the number of 16-bit entries available. Finally, if
        * OS_STK is set to INT32U, stk_size contains the number of 32-bit entries
        * available on the stack.
        *
        * pext is a pointer to a user supplied memory location which is used as a TCB extension.
        * For example, this user memory can hold the contents of floating-point registers
        * during a context switch, the time each task takes to execute, the number of times
        * the task has been switched-in, etc.
        *
        * opt contains additional information (or options) about the behavior of the task. The
        * LOWER 8-bits are reserved by uC/OS-II while the upper 8 bits can be application
        * specific. See OS_TASK_OPT_??? in uCOS-II.H. Current choices are:
        *
        * OS_TASK_OPT_STK_CHK Stack checking to be allowed for the task
        * OS_TASK_OPT_STK_CLR Clear the stack when the task is created
        * OS_TASK_OPT_SAVE_FP If the CPU has floating-point registers, save them
        * during a context switch.
        * 傳參:task 任務代碼的一個指針(指向任務代碼段)
        *
        * p_arg 當task第一次運行時,它代表指向一個用于向task傳遞參數的可選數據區域的指針.當task
        * 在連接數據的時候,它被要求和像下面的例子這樣傳遞參數p_arg :
        *
        * void Task (void *p_arg)
        * {
        * for (;;) {
        * Task code;
        * }
        * }
        *
        * ptos 任務棧頂指針.假如OS_STK_GROWTH設置為1,則棧被認為是向低地址推移的(即從高存儲到低
        * 存儲位置).棧頂指針將指向棧所在的存儲器的最高位置.假如OS_STK_GROWTH設置為0,則棧被
        * 認為是向高地址推移的(即從低存儲到高存儲位置).棧頂指針隨內存增加增加. ptos一定指向
        * 一個可用的空閑的數據項.
        *
        * prio 任務的優先級. 每個任務都必須有一個唯一的優先級.優先級數字越小,優先級別越高.
        *
        * id 任務的ID號(0..65535)
        *
        * pbos 任務的棧底指針. 假如OS_STK_GROWTH設置為1,則棧被認為是向低地址推移的(即從高存儲到低
        * 存儲位置).棧底指針將指向棧所在的存儲器的最低位置.假如OS_STK_GROWTH設置為0,則棧被
        * 認為是向高地址推移的(即從低存儲到高存儲位置).棧底指針隨內存增加增加. ptos一定指向
        * 一個可用的空閑的數據項.
        *
        * stk_size 棧的長度.如果OS_STK設置為INT8U,stk_size則為字節數允許.若OS_STK設置為INT16U,stk_size則為十
        * 六位數允許.最后若OS_STK設置為INT32U,stk_size則為32位二進制允許.(指明棧的寬度)
        *
        * pext 是一個指針,指向用戶提供的用于TCB擴展部分的內存空間. 例如:通過上下文切換用戶存儲器能
        * 保持住浮點寄存器的內容、每次任務運行的時間、任務被開關的次數等等.
        *
        * opt 包含任務行為的附加信息(或選項).低八位被uC/OS-II系統作為保留字.高八位作為特殊的應用.這個
        * 選項的設置查看uCOS-II.H.中的OS_TASK_OPT_???.當前選項是:
        * OS_TASK_OPT_STK_CHK 需要進行棧的檢查
        * OS_TASK_OPT_STK_CLR 任務創建時清除棧
        * OS_TASK_OPT_SAVE_FP 假如處理器有浮點數據,保存它們
        *
        * Returns : OS_ERR_NONE if the function was successful.
        * OS_PRIO_EXIT if the task priority already exist
        * (each task MUST have a unique priority).
        * OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
        * (i.e. > OS_LOWEST_PRIO)
        * OS_ERR_TASK_CREATE_ISR if you tried to create a task from an ISR.
        *
        * 返回值 : OS_ERR_NONE 函數執行成功范圍的內容
        * OS_PRIO_EXIT 該任務的優先級已經存在返回該值
        * (每個任務都有一個唯一的優先級).
        * OS_ERR_PRIO_INVALID 設置的優先級大于最大的優先級別返回該值
        * (即 > OS_LOWEST_PRIO)
        * OS_ERR_TASK_CREATE_ISR 當在ISR中創建任務時返回該值(ISR中不允許進行任務創建)
        *********************************************************************************************************
        */
        /*$PAGE*/
        #if OS_TASK_CREATE_EXT_EN > 0
        INT8U OSTaskCreateExt (void (*task)(void *p_arg),
        void *p_arg,
        OS_STK *ptos,
        INT8U prio,
        INT16U id,
        OS_STK *pbos,
        INT32U stk_size,
        void *pext,
        INT16U opt)
        {
        OS_STK *psp;
        INT8U err;
        #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
        /* 分配CPU狀態寄存器的存儲 */
        OS_CPU_SR cpu_sr = 0;
        #endif



        #if OS_ARG_CHK_EN > 0
        if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
        /* 確保優先級在允許的范圍內 */
        return (OS_ERR_PRIO_INVALID);
        }
        #endif
        OS_ENTER_CRITICAL();
        if (OSIntNesting > 0) { /* Make sure we dont create the task from within an ISR */
        /* 確保不在ISR中創建任務 */
        OS_EXIT_CRITICAL();
        return (OS_ERR_TASK_CREATE_ISR);
        }
        if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesnt already exist at this priority */
        /* 確保任務優先級設置沒有重復 */
        OSTCBPrioTbl[prio] = OS_TCB_RESERVED;/* Reserve the priority to prevent others from doing ... */
        /* ... the same thing until task is created. */
        /* 直到任務被創建完成,保留優先級確保其他任務不做同樣的事情 */
        OS_EXIT_CRITICAL();

        #if (OS_TASK_STAT_STK_CHK_EN > 0)
        OS_TaskStkClr(pbos, stk_size, opt); /* Clear the task stack (if needed) */
        /* 清棧 (如需) */
        #endif

        psp = OSTaskStkInit(task, p_arg, ptos, opt); /* Initialize the tasks stack */
        /* 初始化任務棧 */
        err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);
        if (err == OS_ERR_NONE) {
        if (OSRunning == OS_TRUE) { /* Find HPT if multitasking has started */
        /* 在多任務開始后發現HPT */
        OS_Sched();
        }
        } else {
        OS_ENTER_CRITICAL();
        OSTCBPrioTbl[prio] = (OS_TCB *)0; /* Make this priority avail. to others */
        /* 是這個優先級在其他任務中可用 */
        OS_EXIT_CRITICAL();
        }
        return (err);
        }
        OS_EXIT_CRITICAL();
        return (OS_ERR_PRIO_EXIST);
        }
        #endif

        學習創建任務這個函數,我們就要了解的更多,首先必須對每一個傳參要有所了解,在注釋中我已經寫清楚了;第二要知道我們在uC/OS中能創建最多64個進程,由于系統占用了4個還有4個備用,所以我們能創建的只有56個;第三也是最終要的,在任務中我們可以創建新的任務,但是在中斷函數中絕不能創建新的任務,這將會引起未知錯誤。
        再來看函數OSStart()

        /*
        *********************************************************************************************************
        * START MULTITASKING
        * 開始多任務運行
        *
        * Description: This function is used to start the multitasking process which lets uC/OS-II manages the
        * task that you have created. Before you can call OSStart(), you MUST have called OSInit()
        * and you MUST have created at least one task.
        *
        ×描述:該函數用于開啟你已經在uC/OS-II中創建的多任務進程.在調用該函數前,必須已經調用了OSInit()函
        * 數和創建了至少一個進程.
        ×
        * Arguments : none
        *傳參 :無
        *
        * Returns : none
        *返回 : 無
        *
        * Note : OSStartHighRdy() MUST:
        * a) Call OSTaskSwHook() then,
        * b) Set OSRunning to OS_TRUE.
        * c) Load the context of the task pointed to by OSTCBHighRdy.
        * d_ Execute the task.
        * 說明 : OSStartHighRdy() 函數必須使用:
        * a) 然后調用函數OSTaskSwHook(),
        * b) 設置 OSRunning為 OS_TRUE.
        * c) 加載被OSTCBHighRdy指向的內容.
        * d_ 運行任務
        *********************************************************************************************************
        */

        void OSStart (void)
        {
        if (OSRunning == OS_FALSE) {
        OS_SchedNew(); /* Find highest prioritys task priority number */
        OSPrioCur = OSPrioHighRdy;
        OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; /* Point to highest priority task ready to run */
        OSTCBCur = OSTCBHighRdy;
        OSStartHighRdy(); /* Execute target specific code to start task */
        }
        }

        這個函數的學習,我們目前需要知道的只有兩點:一、它必須在OSInit()和OSTaskCreate()之后,因為這樣才有進程開始;二、就是說明里的內容,這個函數的執行是一個按順序執行整個動作。現在我們還不用明白它干了什么,只要知道怎么用就行了。這里需要注意為什么在系統中時序,先后執行的順序這么重要,因為uC/OS系統是一個搶先式的執行系統,如果時序不對,那么就會產生不一樣的結果。
        這就是我才看uC/OS系統的一些理解,在以后的處理過程中,學習到更多的東西,我將會寫出來。個人感覺,看注釋其實是一個非常好的學習方法,雖然注釋是英文很難看懂,但這樣更加準確,看懂了我們也就理解了。


        關鍵詞: ARMuCO

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 正安县| 察哈| 尉氏县| 嘉义市| 阜新| 嘉荫县| 拜泉县| 青海省| 巨鹿县| 平江县| 工布江达县| 恩施市| 大化| 和顺县| 崇仁县| 潮州市| 广州市| 凤冈县| 荔浦县| 通许县| 苍南县| 惠安县| 栖霞市| 农安县| 怀宁县| 乌拉特前旗| 凤凰县| 秭归县| 霍州市| 清原| 佛冈县| 延吉市| 肃北| 遂川县| 呈贡县| 视频| 南雄市| 漾濞| 金山区| 滁州市| 成都市|