uC/OS-II transplantation steps on C51

Publisher:名字太长了吗Latest update time:2016-11-22 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

During this period, uC/OS-II 2.52 has been successfully ported to the 51 MCU. The following are the steps for porting:

1. In the main function, only include
void main(void)
{
     OSInit();
   
     OSStart();
}
to see if it can be compiled. If it can be compiled, proceed to the next step.
2. Verify OSTaskStkInit() and OSStartHighRdy() functions
. First, modify the OS_CFG.H file and set OS_TASK_STAT_EN to 0 to disable the statistical task. Only let the idle task work and execute it in single step until uC/OS-II switches to OS_TaskIdle(). When single stepping, skip the OSInit() function and step into the OSStart() function. Keep single stepping until OSStartHighRdy() is called (this is the last sentence of the OSStart() function), and then step into OSStartHighRdy(). At this time, the compiler should switch to assembly language mode because OSStartHighRdy() is implemented with assembly statements. OSStartRdy() will start running the first task; and there is no application task at this time. Only OS_TaskIdle() can run. If the debugger is running in the OS_TaskIdle() loop and has executed several times in an infinite loop, then it has verified that the OSTaskStkInit() and OSStartHighRdy() functions were successful.

3. Verify the OSCtxSw() function (note that the interrupt is disabled, see OS_Sched() in OS_CORE.C)
If the previous test is successful, this step of code verification is relatively easy, because we already know that the stack structure initialized by OSTaskStkInit() is correct. In this step of the test, an application is added and it switches to the idle task continuously. Before this, it should be ensured that the soft interrupt vector or instruction trap TRAP vector has been correctly set to point to the OSCtxSw() function. Here, uC/OS-II should start executing TestTask() (assuming that the task just created is named it) as the first task, instead of the idle task. You can execute it in single step until the beginning of the TestTask() function. Note that interrupts are not allowed at this time, and the clock beat is not turned on, so OSTimeDly(1) will not return to TestTask(). After scheduling, OSCtxSw() returns to the OS_TaskIdle() task. This shows that the OSCtxSw() function has been successfully transplanted.

#i nclude "includes.h"
OS_STK TestTaskStk[100];


void TestTask(void *ptrdata)
{
    ptrdata=ptrdata;
    while(1)
    {
        OSTimeDly(1);
     }
}

void main(void)
{
   OSInit();
   
   OSTaskCreate(TestTask,(void *)0,&TestTaskStk[99],0); //51 simulation stack? C_XBP increment
   OSStart();
}

3. Verify OSIntCtxSw() and OSTickISR() functions
OSIntCtxSw() is very similar to OSCtxSw() and is simpler than OSCtxSw().
Before this test, you should ensure that the clock interrupt vector points to the clock tick interrupt service subroutine, then initialize the clock tick and enable the interrupt. I use a 100Hz tick here, and the tick speed should match the OS_TICKS_PER_SEC set in OS_CFG.H.
The test code is as follows:
#include "includes.h"
sbit LedBlink=P1^0;

OS_STK TestTaskStk[100];


void TestTask(void *ptrdata)
{
    ptrdata=ptrdata;
 
    OS_ENTER_CRITICAL();

    TMOD=0x01;
    TH0=0xdc; //10ms,100hz
    TL0=0x00;
    TR0=1;
    ET0=1;                         

     OS_EXIT_CRITICAL();   

     while(1)
    {
        OSTimeDly(1);
        if (LedBlink==FALSE)
        {
              LedBlink=TRUE;    

         }else
         { 
            LedBlink=FALSE;   

          }
     }
}

void main(void)
{
   OSInit();
   
   OSTaskCreate(TestTask,(void *)0,&TestTaskStk[99],0); //51 simulation stack? C_XBP increment
   OSStart();
}

The clock tick interrupt calls OSTickISR(), which then calls OSTimeTick.
Note: There must be an interrupt scheduler in OSTickISR, otherwise the idle task cannot switch to other application tasks because the idle task has no task delay function.

After successful compilation, click Run, then set a breakpoint at the TestTask task OSTimeDly(1); and step into it to see if the task can be correctly scheduled to OSTaskIdle(), i.e., the idle task. The idle task will run until it receives a clock beat interrupt (i.e., Timer0). The clock beat interrupt calls OSTickISR(), which then calls OSTimerTick(). OSTimerTick() decrements the .OSTCBDly counter of TestTask() to 0, putting the task into the ready state. When OSTickISR() is completed and calls the OSIntExit() function, OSIntExit() will notice that there is a more important task and TestTask() is already in the ready state waiting to run. At this time, the ISR will no longer return to the idle task, but will switch tasks and return to the TestTask() task. Of course, the above assumes that both OSIntCtxSw() and OSTickISR() functions work properly. If OSIntCtxSw() works properly and the clock frequency has been set to 100Hz (10ms), you can see the LED P1.0 flashing back and forth.

4. Then write the entry program of other interrupt service functions, you can refer to OSTickISR().

5. At this point, the porting of uC/OS-II is OK, more applications can be added, and the real project work can begin.


Reference address:uC/OS-II transplantation steps on C51

Previous article:C51 program for HT1621 driving segment LCD
Next article:An example of how to call an assembly function in KEIL C51 (v6.21)

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号