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.
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)
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Bluetooth cannot discover CHAR1
- LLAKG: Arduino automatic watering system (Episode 3: C language program upgrade and function optimization)
- [NXP Rapid IoT Review] - NXP Rapid IOT Studio Experience
- TI Signal Chain and Power Q&A Series Live Broadcast - USB Type-C Special Prize Live Broadcast in Progress!
- The Structure and Interpretation of Computer Programs (2nd Edition)
- Teacher maychang's new work - interesting video about the history of electronic technology: the debate between AC and DC
- Detailed description of the debugging document of the NUCLEO-G431RB+IHM08-V4 three-resistor FOC (5.4.1 library) motor control board
- Interference Analysis and Countermeasures in High-Frequency PCB Design
- TI - MCU - MSP430 User Guide 13 -> Timer module
- Understanding characteristic impedance