Study 1 of UC/OS_II based on stm32f103zet6 (initial transplantation of OS--lighting method)

Publisher:RadiantDreamsLatest update time:2017-09-06 Source: eefocusKeywords:stm32f103zet6 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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


  1. #ifndef OS_CPU_H  

  2. #define OS_CPU_H  

  3.  

  4.  

  5. #ifdef OS_CPU_GLOBALS  

  6. #define OS_CPU_EXT  

  7. #else  

  8. #define OS_CPU_EXT extern  

  9. #endif  


A global variable declaration problem


2. Type definition



  1. typedef unsigned char BOOLEAN;  

  2. typedef unsigned char INT8U; /* Unsigned 8 bit quantity */  

  3. typedef signed char INT8S; /* Signed 8 bit quantity */  

  4. typedef unsigned short INT16U; /* Unsigned 16 bit quantity */  

  5. typedef signed short INT16S; /* Signed 16 bit quantity */  

  6. typedef unsigned int INT32U; /* Unsigned 32 bit quantity */  

  7. typedef signed int INT32S; /* Signed 32 bit quantity */  

  8. typedef float FP32; /* Single precision floating point */  

  9. typedef double FP64; /* Double precision floating point */  

  10.   

  11. typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */  

  12. 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



  1. #define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}  

  2. #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


  1. OS_CPU_SR_Save  

  2.     MRS R0, PRIMASK; Set prio int mask to mask all (except faults)  

  3.     CPSID I  

  4.     BX LR  

  5.   

  6. OS_CPU_SR_Restore  

  7.     MSR PRIMASK, R0  

  8.     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.


  1. #define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */  

  2.  

  3. #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



  1. /* 

  2. *************************************************** *************************************************** ***** 

  3. *PROTOTYPES 

  4. *************************************************** *************************************************** ***** 

  5. */  

  6.  

  7. #if OS_CRITICAL_METHOD == 3 /* See OS_CPU_A.ASM */  

  8. OS_CPU_SR OS_CPU_SR_Save(void);  

  9. void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);  

  10. #endif  

  11.   

  12. void OSCtxSw(void);  

  13. void OSIntCtxSw(void);  

  14. void OSStartHighRdy(void);  

  15.   

  16. void OS_CPU_PendSVHandler(void);  

  17.   

  18.                                                   /* See OS_CPU_C.C */  

  19. void OS_CPU_SysTickHandler(void);  

  20. void OS_CPU_SysTickInit(void);  

  21.   

  22.                                                   /* See BSP.C */  

  23. INT32U OS_CPU_SysTickClkFreq(void);  


All we need to do is comment out these three functions, because we implemented them ourselves



  1.                                                   /* See OS_CPU_C.C */  

  2. // void OS_CPU_SysTickHandler(void);  

  3. // void OS_CPU_SysTickInit(void);  

  4.   

  5. // /* See BSP.C */  

  6. // 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


  1.  #define OS_FLAG_EN 0 //Disable semaphore set      

  2.  #define OS_MBOX_EN 0 //Disable mailbox      

  3.  #define OS_MEM_EN 0 //Disable memory management      

  4.  #define OS_MUTEX_EN 0 //Disable mutex semaphore      

  5.  #define OS_Q_EN 0 //Disable queue      

  6.  #define OS_SEM_EN 0 //Disable semaphore      

  7.  #define OS_TMR_EN 0 //Disable timer      

  8.  #define OS_DEBUG_EN 0 //Disable debugging    

  9.   

  10.  #define OS_APP_HOOKS_EN 0 336. #define OS_FLAG_EN 0 //Disable semaphore set      

  11.  #define OS_MBOX_EN 0 //Disable mailbox      

  12. #define OS_MEM_EN 0 //Disable memory management      

  13. #define OS_MUTEX_EN 0 //Disable mutex semaphore      

  14.  #define OS_Q_EN 0 //Disable queue      

  15. #define OS_SEM_EN 0 //Disable semaphore      

  16.  #define OS_TMR_EN 0 //Disable timer      

  17.  #define OS_DEBUG_EN 0 //Disable debugging    

  18.  #define OS_APP_HOOKS_EN 0 //hook function can also be commented out  

  19.  #define OS_EVENT_MULTI_EN 0 //Multiple event functions are the same  

  20.  #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


  1. // #define OS_CPU_CM3_NVIC_ST_CTRL (*((volatile INT32U *)0xE000E010)) /* SysTick Ctrl & Status Reg. */  

  2. // #define OS_CPU_CM3_NVIC_ST_RELOAD (*((volatile INT32U *)0xE000E014)) /* SysTick Reload Value Reg. */  

  3. // #define OS_CPU_CM3_NVIC_ST_CURRENT (*((volatile INT32U *)0xE000E018)) /* SysTick Current Value Reg. */  

  4. // #define OS_CPU_CM3_NVIC_ST_CAL (*((volatile INT32U *)0xE000E01C)) /* SysTick Cal Value Reg. */  

  5. // #define OS_CPU_CM3_NVIC_PRIO_ST (*((volatile INT8U *)0xE000ED23)) /* SysTick Handler Prio Reg. */  

  6.   

  7. // #define OS_CPU_CM3_NVIC_ST_CTRL_COUNT 0x00010000 /* Count flag. */  

  8. // #define OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC 0x00000004 /* Clock Source. */  

  9. // #define OS_CPU_CM3_NVIC_ST_CTRL_INTEN 0x00000002 /* Interrupt enable. */  

  10. // #define OS_CPU_CM3_NVIC_ST_CTRL_ENABLE 0x00000001 /* Counter mode. */  

  11. // #define OS_CPU_CM3_NVIC_PRIO_MIN 0xFF /* Min handler prio. */  


