1.準(zhǔn)備相關(guān)文件
直接使用官方的STM32F4移植例程杰标,里面也包含UCOSII的源代碼值桩。
進(jìn)入官網(wǎng)下載中心:
https://www.micrium.com/downloadcenter/
Browse by MCU Manufacturer,然后找到STM32F4:
點(diǎn)進(jìn)去蜗元,選這個(gè)UCOSII的工程:
紅框是這個(gè)工程主要用于評(píng)估的項(xiàng)目,這個(gè)工程是用于評(píng)估UCOSII的,比較容易移植刘急,另外,這個(gè)工程支持右面4個(gè)IDE浸踩,比較方便叔汁。
然后準(zhǔn)備自己的STM32工程,可以用CubeMX創(chuàng)建检碗,在創(chuàng)建好的工程中新建一個(gè)UCOSII的文件夾用于存放UCOSII相關(guān)的代碼文件据块。
下載好的工程打開,找到下面這三個(gè)文件夾折剃,復(fù)制到UCOSII文件夾中另假。
然后在UCOSII中新建兩個(gè)文件夾:uCOS-BSP和uCOS-Config,將Micrium\Examples\ST\STM3240G-EVAL\BSP下的這三個(gè)文件復(fù)制到uCOS-BSP中:
然后將Micrium\Examples\ST\STM3240G-EVAL\OS2下的這6個(gè)文件復(fù)制到uCOS-Config:
最后怕犁,新建一個(gè)頭文件“includes.h”放到uCOS-Config文件夾中浪谴,內(nèi)容如下:
/************************************************
* 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
到現(xiàn)在為止UCOSII的文件都已經(jīng)添加到項(xiàng)目中了,現(xiàn)在項(xiàng)目文件結(jié)構(gòu)應(yīng)該是這樣的:
2. 編譯測(cè)試
在移植來(lái)的BSP中寫了許多example因苹,會(huì)關(guān)聯(lián)到官方項(xiàng)目的其他文件苟耻,現(xiàn)在把他們刪除。也就是修改bsp.c扶檐、bsp.h兩個(gè)文件凶杖。
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. */
現(xiàn)在,這個(gè)工程應(yīng)該可以編譯了款筑。
由于我用的vscode智蝠,使用makefile進(jìn)行編譯腾么,所以要把UCOSII的源代碼文件、asm文件杈湾、頭文件引用目錄加入到makefile中解虱。
vscode里有復(fù)制相對(duì)路徑功能很好用:
但是復(fù)制的相對(duì)路徑是win平臺(tái)的路徑格式,我用的makefile是要在minGW中運(yùn)行的漆撞,所以要轉(zhuǎn)為sh的路徑格式殴泰,也就是''要改成'/',然后不是最后一個(gè)文件的話后面要加換行符 浮驳。改好的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文件所在的目錄至会,并且父目錄對(duì)子目錄無(wú)效的离咐。
另外,在我們移植來(lái)的文件中會(huì)出現(xiàn)這種情況:
這個(gè)時(shí)候如果是Keil選擇RealView奉件,IAR選擇IAR宵蛀,makefile用的是GNU,選擇GNU下的文件县貌。
makefile改一下术陶,就可以編譯測(cè)試了。但是在make過(guò)程中出現(xiàn)了這樣的錯(cuò)誤:
mingw32-make: *** No rule to make target 'build/os_cpu_a.S', needed by 'build/STM32F429IGT-UCOSII.elf'. Stop.
終端進(jìn)程已終止窃这,退出代碼: 2
這是因?yàn)閛s_cpu_a.S文件的后綴不符合我們makefile中的規(guī)則(makefile中規(guī)則只對(duì)于.s文件)瞳别,把這文件后綴改為小寫,再次編譯杭攻,成功祟敛。
3. 編寫UCOS的include文件
創(chuàng)建一個(gè)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. 修改文件
- PendSV_Handler():把os_cpu_a.s中的OS_CPU_PendSVHandler函數(shù)改為PendSV_Handler馆铁,總共兩處。然后把stm32f4xx_it.c中的
void PendSV_Handler(void)
去掉锅睛,對(duì)應(yīng)h文件的void PendSV_Handler(void);
也去掉埠巨,原因是在os_cpu_a.s已經(jīng)定義。 - SysTick_Handler():在os_cpu_c.c中定義了OS_CPU_SysTickHandler()现拒,但是同上面的pendsv一樣辣垒,名稱和啟動(dòng)文件.s中的vector不符,把這個(gè)函數(shù)定義和在頭文件中的聲明注釋掉印蔬。(不注釋掉應(yīng)該也行)勋桶。然后把這個(gè)函數(shù)里的內(nèi)容復(fù)制到stm32f4xx_it.c的SysTick_Handler()中,OSIntNesting++這個(gè)我參考其他人的教程沒有復(fù)制,具體原因沒有測(cè)試例驹。并且捐韩,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 */
}
- 按照下面5或6的第一步鹃锈,在IDE上打開FPU(makefile的工程在makefile中已經(jīng)設(shè)置好了)荤胁,第二步設(shè)置tm32f429xx.h中__FPU_PRESENT為1。下面的步驟是把廢棄的5屎债、6步的匯編變成C語(yǔ)言放在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;
- 設(shè)置UCOSII的時(shí)鐘:OS_TICKS_PER_SEC改為1000U已旧。根據(jù)CubeMX生成的工程的systick頻率而來(lái)秸苗。
-
U倌取(廢棄的方法)(KEIL MDK5)開啟FPU:在keil中,如果下面這個(gè)設(shè)置了not used惊楼,就不會(huì)出錯(cuò)玖瘸,但是是就不適用硬件計(jì)算浮點(diǎn)了(F429有這個(gè)功能);如果選了use single precision檀咙,那么對(duì)應(yīng)的程序必須打開FPU雅倒。
如何開啟FPU:
- 首先keil按上面打開
- 在stm32f429xx.h中__FPU_PRESENT要為1
- 在os_cpu_a.asm中會(huì)根據(jù)keil設(shè)置自動(dòng)切換對(duì)FPU的支持。
- Cortex-M4有個(gè)Lazy Stacking功能弧可,如果使用FPU的話需要關(guān)閉這個(gè)功能蔑匣,所以修改這個(gè)s文件。在starup_stm32f429xx.s中棕诵,要加上下面代碼裁良,
;to enable FPU
兩個(gè)注釋之間是要插入的代碼。
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
-
PL住(廢棄的方法)(IAR EWARM8)開啟FPU:在keil中价脾,如果下面這個(gè)設(shè)置了none,就不會(huì)出錯(cuò)笛匙,但是是就不使用硬件計(jì)算浮點(diǎn)了(F429有這個(gè)功能)侨把;如果選了VFPv4 single precision,那么對(duì)應(yīng)的程序必須打開FPU妹孙。
如何開啟FPU:
- 首先IAR按上面打開
- 在stm32f429xx.h中__FPU_PRESENT要為1
- 在os_cpu_a.asm中已有對(duì)FPU的支持秋柄。
- Cortex-M4有個(gè)Lazy Stacking功能,如果使用FPU的話需要關(guān)閉這個(gè)功能蠢正,所以修改這個(gè)s文件骇笔。在starup_stm32f429xx.s中,要加上下面代碼,
;to enable FPU
兩個(gè)注釋之間是要插入的代碼蜘拉。
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移植完畢,測(cè)試正常旭旭。