I haven't written a blog for a long time. Recently, the competition was one after another, so I had to participate in the competition. So the learning of stm32 has been stuck, and I started to learn ucosii from the time when I prepared the module recently,
No way, you can continue learning ..
Now, I am officially studying. Today's requirements are not high. I just want to analyze the problems that need to be paid attention to during porting. I will not study the kernel code for the moment! (For code porting, refer to the official source code of st)
That is, the document named an-1018133 in the resource.
Code here you can download http://download.csdn.net/detail/king_bingge/5353528
1. What is the real-time performance of uC/OS?
1. The real-time performance of uC/OS is achieved by scheduled interruptions.
2. When every clock beat arrives, a scheduled interruption occurs. After the interruption, the task is scheduled, the task with the highest priority in the run-ready table (the task is interrupted after the non-preemptive kernel is interrupted ).
That is to say, after a period of time, the system checks whether important tasks need to be run. If yes, it runs more important tasks to ensure real-time performance (bare metal programs cannot do this ).
Of course, system calls are not taken into account here.
Ii. First, take a full look at the architecture of running ucoⅱ on m3.
This is the relationship between the modules of the entire system. Next, we will analyze the precautions for porting according to the manual.
1. 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
Declaration of a global variable
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 all correct.
3. There are two 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);}
The two codes are the two macros used to enter and exit the critical section. So when you use these two macro definitions, you need to add this OS _cpu_sr cpu_sr = 0; To define and initialize it.
The so-called critical section refers to some code that cannot be interrupted. Which Code cannot be interrupted, such as the inbound stack operation we simulate, and when we execute a system call. The code is like the critical section, and the above two macros are used to add the ENTER Macro when starting the code, add the EXIT Macro when exiting this code.
4. Let's continue to see what these two macros have done.
Tracking to discover
OS_CPU_SR_Save MRS R0, PRIMASK ; Set prio int mask to mask all (except faults) CPSID I BX LROS_CPU_SR_Restore MSR PRIMASK, R0 BX LR
This is what we mentioned in the previous step to enable and block interruptions. Note that, according to the ATCPS rules (Baidu is unknown), when C and assembly are mixed calls, R0 passes the first parameter, in addition, R0 still transmits the return value.
5. The next step is the growth direction of the stack. On our stm32 board, the stack grows downward and the stack increases upwards.
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */#define OS_TASK_SW() OSCtxSw()
The second macro is the macro for task switching.
6. The following involves the code to be modified in this file. First, check 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);#endifvoid 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 to comment out the three functions, because this is implemented by ourselves.
/* See OS_CPU_C.C */// void OS_CPU_SysTickHandler(void);// void OS_CPU_SysTickInit(void);// /* See BSP.C */// INT32U OS_CPU_SysTickClkFreq(void);
So far, the first file has been modified and continues ..
Iii. OS _cfg.h File
1. Here are some configurations. We can configure our OS based on the functions we need to implement. Of course, if it is just for the lighting, we can do this.
# Define OS _FLAG_EN 0 // disable semaphores # define OS _MBOX_EN 0 // disable email # define OS _MEM_EN 0 // disable memory management # define OS _MUTEX_EN 0 // disable mutex semaphores # define OS _Q_EN 0/ /disable queue # define OS _SEM_EN 0 // disable semaphores # define OS _TMR_EN 0 // disable the timer # define OS _DEBUG_EN 0 // disable debugging # define OS _APP_HOOKS_EN 0 336. # define OS _FLAG_EN 0 // disable semaphores # define OS _MBOX_EN 0 // disable email # define OS _MEM_EN 0 // disable memory management # define OS _MUTEX_EN 0 // disable mutex semaphores # define OS _Q_EN 0/ /disable queue # define OS _SEM_EN 0 // disable semaphores # define OS _TMR_EN 0 // disable timer # define OS _DEBUG_EN 0 // disable debugging # define OS _APP_HOOKS_EN 0 // The hook function can also be commented out # define OS _EVENT_MULTI_EN 0 // The same is true for multiple event functions # define OS _EVENT_MULTI_EN 0
So here, there is so much content 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. */
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;/
In this case, the file is also fixed. Continue to next
5. In the OS _dbg.c File
Modify a place, # define OS _COMPILER_OPT _ root, comment out the following _ root; otherwise, an error is returned. Try it by yourself
6. Go to the OS _cpu_a.asm Assembly file.
1. Change all the PUBLIC in it to EXPORT. This is stipulated by the ARM assembly language.
2. rseg code: NOROOT (2) the CODE segment format also needs to be modified.
Modify as follows:
AREA |.text|, CODE , READONLY, ALIGN = 2THUMBREQUIRE8PRESERVE8
For more information, see the Introduction to ARM assembly programming.
This file has been modified.
VII. startup files
There is a point that needs to be modified, that is, to interrupt this part. Replace all PendSV_Handler in the startup code with OS _CPU_PendSVHandler.
The file has been modified.
At this point, we have completed a majority of porting, and the next step is to write your own code.
8. Compile a few simple functions to realize the lighting.
# Include "DES. h "static OS _STK startup_task_stk [STARTUP_TASK_STK_SIZE]; // defines the 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: no */void BSP_Init (void) {LED_GPIO_Config ();/* LED port initialization */} void Task_LED (void * p_arg) {(void) p_arg; // 'P _ arg 'is not used, preventing the compiler from prompting the warning javasick_init (); while (1) {LED1 (ON); OSTimeDlyHMSM (0, 500 ); LED1 (OFF); OSTimeDlyHMSM (0, 500,);}/** function name: SysTick_init * Description: configure the SysTick timer * input: none * output: no */void SysTick_init (void) {SysTick_Config (SystemCoreClock/OS _TICKS_PER_SEC); // initialize and enable SysTick timer}
Now, the single task system is implemented. OK. The light is lit! The next step is to carefully analyze the source code.