STM32F429移植UCOSII笔记

作者: 李二瞄 | 来源:发表于2019-08-01 17:52 被阅读0次

    1.准备相关文件

    直接使用官方的STM32F4移植例程,里面也包含UCOSII的源代码。
    进入官网下载中心:
    https://www.micrium.com/downloadcenter/
    Browse by MCU Manufacturer,然后找到STM32F4:


    点进去,选这个UCOSII的工程:

    红框是这个工程主要用于评估的项目,这个工程是用于评估UCOSII的,比较容易移植,另外,这个工程支持右面4个IDE,比较方便。
    然后准备自己的STM32工程,可以用CubeMX创建,在创建好的工程中新建一个UCOSII的文件夹用于存放UCOSII相关的代码文件。
    下载好的工程打开,找到下面这三个文件夹,复制到UCOSII文件夹中。

    然后在UCOSII中新建两个文件夹:uCOS-BSP和uCOS-Config,将Micrium\Examples\ST\STM3240G-EVAL\BSP下的这三个文件复制到uCOS-BSP中:

    然后将Micrium\Examples\ST\STM3240G-EVAL\OS2下的这6个文件复制到uCOS-Config:
    image.png
    最后,新建一个头文件“includes.h”放到uCOS-Config文件夹中,内容如下:
    /************************************************
    * UCOS主要包含的头文件
    ************************************************/
    #ifndef __INCLUDES_H_
    #define __INCLUDES_H_
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdarg.h>
    #include "os.h"
    #include "os_cpu.h"
    #include "os_cfg.h"
    #include <stm32f4xx.h>
    #endif
    

    到现在为止UCOSII的文件都已经添加到项目中了,现在项目文件结构应该是这样的:



    2. 编译测试

    在移植来的BSP中写了许多example,会关联到官方项目的其他文件,现在把他们删除。也就是修改bsp.c、bsp.h两个文件。
    bsp.c:

    /*
    *********************************************************************************************************
    * EXAMPLE CODE
    *
    * This file is provided as an example on how to use Micrium products.
    *
    * Please feel free to use any application code labeled as 'EXAMPLE CODE' in
    * your application products. Example code may be used as is, in whole or in
    * part, or may be used as a reference only. This file can be modified as
    * required to meet the end-product requirements.
    *
    * Please help us continue to provide the Embedded community with the finest
    * software available. Your honesty is greatly appreciated.
    *
    * You can find our product's user manual, API reference, release notes and
    * more information at https://doc.micrium.com.
    * You can contact us at www.micrium.com.
    *********************************************************************************************************
    */
    /*
    *********************************************************************************************************
    *
    * MICRIUM BOARD SUPPORT PACKAGE
    *
    * ST Microelectronics STM32
    * on the
    *
    * STM3240G-EVAL
    * Evaluation Board
    *
    * Filename : bsp.c
    * Version : V1.00
    * Programmer(s) : FF
    *********************************************************************************************************
    */
    /*
    *********************************************************************************************************
    * INCLUDE FILES
    *********************************************************************************************************
    */
    #define BSP_MODULE
    #include <bsp.h>
    #include <stm32f4xx_hal.h>
    /*
    *********************************************************************************************************
    * BSP_CPU_ClkFreq()
    *
    * Description : Read CPU registers to determine the CPU clock frequency of the chip.
    *
    * Argument(s) : none.
    *
    * Return(s) : The CPU clock frequency, in Hz.
    *
    * Caller(s) : Application.
    *
    * Note(s) : none.
    *********************************************************************************************************
    */
    CPU_INT32U BSP_CPU_ClkFreq (void)
    {
    CPU_INT32U hclk_freq;
    hclk_freq = HAL_RCC_GetHCLKFreq();
    return (hclk_freq);
    }
    

    bsp.h:

    /*
    *********************************************************************************************************
    *
    * MICRIUM BOARD SUPPORT PACKAGE
    *
    * ST Microelectronics STM32
    * on the
    *
    * STM3240G-EVAL
    * Evaluation Board
    *
    * Filename : bsp.h
    * Version : V1.00
    * Programmer(s) : FF
    *********************************************************************************************************
    */
    #ifndef BSP_PRESENT
    #define BSP_PRESENT
    /*
    *********************************************************************************************************
    * EXTERNS
    *********************************************************************************************************
    */
    #ifdef BSP_MODULE
    #define BSP_EXT
    #else
    #define BSP_EXT extern
    #endif
    /*
    *********************************************************************************************************
    * INCLUDE FILES
    *********************************************************************************************************
    */
    #include <cpu.h>
    #include <cpu_core.h>
    #include <lib_def.h>
    /*
    *********************************************************************************************************
    * FUNCTION PROTOTYPES
    *********************************************************************************************************
    */
    CPU_INT32U BSP_CPU_ClkFreq(void);
    /*
    *********************************************************************************************************
    * MODULE END
    *********************************************************************************************************
    */
    #endif /* End of module include. */
    

    现在,这个工程应该可以编译了。
    由于我用的vscode,使用makefile进行编译,所以要把UCOSII的源代码文件、asm文件、头文件引用目录加入到makefile中。
    vscode里有复制相对路径功能很好用:



    但是复制的相对路径是win平台的路径格式,我用的makefile是要在minGW中运行的,所以要转为sh的路径格式,也就是''要改成'/',然后不是最后一个文件的话后面要加换行符 。改好的makefile如下:

    ##########################################################################################################################
    # File automatically-generated by tool: [projectgenerator] version: [3.3.0] date: [Thu Aug 01 10:21:39 CST 2019]
    ##########################################################################################################################
    # ------------------------------------------------
    # Generic Makefile (based on gcc)
    #
    # ChangeLog :
    #   2017-02-10 - Several enhancements + project update mode
    # 2015-07-22 - first version
    # ------------------------------------------------
    ######################################
    # target
    ######################################
    TARGET = STM32F429IGT-UCOSII
    ######################################
    # building variables
    ######################################
    # debug build?
    DEBUG = 1
    # optimization
    OPT = -Og
    #######################################
    # paths
    #######################################
    # Build path
    BUILD_DIR = build
    ######################################
    # source
    ######################################
    # C sources
    #在此处定义路径
    UCOSII = uCOS-II
    BSP = BSP
    UC_CPU = uCOS-II/uC-CPU
    UC_LIB = uCOS-II/uC-LIB
    UC_CONFIG = uCOS-II/uC-Config
    UC_CORE = uCOS-II/uCOS-II
    UC_BSP = uCOS-II/uC-BSP
    C_SOURCES = \
    Core/Src/main.c \
    Core/Src/stm32f4xx_it.c \
    Core/Src/stm32f4xx_hal_msp.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rtc_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr_ex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c \
    Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c \
    Core/Src/system_stm32f4xx.c \
    $(UC_CPU)/cpu_core.c \
    $(UC_CPU)/ARM-Cortex-M4/GNU/cpu_c.c \
    $(UC_LIB)/lib_ascii.c \
    $(UC_LIB)/lib_math.c \
    $(UC_LIB)/lib_mem.c \
    $(UC_LIB)/lib_str.c \
    $(UC_BSP)/bsp.c \
    $(UC_BSP)/cpu_bsp.c \
    $(UC_CONFIG)/app_hooks.c \
    $(UC_CORE)/Source/os_core.c \
    $(UC_CORE)/Source/os_flag.c \
    $(UC_CORE)/Source/os_mbox.c \
    $(UC_CORE)/Source/os_mem.c \
    $(UC_CORE)/Source/os_mutex.c \
    $(UC_CORE)/Source/os_q.c \
    $(UC_CORE)/Source/os_sem.c \
    $(UC_CORE)/Source/os_task.c \
    $(UC_CORE)/Source/os_time.c \
    $(UC_CORE)/Source/os_tmr.c \
    $(UC_CORE)/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_c.c \
    $(UC_CORE)/Ports/ARM-Cortex-M4/Generic/GNU/os_dbg.c \
    $(BSP)/printf_support.c
    # ASM sources
    ASM_SOURCES = \
    startup_stm32f429xx.s \
    $(UC_CPU)/ARM-Cortex-M4/GNU/cpu_a.s \
    $(UC_LIB)/Ports/ARM-Cortex-M4/GNU/lib_mem_a.s \
    $(UC_CORE)/Ports/ARM-Cortex-M4/Generic/GNU/os_cpu_a.s
    #######################################
    # binaries
    #######################################
    PREFIX = arm-none-eabi-
    # The gcc compiler bin path can be either defined in make command via GCC_PATH variable (> make GCC_PATH=xxx)
    # either it can be added to the PATH environment variable.
    ifdef GCC_PATH
    CC = $(GCC_PATH)/$(PREFIX)gcc
    AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
    CP = $(GCC_PATH)/$(PREFIX)objcopy
    SZ = $(GCC_PATH)/$(PREFIX)size
    else
    CC = $(PREFIX)gcc
    AS = $(PREFIX)gcc -x assembler-with-cpp
    CP = $(PREFIX)objcopy
    SZ = $(PREFIX)size
    endif
    HEX = $(CP) -O ihex
    BIN = $(CP) -O binary -S
    #######################################
    # CFLAGS
    #######################################
    # cpu
    CPU = -mcpu=cortex-m4
    # fpu
    FPU = -mfpu=fpv4-sp-d16
    # float-abi
    FLOAT-ABI = -mfloat-abi=hard
    # mcu
    MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
    # macros for gcc
    # AS defines
    AS_DEFS =
    # C defines
    C_DEFS = \
    -DUSE_HAL_DRIVER \
    -DSTM32F429xx
    # AS includes
    AS_INCLUDES =
    # C includes
    C_INCLUDES = \
    -ICore/Inc \
    -IDrivers/STM32F4xx_HAL_Driver/Inc \
    -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy \
    -IDrivers/CMSIS/Device/ST/STM32F4xx/Include \
    -IDrivers/CMSIS/Include \
    -IDrivers/CMSIS/Include \
    -I$(UCOSII) \
    -I$(UC_CPU) \
    -I$(UC_CPU)/ARM-Cortex-M4 \
    -I$(UC_CPU)/ARM-Cortex-M4/GNU \
    -I$(UC_LIB) \
    -I$(UC_BSP) \
    -I$(UC_CONFIG) \
    -I$(UC_CORE)/Source \
    -I$(UC_CORE)/Ports/ARM-Cortex-M4/Generic/GNU \
    -I$(BSP)
    # compile gcc flags
    ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
    CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
    ifeq ($(DEBUG), 1)
    CFLAGS += -g -gdwarf-2
    endif
    # Generate dependency information
    CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
    #######################################
    # LDFLAGS
    #######################################
    # link script
    LDSCRIPT = STM32F429IGTx_FLASH.ld
    # libraries
    LIBS = -lc -lm -lnosys
    LIBDIR =
    LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
    # default action: build all
    all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
    #######################################
    # build the application
    #######################################
    # list of objects
    OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
    vpath %.c $(sort $(dir $(C_SOURCES)))
    # list of ASM program objects
    OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
    vpath %.s $(sort $(dir $(ASM_SOURCES)))
    $(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
        $(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
    $(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
        $(AS) -c $(CFLAGS) $< -o $@
    $(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
        $(CC) $(OBJECTS) $(LDFLAGS) -o $@
        $(SZ) $@
    $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
        $(HEX) $< $@
        
    $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
        $(BIN) $< $@    
        
    $(BUILD_DIR):
        mkdir $@        
    #######################################
    # clean up
    #######################################
    clean:
        -rm -fR $(BUILD_DIR)
    #######################################
    # dependencies
    #######################################
    -include $(wildcard $(BUILD_DIR)/*.d)
    # *** EOF ***
    

    要注意的是C_SOURCES里面要添加所有用到的c文件,同理ASM_SOURCES里面要添加所有用到的s文件。C_INCLUDES里面要包含所有h文件所在的目录,并且父目录对子目录无效的。
    另外,在我们移植来的文件中会出现这种情况:



    这个时候如果是Keil选择RealView,IAR选择IAR,makefile用的是GNU,选择GNU下的文件。
    makefile改一下,就可以编译测试了。但是在make过程中出现了这样的错误:

    mingw32-make: *** No rule to make target 'build/os_cpu_a.S', needed by 'build/STM32F429IGT-UCOSII.elf'.  Stop.
    终端进程已终止,退出代码: 2
    

    这是因为os_cpu_a.S文件的后缀不符合我们makefile中的规则(makefile中规则只对于.s文件),把这文件后缀改为小写,再次编译,成功。

    3. 编写UCOS的include文件

    创建一个includes.h,在里面包含使用UCOSII必要include的头文件,代码如下:

    /*
    ************************************************************************************************
    INCLUDES.C ucos
    Jean J. Labrosse
    ************************************************************************************************
    */
    
    #ifndef __INCLUDES_H__
    #define __INCLUDES_H__
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    #include <stdarg.h>
    
    #include "os.h"
    #include "os_cpu.h"
    #include "os_cfg.h"
    
    #include <stm32f4xx.h>      
    
    #endif
    

    4. 修改文件

    1. PendSV_Handler():把os_cpu_a.s中的OS_CPU_PendSVHandler函数改为PendSV_Handler,总共两处。然后把stm32f4xx_it.c中的void PendSV_Handler(void)去掉,对应h文件的void PendSV_Handler(void);也去掉,原因是在os_cpu_a.s已经定义。
    2. SysTick_Handler():在os_cpu_c.c中定义了OS_CPU_SysTickHandler(),但是同上面的pendsv一样,名称和启动文件.s中的vector不符,把这个函数定义和在头文件中的声明注释掉。(不注释掉应该也行)。然后把这个函数里的内容复制到stm32f4xx_it.c的SysTick_Handler()中,OSIntNesting++这个我参考其他人的教程没有复制,具体原因没有测试。并且,stm32f4xx_it.c要包含上面的"includes.h"。下面是代码:
    void SysTick_Handler(void)
    {
      /* USER CODE BEGIN SysTick_IRQn 0 */
    
      /* USER CODE END SysTick_IRQn 0 */
      HAL_IncTick();
      /* USER CODE BEGIN SysTick_IRQn 1 */
        OSTimeTick();                                /* Call uC/OS-II's OSTimeTick()                       */
        OSIntExit();
      /* USER CODE END SysTick_IRQn 1 */
    }
    
    1. 按照下面5或6的第一步,在IDE上打开FPU(makefile的工程在makefile中已经设置好了),第二步设置tm32f429xx.h中__FPU_PRESENT为1。下面的步骤是把废弃的5、6步的汇编变成C语言放在systeminit中,兼容性更好。然后在system_stm32f4xx.c中,void SystemInit(void)里面加一行代码(FPU->FPCCR &= ~(FPU_FPCCR_ASPEN_Msk|FPU_FPCCR_LSPEN_Msk);)就可以了:
    oid SystemInit(void)
    {
      /* FPU settings ------------------------------------------------------------*/
      #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
            FPU->FPCCR &= ~(FPU_FPCCR_ASPEN_Msk|FPU_FPCCR_LSPEN_Msk);
      #endif
      /* Reset the RCC clock configuration to the default reset state ------------*/
      /* Set HSION bit */
      RCC->CR |= (uint32_t)0x00000001;
    
      /* Reset CFGR register */
      RCC->CFGR = 0x00000000;
    
      /* Reset HSEON, CSSON and PLLON bits */
      RCC->CR &= (uint32_t)0xFEF6FFFF;
    
    1. 设置UCOSII的时钟:OS_TICKS_PER_SEC改为1000U。根据CubeMX生成的工程的systick频率而来。
    2. !(废弃的方法)(KEIL MDK5)开启FPU:在keil中,如果下面这个设置了not used,就不会出错,但是是就不适用硬件计算浮点了(F429有这个功能);如果选了use single precision,那么对应的程序必须打开FPU。



      如何开启FPU:

      • 首先keil按上面打开
      • 在stm32f429xx.h中__FPU_PRESENT要为1
      • 在os_cpu_a.asm中会根据keil设置自动切换对FPU的支持。
      • Cortex-M4有个Lazy Stacking功能,如果使用FPU的话需要关闭这个功能,所以修改这个s文件。在starup_stm32f429xx.s中,要加上下面代码,;to enable FPU两个注释之间是要插入的代码。
            IMPORT  SystemInit
            IMPORT  __main
    
                     LDR     R0, =SystemInit
                     BLX     R0
                        ;to enable FPU
                        IF {FPU} != "SoftVFP"
                                                    ; Enable Floating Point Support at reset for FPU
                     LDR.W   R0, =0xE000ED88         ; Load address of CPACR register
                     LDR     R1, [R0]                ; Read value at CPACR
                     ORR     R1,  R1, #(0xF <<20)    ; Set bits 20-23 to enable CP10 and CP11 coprocessors
                                                    ; Write back the modified CPACR value
                     STR     R1, [R0]                ; Wait for store to complete
                     DSB
                    
                                                    ; Disable automatic FP register content
                                                    ; Disable lazy context switch
                     LDR.W   R0, =0xE000EF34         ; Load address to FPCCR register
                     LDR     R1, [R0]
                     AND     R1,  R1, #(0x3FFFFFFF)  ; Clear the LSPEN and ASPEN bits
                     STR     R1, [R0]
                     ISB                             ; Reset pipeline now the FPU is enabled
                     ENDIF
                        ;to enable FPU
                     LDR     R0, =__main
                     BX      R0
                     ENDP
    
    1. !(废弃的方法)(IAR EWARM8)开启FPU:在keil中,如果下面这个设置了none,就不会出错,但是是就不使用硬件计算浮点了(F429有这个功能);如果选了VFPv4 single precision,那么对应的程序必须打开FPU。



      如何开启FPU:

      • 首先IAR按上面打开
      • 在stm32f429xx.h中__FPU_PRESENT要为1
      • 在os_cpu_a.asm中已有对FPU的支持。
      • Cortex-M4有个Lazy Stacking功能,如果使用FPU的话需要关闭这个功能,所以修改这个s文件。在starup_stm32f429xx.s中,要加上下面代码,;to enable FPU两个注释之间是要插入的代码。
    THUMB
            PUBWEAK Reset_Handler
            SECTION .text:CODE:REORDER:NOROOT(2)
    Reset_Handler
    
            LDR     R0, =SystemInit
            BLX     R0
            ;to enable FPU
            #ifdef __ARMVFP__
                                        ; Enable Floating Point Support at reset for FPU
            LDR.W   R0, =0xE000ED88         ; Load address of CPACR register
            LDR     R1, [R0]                ; Read value at CPACR
            ORR     R1,  R1, #(0xF <<20)    ; Set bits 20-23 to enable CP10 and CP11 coprocessors
                                        ; Write back the modified CPACR value
            STR     R1, [R0]                ; Wait for store to complete
            DSB
    
                                        ; Disable automatic FP register content
                                        ; Disable lazy context switch
            LDR.W   R0, =0xE000EF34         ; Load address to FPCCR register
            LDR     R1, [R0]
            AND     R1,  R1, #(0x3FFFFFFF)  ; Clear the LSPEN and ASPEN bits
            STR     R1, [R0]
            ISB                             ; Reset pipeline now the FPU is enabled
            #endif
            ;to enable FPU
            LDR     R0, =__iar_program_start
            BX      R0
    

    到此为止,UCOSII移植完毕,测试正常。

    相关文章

      网友评论

        本文标题:STM32F429移植UCOSII笔记

        本文链接:https://www.haomeiwen.com/subject/qfpcdctx.html