STM32上的UCOSII移植步骤与关键知识点解析

需积分: 10 4 下载量 130 浏览量 更新于2024-07-28 收藏 215KB DOC 举报
"ucosii在stm32上的移植详解" UCOSII,全称为uC/OS-II,是一款流行的实时操作系统(RTOS),适用于嵌入式系统。STM32系列微控制器是基于ARM Cortex-M3内核的,具有丰富的外设接口和高性能特性,广泛应用于各种嵌入式应用。移植UCOSII到STM32上是为了利用其内核调度、任务管理等功能,实现复杂的嵌入式系统设计。 移植UCOSII到STM32,首先需要对目标芯片和操作系统内核有深入理解。对于STM32,理解Cortex-M3内核至关重要。Cortex-M3是ARM公司设计的一种低功耗、高性能的32位微处理器内核,它主要采用Thumb-2指令集,简化了代码体积,提高了执行效率。 《ARMCortex-M3权威指南》是一本详尽介绍Cortex-M3的书籍。在移植过程中,需要关注以下几个关键章节: 1. Chapter 2 - Cortex-M3概览:这部分介绍了Cortex-M3的基本架构和特性,包括处理器核心、内存系统和外设接口等。 2. Chapter 3 - Cortex-M3基础:详细讲解了寄存器组和特殊功能寄存器。通用寄存器R0-R12、堆栈寄存器R13(MSP和PSP)、连接寄存器R14(LR)、程序计数寄存器R15(PC)以及程序状态字寄存器组(PSRs)、中断屏蔽寄存器组和控制寄存器(CONTROL)。 - R13的MSP和PSP分别用于异常处理和应用程序的堆栈操作,R14存储子程序返回地址,R15是程序执行的指针。 - PSRs用于保存程序状态,如中断状态、条件码等,而中断屏蔽寄存器则控制异常处理的使能和禁止。 - CONTROL寄存器确定当前运行的特权级别,以及选择MSP或PSP作为当前堆栈指针。 在理解了Cortex-M3内核之后,接下来就是移植UCOSII的具体步骤: 1. 初始化设置:包括堆栈初始化、中断向量表的配置、NVIC(Nested Vectored Interrupt Controller)的设置等。 2. 处理器模式和特权级:UCOSII需要在特权模式下运行,因此要配置CONTROL寄存器来确保这一点。 3. 时间管理:Cortex-M3内核有一个内置的定时器(SysTick)可以用来实现UCOSII的时间基。 4. 任务切换:实现UCOSII的任务调度,包括任务创建、删除、挂起、恢复等,需要利用寄存器R13、R14和控制寄存器来保存和恢复上下文。 5. 内存管理:根据UCOSII的需求,配置RAM区域,分配任务堆栈和系统数据结构。 6. 中断处理:配置中断服务例程,确保在中断发生时,UCOSII能正确地管理和恢复任务。 7. 外设驱动:根据STM32的外设,编写相应的设备驱动,如串口、GPIO、定时器等,使UCOSII能与硬件交互。 8. 测试验证:移植完成后,通过一系列测试确保UCOSII的稳定运行,如任务调度、中断处理、内存管理等。 在移植过程中,可能会遇到如堆栈溢出、中断处理不当、任务同步问题等挑战,需要通过调试和优化来解决。移植完成后,开发者就可以基于UCOSII开发应用软件,利用其提供的任务管理、信号量、互斥锁、消息队列等功能,实现复杂的实时任务调度。 移植UCOSII到STM32是一项涉及硬件理解、内核原理掌握以及操作系统机制实现的工作。通过深入学习和实践,开发者能够将UCOSII的优势充分发挥,构建高效可靠的嵌入式系统。
2010-09-15 上传
/*********************** (C) COPYLEFT 2010 Leafgrass *************************/ This project runs on uC/OS-II V2.52 and is based on STM32F103RBT6(ARM Cortex-M3 Core) Take care of the configuration of project. There're some Include Paths while linking which cannot be modified. Procedure of driving a device(IMPORTANT!!!): 1.Connect hardware correctly. 2.Prepare DEVICE_NAME.h and DEVICE_NAME.c. 3.Enable clock of related components. 4.Enable related interrupt while configure NVIC. 5.Configure related IO pins. 6.Finish test code and begin testing. 2010-06-10( original ): Sucessfully port uCOS-II V2.52. 2010-06-11: Add code "SysTick_CounterCmd(SysTick_Counter_Enable);" in SysTick_Configuration(), solve the problem that the program can't get into SysTickHandler(), as below: /******************************************************************************* * Function Name : SysTick_Config * Description : Configures SysTick * Input : None * Output : None * Return : None *******************************************************************************/ void SysTick_Configuration(void) { NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 0, 1); /* Configure HCLK clock as SysTick clock source */ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /* SysTick interrupt each 1000 Hz with HCLK equal to 72MHz */ SysTick_SetReload(9000); /* Enable the SysTick Interrupt */ SysTick_ITConfig(ENABLE); SysTick_CounterCmd(SysTick_Counter_Enable); //Important!! Solve "the program can't get into SysTickHandler()!! } 2010-06-12( updates to V1.0 ): 1. Add EXTI8, EXTI9 on PC8, PC9, only for EXTI test. 2. Modify some comments in LCD5110_lib. 3. (in main.c) Modifiy tasks' priority LED_TASK_Prio 1 -> 5 START_TASK_Prio 2 -> 10 4. (in main.c) Modify code "OSTaskDel(START_TASK_Prio);" to "OSTaskSuspend(START_TASK_Prio);" 2010-07-13 1.Drive LTM022A69B LCD ok. Just use I/O to imitate SPI. Still cannot use internal SPI to drive it. 2.Move LCD library of LTM022A69B into "LCD_lib.c". 2010-07-15: Add color bar display in LCD_test(). 2010-07-16( updates to V1.1 ): 1.Solve problem about position error and color error, when display a set of 16-bit color data. Mainly resulted from CPU type, big endian or little endian. STM32F103RBT6 is little endian while in default set. 2.Add Draw_img(); 3.Add colorful characters and strings, add parameters about colors in display functions.(colors are defined in LTM022A69B.h) 2010-07-17: 1.Add comments in LCD_Init(). 2.Add parameter "color" to function Draw_dot(). 3.Add function SetCursor(). 4.Unify LCD related functions' name. Add prefix "LCD_". 2010-07-19: Modify data type in LCD_Lib. normal --> const. At one time, modify the pointers type to const. 2010-07-20: 1.Correct the error that OSTimeDlyHMSM() can't delay an accurate time, by modifying SysTick_Configuration() to get an correct clock frequency. 2010-07-31: Add STM32_Init.c but is not referenced, for future use of Configuration Wizard. 2010-08-01: Configure SPI ok, and do some test(SPI2 tx -> SPI1 rx, display on LCD). 2010-08-03: 1.Add SPI test code in main.c, SPI2 send data, SPI1 receive data , display info on LCD, use soft SPI. 2.Add exported macro "USESPI" to choose if use SPI to drive LCD or not. 3.After several days researching about hard SPI to drive LCD, failed. So switch to use a faster GPIO method, as below: Replace "#define LCD_RST_H() GPIO_SetBits(LCD_CTRL_PORT, LCD_RST)" in ST library with "#define LCD_RST_H() ( LCD_CTRL_PORT->BSRR = LCD_RST )" for a faster LCD refresh speed. 4.Modify name "LCD_SCI" to "LCD_SI", 'cause it means Serial Interface. 5.Modify function name "LCD_test()" to "LCD_Test()". 2010-08-06: Comment off "typedef enum {FALSE = 0, TRUE = !FALSE} bool;" in stm32f10x.type.h in order to avoid warning. 2010-08-09: Prepare to update to v2.0. 2010-08-10( Update to v2.0, use ST's FWLib3.1.2 ): 1. Set project(Keil RealView MDK). (1) RO memory area : IROM1 -- start at 0x08000000, size 0x20000. (2) RW memory area : IRAM1 -- start at 0x20000000, size 0x5000. (3) Output setup. (4) Listing setup, no assembler list. (5) C/C++ setup. Preprocessor Symbols : Define -- USE_STDPERIPH_DRIVER, STM32F10X_MD. Include Paths : ..\; ..\..\Libraries\CMSIS\Core\CM3; ..\..\Libraries\STM32F10x_StdPeriph_Driver\inc; ..\..\App; ..\..\Driver; ..\..\OS; ..\..\OS\port (6) Linker, Use memory layout from target dialog. (7) Debug and Utilities, Cortex-M/R J-Link/J-Trace. Disable Trace. 2. Modify code in "includes.h". 3. Modify startup code, did not use the st original one. Port those used in FWLib2.0 instead. Of course, some code are revised for FWLib3.1.2(StdPeriph_Driver and CMSIS). Mainly rewrite the names of the ISR. The most important two are : "PendSV_Handler" and "SysTick_Handler". ---> "OSPendSV" and "SysTick_Handler". (in "os_cpu_a.asm") (in "stm32f10x_it.c") 4. Modify initial code for SysTick in "SysTick_Configuration()" in "CPU_Init.c" because of the changing of library. Note : A general problem is that program always go into "B OSStartHang" in "OSStartHighRdy" in "os_cpu_a.asm", and will die in there... That's caused by program hasn't step into the correct ISR yet. Enable the SysTick interrupt, check if the name of Interrupt Service Routines are right, then all will be OK. 5. Still some problem with retargeting "printf()". If use "printf()" in program, system wouldn't run. 6. Change Project name to "RTOS_STM32". 2010-08-11( Update to v2.1, use ST's FWLib3.3.0 ): 1. Modify Include Path in Target Options. 2. Comment "typedef enum {FALSE = 0, TRUE = !FALSE} bool;" off in order to avoid error: "..\stm32f10x.h(454): error: #40: expected an identifier". 2010-08-12( Update to v2.2 ): 1. Remove the incorrect use of SPI in LCD display, add a new schedule( maily used SPI busy flag ). 2. Commen off code "assert_param(IS_SPI_ALL_PERIPH(SPIx));" in "SPI_I2S_SendData()", "SPI_I2S_ReceiveData()", and "SPI_I2S_GetFlagStatus" in "stm32f10x_spi.h", in order to improve LCD refresh frequency. 3. Finish to retarget C library printf() to UART. As a foundation, change the setup of KEIL in "Target Options" --> "Code Generation" --> tick "Use MicroLIB". There are still some problem with building, modify a few lines in "stm32f10x_startup.s" : ================================ IF :DEF:__MICROLIB EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit ELSE IMPORT __use_two_region_memory EXPORT __user_initial_stackheap ================================ Then rebuild. Add retarget code in main.c : ================================================================ #ifdef __GNUC__ // With GCC/RAISONANCE, small printf // (option LD Linker->Libraries->Small printf set to 'Yes') // calls __io_putchar() #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif // __GNUC__ ---------------------------------------------------------------- PUTCHAR_PROTOTYPE { // Place your implementation of fputc here // e.g. write a character to the USART USART_SendData(USARTx, (u8)ch); // Loop until the end of transmission while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} return ch; } ================================================================ 2010-08-14(update to v2.3): 1. Rewrite the different part of code into its C file. 2. Drive TIM3 output PWM wave successfully. 3. Add "servo" file, for servo control. 2010-08-19(update to v2.4, GPS data receive ok): 1. Add "gps" file. 2. Add code in "USART3_IRQHandler()", mainly to receive data from GPS. But there's still someting confusing, that the pair "USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);" and "USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);" cannot work well. Because once use them, some data will be lost. 2010-08-22: Refresh firmware of GPS, modify to Baudrate 9600, China timezone, WGS-84 coordinate. 2010-09-02: Replace those two old startup files "cortexm3_macro.s" and "stm32f10x_startup.s" with the one "startup_stm32f10x_md.s" which is created by MCD Application Team in FWLib3.3.0. 2010-09-13: 1. Add general_task.h and .c for miscellaneous experimental purpose. 2. Add uart output infomation in booting stage. 3. Add macro "LED_TOGGLE()" use "(GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1))" 4. Create Logo: _ _ / / | | ___ __ _ _| |_ __ _ _ __ __ _ _ _ | | / _ \/ _` |_ _/ _` | \/ _)/ _` | / / / / | |_ _ __( (_| | | | (_| | | | ( (_| | \ \ \ \ |_ _ _\___|\__,_| | | \__, / | | \__,_| /_/ /_/ /_/ \_ _/ 5. EXTI again. setup procedure: GPIO IN FLOATING -> NVIC IRQ -> EXTI Config -> _it.c /*********************** (C) COPYLEFT 2010 Leafgrass *************************/