Correspondingly, this function also needs to be commented out


  1. //void OS_CPU_SysTickInit (void)  

  2. //{  

  3. // INT32U cnts;  

  4. //  

  5. //  

  6. // cnts = OS_CPU_SysTickClkFreq() / OS_TICKS_PER_SEC;  

  7. //  

  8. // OS_CPU_CM3_NVIC_ST_RELOAD = (cnts - 1);  

  9. // /* Set prio of SysTick handler to min prio. */  

  10. // OS_CPU_CM3_NVIC_PRIO_ST = OS_CPU_CM3_NVIC_PRIO_MIN;  

  11. // /* Enable timer. */  

  12. // OS_CPU_CM3_NVIC_ST_CTRL |= OS_CPU_CM3_NVIC_ST_CTRL_CLK_SRC | OS_CPU_CM3_NVIC_ST_CTRL_ENABLE;  

  13. // /* Enable timer interrupt. */  

  14. // OS_CPU_CM3_NVIC_ST_CTRL |= OS_CPU_CM3_NVIC_ST_CTRL_INTEN;  

  15. /  


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:


  1. AREA |.text|, CODE, READONLY, ALIGN = 2  

  2. THUMB  

  3. REQUIRE8  

  4. 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


  1. #include "includes.h"  

  2.   

  3. static OS_STK startup_task_stk[STARTUP_TASK_STK_SIZE]; //Define stack  

  4.     

  5. int main(void)  

  6. {  

  7.     BSP_Init();  

  8.     OSInit();  

  9.     OSTaskCreate(Task_LED,(void *)0,  

  10.     &startup_task_stk[STARTUP_TASK_STK_SIZE-1], STARTUP_TASK_PRIO);  

  11.   

  12.     OSStart();  

  13.     return 0;  

  14.  }  

  15.    

  16.  /* 

  17.  * Function name: BSP_Init 

  18.  * Description: Clock initialization, hardware initialization 

  19.  * Input: None 

  20.  * Output: None 

  21.  */  

  22. void BSP_Init(void)  

  23. {  

  24.     LED_GPIO_Config(); /* LED port initialization */  

  25. }  

  26.   

  27. void Task_LED(void *p_arg)  

  28. {  

  29.    (void)p_arg; // 'p_arg' is not used, to prevent compiler warnings  

  30.     SysTick_init();  

  31.     while (1)  

  32.     {  

  33.         LED1(ON);  

  34.         OSTimeDlyHMSM(0, 0,0,500);  

  35.         LED1(OFF);  

  36.         OSTimeDlyHMSM(0, 0,0,500);  

  37.     }  

  38. }  

  39.    

  40. /* 

  41.  * Function name: SysTick_init 

  42.  * Description: Configure SysTick timer 

  43.  * Input: None 

  44.  * Output: None 

  45.  */  

  46. void SysTick_init(void)  

  47. {  

  48.     SysTick_Config(SystemCoreClock /OS_TICKS_PER_SEC); //Initialize and enable SysTick timer  

  49. }  

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.


Keywords:stm32f103zet6 Reference address:Study 1 of UC/OS_II based on stm32f103zet6 (initial transplantation of OS--lighting method)

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

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号