The code can be downloaded here http://download.csdn.net/detail/king_bingge/5353528
1. How is the real-time performance of uc/OS achieved?
1. The real-time performance of uC/OS is achieved through timed interrupts.
2. When each clock beat arrives, a timer interrupt will be generated. After the interrupt, task scheduling will be performed to run the task with the highest priority in the ready list (the interrupted task will continue to run after a non-preemptive kernel interrupt).
That is, after a period of time, it detects whether there are important tasks that need to be run. If yes, it switches to run more important tasks to ensure real-time performance (bare metal programs cannot do this).
Of course, system calls are not taken into account here.
2. First, let's take a look at the overall architecture of running ucosII on M3
This is the relationship between the modules of the entire system. Next, follow the manual to analyze the points that need to be paid attention to during transplantation.
1. About OS_CPU.h file
#ifndef OS_CPU_H
#define OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
A global variable declaration problem
2. Type definition
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
For common compilers, these are no problem.
3. Next are two more important functions in the assembly code
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
These two codes are the two macros for entering and exiting the critical section. So when you use these two macro definitions, you need to add this sentence OS_CPU_SR cpu_sr = 0; to define and initialize.
The so-called critical section refers to some code that cannot be interrupted. What code cannot be interrupted? For example, the stack push operation we simulated, or when we execute a system call. Then the code like this is the critical section, and the role of the above two macros is that when some code is critical code, we add the ENTER macro when starting this code, and add the EXIT macro when exiting this code.
4. Next, let’s take a look at what these two macros do.
Follow up and you will find
OS_CPU_SR_Save
MRS R0, PRIMASK; Set prio int mask to mask all (except faults)
CPSID I
BX LR
OS_CPU_SR_Restore
MSR PRIMASK, R0
BX LR
This is what we said in the previous step about opening and disabling interrupts. Note that according to the ATCPS rule (if you don't know, you can search on Baidu), when C and assembly are mixed calls, R0 passes the first parameter, and R0 also passes the return value.
5. Next is the growth direction of the stack. On our stm32 board, the stack grows downward and the heap grows upward.
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
#define OS_TASK_SW() OSCtxSw()
The second macro definition is the task switching macro, which will be mentioned below
6. The following involves the code that needs to be modified in this file. First, look at the source code. This is the function prototype declaration
/*
*************************************************** *************************************************** *****
*PROTOTYPES
*************************************************** *************************************************** *****
*/
#if OS_CRITICAL_METHOD == 3 /* See OS_CPU_A.ASM */
OS_CPU_SR OS_CPU_SR_Save(void);
void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif
void OSCtxSw(void);
void OSIntCtxSw(void);
void OSStartHighRdy(void);
void OS_CPU_PendSVHandler(void);
/* See OS_CPU_C.C */
void OS_CPU_SysTickHandler(void);
void OS_CPU_SysTickInit(void);
/* See BSP.C */
INT32U OS_CPU_SysTickClkFreq(void);
All we need to do is comment out these three functions, because we implemented them ourselves
/* See OS_CPU_C.C */
// void OS_CPU_SysTickHandler(void);
// void OS_CPU_SysTickInit(void);
// /* See BSP.C */
// INT32U OS_CPU_SysTickClkFreq(void);
At this point, the first file has been modified, and we can continue.
3. About os_cfg.h file
1. Here are some configurations. Configure our OS according to the functions we need to achieve. Of course, if it is just for lighting, then we can do this
#define OS_FLAG_EN 0 //Disable semaphore set
#define OS_MBOX_EN 0 //Disable mailbox
#define OS_MEM_EN 0 //Disable memory management
#define OS_MUTEX_EN 0 //Disable mutex semaphore
#define OS_Q_EN 0 //Disable queue
#define OS_SEM_EN 0 //Disable semaphore
#define OS_TMR_EN 0 //Disable timer
#define OS_DEBUG_EN 0 //Disable debugging
#define OS_APP_HOOKS_EN 0 336. #define OS_FLAG_EN 0 //Disable semaphore set
#define OS_MBOX_EN 0 //Disable mailbox
#define OS_MEM_EN 0 //Disable memory management
#define OS_MUTEX_EN 0 //Disable mutex semaphore
#define OS_Q_EN 0 //Disable queue
#define OS_SEM_EN 0 //Disable semaphore
#define OS_TMR_EN 0 //Disable timer
#define OS_DEBUG_EN 0 //Disable debugging
#define OS_APP_HOOKS_EN 0 //hook function can also be commented out
#define OS_EVENT_MULTI_EN 0 //Multiple event functions are the same
#define OS_EVENT_MULTI_EN 0
So, here are the contents that need to be modified in this file.
4. About the os_cpu_c.c file.
This file corresponds to the previous macro switch. We need to comment out the macro switches and function definitions related to the previous three functions. The specific operations are as follows
// #define OS_CPU_CM3_NVIC_ST_CTRL (*((volatile INT32U *)0xE000E010)) /* SysTick Ctrl & Status Reg. */
// #define OS_CPU_CM3_NVIC_ST_RELOAD (*((volatile INT32U *)0xE000E014)) /* SysTick Reload Value Reg. */
// #define OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018)) /* SysTick Current Value Reg. */
// #define OS_CPU_CM3_NVIC_ST_CAL (*((volatile INT32U *)0xE000E01C)) /* SysTick Cal Value Reg. */
// #define OS_CPU_CM3_NVIC_PRIO_ST (*((volatile INT8U *)0xE000ED23)) /* SysTick Handler Prio Reg. */
// #define OS_CPU_CM3_NVIC_ST_CTRL_COUNT 0x00010000 /* Count flag. */
// #define OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC 0x00000004 /* Clock Source. */
// #define OS_CPU_CM3_NVIC_ST_CTRL_INTEN 0x00000002 /* Interrupt enable. */
// #define OS_CPU_CM3_NVIC_ST_CTRL_ENABLE 0x00000001 /* Counter mode. */
// #define OS_CPU_CM3_NVIC_PRIO_MIN 0xFF /* Min handler prio. */
Correspondingly, this function also needs to be commented out
//void OS_CPU_SysTickInit (void)
//{
// INT32U cnts;
//
//
// cnts = OS_CPU_SysTickClkFreq() / OS_TICKS_PER_SEC;
//
// OS_CPU_CM3_NVIC_ST_RELOAD = (cnts - 1);
// /* Set prio of SysTick handler to min prio. */
// OS_CPU_CM3_NVIC_PRIO_ST = OS_CPU_CM3_NVIC_PRIO_MIN;
// /* Enable timer. */
// OS_CPU_CM3_NVIC_ST_CTRL |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;
// /* Enable timer interrupt. */
// OS_CPU_CM3_NVIC_ST_CTRL |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;
/
Then this file is also solved. Continue to the next
5. In the file OS_dbg.c
Modify one place, #define OS_COMPILER_OPT __root, and comment out the following __root, otherwise an error will be reported. You can try it yourself
6. Come to the assembly file OS_cpu_a.asm
1. Change all PUBLIC to EXPORT. This is stipulated by the ARM assembly language.
2. RSEG CODE:CODE:NOROOT(2) The format of the code segment also needs to be modified
Modify as follows:
AREA |.text|, CODE, READONLY, ALIGN = 2
THUMB
REQUIRE8
PRESERVE8
For a detailed explanation, please read the introduction to ARM assembly programming.
At this point, the file has been modified.
7. About startup files
There is one place that needs to be modified, and that is the interrupt part. Replace all occurrences of PendSV_Handler in the startup code with OS_CPU_PendSVHandler.
Then this file has been modified
At this point, we have completed most of our transplantation, and the next step is to write our own code.
8. Write a few simple functions to turn on the lights
#include "includes.h"
static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE]; //Define stack
int main(void)
{
BSP_Init();
OSInit();
OSTaskCreate(Task_LED,(void *)0,
&startup_task_stk[STARTUP_TASK_STK_SIZE-1], STARTUP_TASK_PRIO);
OSStart();
return 0;
}
/*
* Function name: BSP_Init
* Description: Clock initialization, hardware initialization
* Input: None
* Output: None
*/
void BSP_Init(void)
{
LED_GPIO_Config(); /* LED port initialization */
}
void Task_LED(void *p_arg)
{
(void)p_arg; // 'p_arg' is not used, to prevent compiler warnings
SysTick_init();
while (1)
{
LED1(ON);
OSTimeDlyHMSM(0, 0,0,500);
LED1(OFF);
OSTimeDlyHMSM(0, 0,0,500);
}
}
/*
* Function name: SysTick_init
* Description: Configure SysTick timer
* Input: None
* Output: None
*/
void SysTick_init(void)
{
SysTick_Config(SystemCoreClock /OS_TICKS_PER_SEC); //Initialize and enable SysTick timer
}
At this point, the single-task system has been implemented. OK. The lights are turned on! The next step is to carefully analyze the source code.
Previous article:Study 2 of UC/OS_II based on stm32f103zet6 (preliminary analysis of OS--lighting method)
Next article:Study on DS18B20 based on stm32f103zet6
- Popular Resources
- Popular amplifiers
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
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- EEWORLD University ---- Wildfire LwIP Application Development Practical Guide
- Compile QT5.6.0
- How to consider and design ESD of RF modules?
- There seems to be something wrong with microPython's regular expression library ure. The matching result of the "*" wildcard is incorrect.
- Regarding IIC communication PCB routing, do I need differential routing? I am currently routing in a dispersed manner? Maximum frequency of 400K
- Decoupling Basics
- Communicate with device over wifi (Android)
- 【RPi Pico】Install MicroPython
- Can anyone recommend the DATASHEE for ATMLU308? I have searched on Baidu but couldn't find it. Thank you.
- MSP430 serial port receiving program (using interruption)