(2025小白全踩坑版)【OpenHarmony】移植 3.1 版本系统到 STM32F407ZG开发板
在上stm32课程,有这样一道要求:
参考了大佬的文章之后,发现出现了liteos_m.mk文件找不到的情况,于是只能另寻他路
VSCode 搭建 STM32 开发环境_vscode stm32仿真-CSDN博客
【OpenHarmony】移植 3.1 版本系统到 STM32_openharmony移植到stm32-CSDN博客
然后看到评论区也有相同的问题,估计是代码的仓库变了,但是由于根本看不懂仓库,只能另寻他路 ,经过重重困难,终于将实验做出来,在这里分享给大家

实验准备
1. STM32F407ZG 开发板 (可以是你用的具体型号,如正点原子探索者、野火指南者等)
2. ST-LINK 调试器 (板载或独立)
3. vscode
4. STM32CubeMX
5. Git 工具(默认安装)
6. OpenOCD https://gnutoolchains.com/arm-eabi/openocd/
7. arm-none-eabi-gcc 编译器下载Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer
8. make工具安装
https://sourceforge.net/projects/ezwinports/files/
下载make-4.1-2-without-guile-w32-bin.zip
9.xcom串口调试
前期安装
1. 将openocd,arm-none-eabi-gcc,make下载之后安装到环境变量
make下载完之后,直接复制到到 GIT 安装路径下的 mingw64 文件夹 Git\mingw64\
,放进去选择重复文件不要覆盖
2. 找到系统变量
点击path
新建三个变量,注意该路劲需要改到自己的路径下
打开vscode 终端,输入
make --version
其他两个可以仿照这样检查是否安装成功
查看是否安装成功
git操作
创建一个文件夹,git
git clone https://gitee.com/openharmony/kernel_liteos_m.git
cd kernel_liteos_m
mkdir ./third_party
cd third_party
git clone https://gitee.com/openharmony/third_party_bounds_checking_function.git ./bounds_checking_function
git clone https://gitee.com/openharmony/third_party_cmsis.git ./cmsis
git clone https://gitee.com/openharmony/third_party_musl.git ./musl
初始化stm32cubemx
修改 HAL 库延时的基础时钟,改为其他非 SysTick 的定时器,避免 HAL 库延时的定时器和系统运行的定时器冲突:
导出
生成源码之后,在clone下来的仓库中新建一个targets文件夹,把源码放入改文件夹
文件配置
创建 target_config.h (在 OPENHM 工程目录下):
#ifndef _TARGET_CONFIG_H
#define _TARGET_CONFIG_H#include "stm32f4xx.h"
#include "stm32f4xx_it.h"#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif /* __cplusplus */
#endif /* __cplusplus *//*=============================================================================System clock module configuration
=============================================================================*/
#define OS_SYS_CLOCK SystemCoreClock
#define LOSCFG_BASE_CORE_TICK_PER_SECOND (1000UL)
#define LOSCFG_BASE_CORE_TICK_HW_TIME 0
#define LOSCFG_BASE_CORE_TICK_WTIMER 0
#define LOSCFG_BASE_CORE_TICK_RESPONSE_MAX SysTick_LOAD_RELOAD_Msk/*=============================================================================Hardware interrupt module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_HWI 0
#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
#define LOSCFG_PLATFORM_HWI_LIMIT 128/*=============================================================================Openharmony Kernel configuration
=============================================================================*//*=============================================================================Task module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_TSK_LIMIT 24
#define LOSCFG_BASE_CORE_TSK_IDLE_STACK_SIZE (0x500U)
#define LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE (0x2D0U)
#define LOSCFG_BASE_CORE_TSK_MIN_STACK_SIZE (0x130U)
#define LOSCFG_BASE_CORE_TIMESLICE 1
#define LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT 20000
/*=============================================================================Semaphore module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_SEM 1
#define LOSCFG_BASE_IPC_SEM_LIMIT 48/*=============================================================================Mutex module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_MUX 1
#define LOSCFG_BASE_IPC_MUX_LIMIT 24
/*=============================================================================Queue module configuration
=============================================================================*/
#define LOSCFG_BASE_IPC_QUEUE 1
#define LOSCFG_BASE_IPC_QUEUE_LIMIT 24
/*=============================================================================Software timer module configuration
=============================================================================*/
#define LOSCFG_BASE_CORE_SWTMR 1
#define LOSCFG_BASE_CORE_SWTMR_ALIGN 1
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 48
/*=============================================================================Memory module configuration
=============================================================================*/
#define LOSCFG_MEM_MUL_POOL 1
#define OS_SYS_MEM_NUM 20
/*=============================================================================Exception module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_EXC 1/*=============================================================================TestSuite configuration
=============================================================================*/
#define LOSCFG_TEST 0#ifndef LOSCFG_BACKTRACE_TYPE
#define LOSCFG_BACKTRACE_TYPE 1
#endif
/*** @ingroup los_config* Configuration backtrace depth.*/
#ifndef LOSCFG_BACKTRACE_DEPTH
#define LOSCFG_BACKTRACE_DEPTH 15
#endif
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */#endif /* _TARGET_CONFIG_H */
修改 Makefile 以集成 LiteOS-M 内核
创建 my_path.mk (在 OPENHM 工程目录下)
# Topdir 顶层目录
LITEOSTOPDIR := ../../ # Correct path from OPENHM to kernel_liteos_m root
LITEOSTOPDIR := $(realpath $(LITEOSTOPDIR))# Variables to hold LiteOS-M specific sources and includes
INTERNAL_C_SOURCES :=
INTERNAL_ASMS_SOURCES :=
INTERNAL_C_INCLUDES :=
INTERNAL_ASFLAGS :=
INTERNAL_CFLAGS :=# Common 内核源文件及头文件目录
INTERNAL_C_SOURCES += \$(wildcard $(LITEOSTOPDIR)/kernel/src/*.c) \$(wildcard $(LITEOSTOPDIR)/kernel/src/mm/*.c) \$(wildcard $(LITEOSTOPDIR)/components/cpup/*.c) \$(wildcard $(LITEOSTOPDIR)/components/power/*.c) \$(wildcard $(LITEOSTOPDIR)/components/backtrace/*.c) \$(wildcard $(LITEOSTOPDIR)/components/exchook/*.c) \$(wildcard $(LITEOSTOPDIR)/components/signal/*.c) \$(wildcard $(LITEOSTOPDIR)/utils/*.c)INTERNAL_C_INCLUDES += \-I$(LITEOSTOPDIR)/utils \-I$(LITEOSTOPDIR)/kernel/include \-I$(LITEOSTOPDIR)/components/cpup \-I$(LITEOSTOPDIR)/components/power \-I$(LITEOSTOPDIR)/components/backtrace \-I$(LITEOSTOPDIR)/components/exchook \-I$(LITEOSTOPDIR)/components/signal \-I$(LITEOSTOPDIR)/components/fs/vfs # Third party related 第三方依赖文件及头文件目录
INTERNAL_C_SOURCES += \$(wildcard $(LITEOSTOPDIR)/third_party/bounds_checking_function/src/*.c)\$(wildcard $(LITEOSTOPDIR)/kal/cmsis/*.c)\$(wildcard $(LITEOSTOPDIR)/kal/posix/src/*.c)INTERNAL_C_INCLUDES += \-I$(LITEOSTOPDIR)/third_party/bounds_checking_function/include \-I$(LITEOSTOPDIR)/third_party/bounds_checking_function/src\-I$(LITEOSTOPDIR)/third_party/cmsis/CMSIS/RTOS2/Include \-I$(LITEOSTOPDIR)/third_party/musl/porting/liteos_m/kernel/include\-I$(LITEOSTOPDIR)/third_party/musl/src/include \-I$(LITEOSTOPDIR)/kal/cmsis \-I$(LITEOSTOPDIR)/kal/posix/include \-I$(LITEOSTOPDIR)/kal/posix/musl_src/internal# Arch related
INTERNAL_ASMS_SOURCES += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.S)INTERNAL_C_SOURCES += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.c) \$(wildcard $(LITEOSTOPDIR)/arch/arm/common/*.c)INTERNAL_C_INCLUDES += -I. \-I$(LITEOSTOPDIR)/arch/include \-I$(LITEOSTOPDIR)/arch/arm/common \-I$(LITEOSTOPDIR)/arch/arm/cortex-m4/gccINTERNAL_CFLAGS += -nostdinc -nostdlib
INTERNAL_ASFLAGS += -imacros $(LITEOSTOPDIR)/kernel/include/los_config.h -DCLZ=CLZ# Append to main Makefile variables
C_SOURCES += $(INTERNAL_C_SOURCES)
ASMM_SOURCES += $(INTERNAL_ASMS_SOURCES)
C_INCLUDES += $(INTERNAL_C_INCLUDES)
ASFLAGS += $(INTERNAL_ASFLAGS)
CFLAGS += $(INTERNAL_CFLAGS)# Remove any direct modification to OBJECTS from my_path.mk
# For example, lines like:
# OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
# OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
# should be removed if they existed.
# The compilation rules for .c and .S files from my_path.mk are also removed,
# as the main Makefile should handle them based on the populated C_SOURCES and ASMM_SOURCES.
# Specific compilation rule for .S files if needed (usually handled by main Makefile's AS rule):
# $(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
# $(CC) -c $(CFLAGS) $(ASFLAGS) $< -o $@
修改主 Makefile (在 OPENHM 工程目录下)
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.6.0.1-B1] date: [Wed May 21 12:17:39 CST 2025]
########################################################################################################################### ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
# 2017-02-10 - Several enhancements + project update mode
# 2015-07-22 - first version
# ------------------------------------------------######################################
# target
######################################
TARGET = OPENHM######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og#######################################
# paths
#######################################
# Build path
BUILD_DIR = build######################################
# source
######################################
# C sources
C_SOURCES = \
Core/Src/main.c \
Core/Src/gpio.c \
Core/Src/usart.c \
Core/Src/stm32f4xx_it.c \
Core/Src/stm32f4xx_hal_msp.c \
Core/Src/stm32f4xx_hal_timebase_tim.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 # ASM sources
ASM_SOURCES = \
startup_stm32f407xx.s# ASM sources
ASMM_SOURCES = #######################################
# 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 \
-DSTM32F407xx# 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/Includeinclude my_path.mk# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sectionsCFLAGS += $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sectionsifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32F407XX_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)))
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMM_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMM_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)/%.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 ***
修改链接脚本targets\OpenHarmony_Demo\STM32F407ZGTx_FLASH.l中
/*
******************************************************************************
**** File : LinkerScript.ld
**
** Author : STM32CubeMX
**
** Abstract : Linker script for STM32F407ZGTx series
** 1024Kbytes FLASH and 192Kbytes RAM
**
** Set heap size, stack size and stack location according
** to application requirements.
**
** Set memory bank area and size if external memory is used.
**
** Target : STMicroelectronics STM32
**
** Distribution: The file is distributed "as is," without any warranty
** of any kind.
**
*****************************************************************************
** @attention
**
** <h2><center>© COPYRIGHT(c) 2025 STMicroelectronics</center></h2>
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** 1. Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
** and/or other materials provided with the distribution.
** 3. Neither the name of STMicroelectronics nor the names of its contributors
** may be used to endorse or promote products derived from this software
** without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************************
*//* Entry Point */
ENTRY(Reset_Handler)/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of RAM */
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack *//* Lowest address of the user mode stack */
_sstack = 0x20000000; /* start of RAM *//* Specify the memory areas */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 1024K
}/* Define output sections */
SECTIONS
{/* The startup code goes first into FLASH */.isr_vector :{. = ALIGN(4);KEEP(*(.isr_vector)) /* Startup code */. = ALIGN(4);} >FLASH/* The program code and other data goes into FLASH */.text :{ _stext = .; /* define a global symbol at code start */. = ALIGN(4);*(.text) /* .text sections (code) */*(.text*) /* .text* sections (code) */*(.glue_7) /* glue arm to thumb code */*(.glue_7t) /* glue thumb to arm code */*(.eh_frame)KEEP (*(.init))KEEP (*(.fini)). = ALIGN(4);_etext = .; /* define a global symbols at end of code */} >FLASH/* Constant data goes into FLASH */.rodata :{. = ALIGN(4);*(.rodata) /* .rodata sections (constants, strings, etc.) */*(.rodata*) /* .rodata* sections (constants, strings, etc.) */. = ALIGN(4);} >FLASH.ARM.extab : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */{. = ALIGN(4);*(.ARM.extab* .gnu.linkonce.armextab.*). = ALIGN(4);} >FLASH.ARM : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */{. = ALIGN(4);__exidx_start = .;*(.ARM.exidx*)__exidx_end = .;. = ALIGN(4);} >FLASH.preinit_array : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */{. = ALIGN(4);PROVIDE_HIDDEN (__preinit_array_start = .);KEEP (*(.preinit_array*))PROVIDE_HIDDEN (__preinit_array_end = .);. = ALIGN(4);} >FLASH.init_array : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */{. = ALIGN(4);PROVIDE_HIDDEN (__init_array_start = .);KEEP (*(SORT(.init_array.*)))KEEP (*(.init_array*))PROVIDE_HIDDEN (__init_array_end = .);. = ALIGN(4);} >FLASH.fini_array : /* The "READONLY" keyword is only supported in GCC11 and later, remove it if using GCC10 or earlier. */{. = ALIGN(4);PROVIDE_HIDDEN (__fini_array_start = .);KEEP (*(SORT(.fini_array.*)))KEEP (*(.fini_array*))PROVIDE_HIDDEN (__fini_array_end = .);. = ALIGN(4);} >FLASH/* used by the startup to initialize data */_sidata = LOADADDR(.data);/* Initialized data sections goes into RAM, load LMA copy after code */.data :{. = ALIGN(4);_sdata = .; /* create a global symbol at data start */*(.data) /* .data sections */*(.data*) /* .data* sections */*(.RamFunc) /* .RamFunc sections */*(.RamFunc*) /* .RamFunc* sections */. = ALIGN(4);_edata = .; /* define a global symbol at data end */} >RAM AT> FLASH_siccmram = LOADADDR(.ccmram);/* CCM-RAM section** IMPORTANT NOTE!* If initialized variables will be placed in this section,* the startup code needs to be modified to copy the init-values.*/.ccmram :{. = ALIGN(4);_sccmram = .; /* create a global symbol at ccmram start */*(.ccmram)*(.ccmram*). = ALIGN(4);_eccmram = .; /* create a global symbol at ccmram end */} >CCMRAM AT> FLASH/* Uninitialized data section */. = ALIGN(4);.bss :{/* This is used by the startup in order to initialize the .bss secion */_sbss = .; /* define a global symbol at bss start */__bss_start__ = _sbss;*(.bss)*(.bss*)*(COMMON). = ALIGN(4);_ebss = .; /* define a global symbol at bss end */__bss_end__ = _ebss;} >RAM/* User_heap_stack section, used to check that there is enough RAM left */._user_heap_stack :{. = ALIGN(8);PROVIDE ( end = . );PROVIDE ( _end = . );. = . + _Min_Heap_Size;. = . + _Min_Stack_Size;. = ALIGN(8);} >RAM/* Remove information from the standard libraries *//DISCARD/ :{libc.a ( * )libm.a ( * )libgcc.a ( * )}}
适配中断服务函数
目标文件:Core/Src/stm32f4xx_it.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file stm32f4xx_it.c* @brief Interrupt Service Routines.******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "los_arch_interrupt.h" // For HalPendSV and other Arch specific interrupt defs
#include "los_tick.h" // For OsTickHandler
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD *//* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*/
extern TIM_HandleTypeDef htim1;/* USER CODE BEGIN EV *//* USER CODE END EV *//******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 */while (1){}/* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles Memory management fault.*/
void MemManage_Handler(void)
{/* USER CODE BEGIN MemoryManagement_IRQn 0 *//* USER CODE END MemoryManagement_IRQn 0 */while (1){/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 *//* USER CODE END W1_MemoryManagement_IRQn 0 */}
}/*** @brief This function handles Pre-fetch fault, memory access fault.*/
void BusFault_Handler(void)
{/* USER CODE BEGIN BusFault_IRQn 0 *//* USER CODE END BusFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_BusFault_IRQn 0 *//* USER CODE END W1_BusFault_IRQn 0 */}
}/*** @brief This function handles Undefined instruction or illegal state.*/
void UsageFault_Handler(void)
{/* USER CODE BEGIN UsageFault_IRQn 0 *//* USER CODE END UsageFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_UsageFault_IRQn 0 *//* USER CODE END W1_UsageFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVCall_IRQn 0 *//* USER CODE END SVCall_IRQn 0 *//* USER CODE BEGIN SVCall_IRQn 1 *//* USER CODE END SVCall_IRQn 1 */
}/*** @brief This function handles Debug monitor.*/
void DebugMon_Handler(void)
{/* USER CODE BEGIN DebugMonitor_IRQn 0 *//* USER CODE END DebugMonitor_IRQn 0 *//* USER CODE BEGIN DebugMonitor_IRQn 1 *//* USER CODE END DebugMonitor_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 */HalPendSV();/* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 */OsTickHandler();/* USER CODE END SysTick_IRQn 0 */HAL_IncTick(); // Keep HAL_IncTick if your HAL driver relies on it for timebases other than the OS tick/* USER CODE BEGIN SysTick_IRQn 1 *//* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************//*** @brief This function handles TIM1 update interrupt and TIM10 global interrupt.*/
void TIM1_UP_TIM10_IRQHandler(void)
{/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 0 *//* USER CODE END TIM1_UP_TIM10_IRQn 0 */HAL_TIM_IRQHandler(&htim1);/* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 *//* USER CODE END TIM1_UP_TIM10_IRQn 1 */
}/* USER CODE BEGIN 1 *//* USER CODE END 1 */
修改 main.c 实现 LiteOS-M 初始化和测试任务
目标文件:Core/Src/main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "cmsis_os2.h" // CMSIS-RTOS API v2
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
osSemaphoreId_t UART1_TX_DMA_SemaphoreHandle;
const osSemaphoreAttr_t UART1_TX_DMA_Semaphore_attributes = {.name = "UART1_TX_DMA_Semaphore",
};osThreadId_t uart_taskHandle;
const osThreadAttr_t uart_task_attributes = {.name = "uart_task",.stack_size = 512 * 2, // 1024 bytes.priority = (osPriority_t)osPriorityNormal3,
};
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void Uart_Task(void *argument);
/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#if 1 // Enable printf redirection
int _write(int fd, char *ptr, int len)
{(void)fd; // Unused parameterosStatus_t result;// osKernelState_t state; // Not strictly needed from the example logic providedif (osKernelGetState() == osKernelInactive){//System not started, use blocking transmitHAL_UART_Transmit(&huart1, (uint8_t *)ptr, len, 0xFFFF);return len;}else{//Acquire semaphore, if previous DMA transfer is complete//Semaphore will be acquired, otherwise task will be suspended//until transfer is completeresult = osSemaphoreAcquire(UART1_TX_DMA_SemaphoreHandle, osWaitForever); // Wait indefinitelyif (result == osOK){HAL_UART_Transmit_DMA(&huart1, (uint8_t *)ptr, len); //Acquired successfully, send datareturn len;}else{return -1; //Acquisition failed}}
}
#endif/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */osKernelInitialize(); // Initialize CMSIS-RTOS KernelUART1_TX_DMA_SemaphoreHandle = osSemaphoreNew(1, 1, &UART1_TX_DMA_Semaphore_attributes); // Create semaphore, initial count 1, max 1uart_taskHandle = osThreadNew(Uart_Task, NULL, &uart_task_attributes); // Create Uart_Taskif (UART1_TX_DMA_SemaphoreHandle == NULL || uart_taskHandle == NULL) {// Error handling for semaphore or task creation failureError_Handler();}printf("System Init!\r\n"); // Print before starting kernel, uses blocking transmitosKernelStart(); // Start CMSIS-RTOS Kernel & Task scheduling/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 4;RCC_OscInitStruct.PLL.PLLN = 168;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
// DMA transfer complete callback
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{if (huart->Instance == USART1) // Check if it's USART1{osSemaphoreRelease(UART1_TX_DMA_SemaphoreHandle);}
}void Uart_Task(void *argument)
{(void)argument; // Unused parameterwhile (1){printf("System Running!!!\r\n"); // This will now use DMA via _writeosDelay(1000); // CMSIS-RTOS delay for 1000ms}
}
/* USER CODE END 4 *//*** @brief Period elapsed callback in non blocking mode* @note This function is called when TIM1 interrupt took place, inside* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment* a global variable "uwTick" used as application time base.* @param htim : TIM handle* @retval None*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* USER CODE BEGIN Callback 0 *//* USER CODE END Callback 0 */if (htim->Instance == TIM1){HAL_IncTick();}/* USER CODE BEGIN Callback 1 *//* USER CODE END Callback 1 */
}/*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
编译项目
打开.vscode文件夹下的tasks.json文件,如果没有的
按 Ctrl+Shift+P 打开命令面板,输入 "Tasks: Configure Task",选择 "Create tasks.json file from template",然后选择 "Others"。
{"version": "2.0.0","tasks": [{"label": "project build: OPENHM","type": "shell","command": "cd ./Harmonylite/kernel_liteos_m/targets/OPENHM && make -j12","group": {"kind": "build","isDefault": true},"presentation": {"reveal": "always","panel": "shared","clear": true},"problemMatcher": "$gcc"},{"label": "project clean: OPENHM","type": "shell","command": "cd ./Harmonylite/kernel_liteos_m/targets/OPENHM && make clean","group": "build","presentation": {"reveal": "always","panel": "shared","clear": true},"problemMatcher": []},{"label": "project download: OPENHM (OpenOCD)","type": "shell","command": "cd ./Harmonylite/kernel_liteos_m/targets/OPENHM && openocd -f interface/stlink-v2.cfg -f target/stm32f4x.cfg -c \"program build/OPENHM.elf verify reset exit\"","group": {"kind": "test","isDefault": false},"presentation": {"reveal": "always","panel": "shared","clear": true},"problemMatcher": []}// 如果原来还有 "build & download" 等其他任务,也需要相应修改]
}
填写完之后Ctrl+Shift+B
编译成功
连接开发板,打开串口
注意波特率配置
成功!