(2025小白全踩坑版)【OpenHarmony】移植 3.1 版本系统到 STM32F407ZG开发板

发布于:2025-05-24 ⋅ 阅读:(13) ⋅ 点赞:(0)

在上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/gcc

INTERNAL_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/Include

include My_Path.mk

# 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 = 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>&copy; 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 parameter
    osStatus_t result;
    // osKernelState_t state; // Not strictly needed from the example logic provided

    if (osKernelGetState() == osKernelInactive)
    {
        //System not started, use blocking transmit
        HAL_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 complete
        result = osSemaphoreAcquire(UART1_TX_DMA_SemaphoreHandle, osWaitForever); // Wait indefinitely
        if (result == osOK)
        {
            HAL_UART_Transmit_DMA(&huart1, (uint8_t *)ptr, len); //Acquired successfully, send data
            return 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 Kernel
  UART1_TX_DMA_SemaphoreHandle = osSemaphoreNew(1, 1, &UART1_TX_DMA_Semaphore_attributes); // Create semaphore, initial count 1, max 1
  uart_taskHandle = osThreadNew(Uart_Task, NULL, &uart_task_attributes); // Create Uart_Task
  
  if (UART1_TX_DMA_SemaphoreHandle == NULL || uart_taskHandle == NULL) {
    // Error handling for semaphore or task creation failure
    Error_Handler();
  }

  printf("System Init!\r\n"); // Print before starting kernel, uses blocking transmit

  osKernelStart(); // 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 parameter
    while (1)
    {
        printf("System Running!!!\r\n"); // This will now use DMA via _write
        osDelay(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"。

请把以下的地址换为自己的地址

"command"这里

{
    "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" 等其他任务,也需要相应修改
    ]
}

打开git bash

cd到个人的项目中
例如我的目录是 D:\Harmonylite\kernel_liteos_m

# 首先,切换到 D 盘 (如果你的 Git Bash 默认不在 D 盘)
cd /d/

# 然后,进入到你的工程目录
# 请将下面的路径替换成你实际的工程路径!
cd Harmonylite/kernel_liteos_m/targets/OPENHM/
make -j12

看是否编译成功

填写完之后Ctrl+Shift+B
选择run task
编译成功

连接开发板,打开串口 
注意波特率配置

成功! 


网站公告

今日签到

点亮在社区的每一天
去签到