stm32 series chip porting to openhrmony3.0 liteos_m
I have found many articles before, but because there are few articles in this regard, and the official website documents are too concise, the transplantation process is cumbersome, so I hereby record it.
Attach final template address: https://gitee.com/emb-y/hm3-to-stm32
1, Create stm32cubemx template project
In order to facilitate the migration, first use stm32cubemx to generate the template project, taking stm32f411 as an example
Of course, the helloworld of embedded people - lights up to prove whether the transplantation is successful
The led of this core board is in pc13, and a template program is directly generated with cubemx
Here, only pc13 is initialized to Output
Just set a name and set the tool chain to MakeFile, and then click generate.
The project catalogue is as follows:
2, Add the configuration file required by Hongmeng and modify MakeFile
Reference here Teacher Lian Zhian's post And Hongmeng official documents
Add target_config.h to the project root directory
#ifndef _TARGET_CONFIG_H #define _TARGET_CONFIG_H #include "stm32f4xx.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 1 #define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 1 #define LOSCFG_PLATFORM_HWI_LIMIT 128 /*============================================================================= 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 0 #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 /* ============================================================================= printf module configuration ============================================================================= */ #define LOSCFG_KERNEL_PRINTF 1 #define LOSCFG_BASE_CORE_SCHED_SLEEP 1 #define LOSCFG_SYS_HEAP_SIZE 0x4000UL #ifdef __cplusplus #if __cplusplus } #endif /* __cplusplus */ #endif /* __cplusplus */ #endif /* _TARGET_CONFIG_H */
The file is liteos_m's profile
Add the build.sh file to the root directory
#!/bin/bash set -e OUT_DIR="$1" TOOLCHAIN_DIR="$2" function main(){ ROOT_DIR=$(cd $(dirname "$0");pwd) if [ -z "${TOOLCHAIN_DIR}" ]; then make clean && make -j16 OUT_DIR_PATH=${OUT_DIR} else make clean && make -j16 OUT_DIR_PATH=${OUT_DIR} TOOLCHAIN_DIR_PATH=${TOOLCHAIN_DIR} fi } main "$@"
This file is a compiled script
Create a new liteos in the root directory_ M folder and add the config.gni file
# Kernel type, e.g. "linux", "liteos_a", "liteos_m". kernel_type = "liteos_m" # Kernel version. kernel_version = "3.0.0" # Board CPU type, e.g. "cortex-a7", "riscv32". board_cpu = "cortex-m4" # Board arch, e.g. "armv7-a", "rv32imac". board_arch = "" # Toolchain name used for system compiling. # E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. # Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toochain. board_toolchain = "arm-none-eabi-gcc" # The toolchain path instatlled, it's not mandatory if you have added toolchian path to your ~/.bashrc. board_toolchain_path = "" # Compiler prefix. board_toolchain_prefix = "arm-none-eabi-" # Compiler type, "gcc" or "clang". board_toolchain_type = "gcc" # Board related common compile flags. board_cflags = [ "-mcpu=cortex-m4", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard", "-mthumb", "-Og", "-fdata-sections", "-ffunction-sections", "-DUSE_HAL_DRIVER", # Modify as appropriate!!!!!!!!!!! "-DSTM32F411xE", # Modify as appropriate!!!!!!!!!!! ] board_cxx_flags = board_cflags board_ld_flags = [] # Board related headfiles search path. # Modify as appropriate!!!!!!!!!!! board_include_dirs = [ "//kernel/liteos_m/kernel/arch/arm/cortex-m4/gcc", "//device/st/stm32f411core", "//device/st/stm32f411core/Core/Inc", "//device/st/stm32f411core/Drivers/CMSIS/Include", "//device/st/stm32f411core/Drivers/CMSIS/Device/ST/STM32F4xx/Include", "//device/st/stm32f411core/Drivers/STM32F4xx_HAL_Driver/Inc", "//device/st/stm32f411core/third_party/LWIP", "//drivers/framework/support/platform/include/common", "//kernel/liteos_m/kal/cmsis", ] # Board adapter dir for OHOS components. board_adapter_dir = "" # Sysroot path. board_configed_sysroot = "" # Board storage type, it used for file system generation. storage_type = ""
Including board_ The last two items of cflags need to be modified according to the chip, and the corresponding options can be found in the makefile
board_include_dirs is the dependent header file directory and needs to be modified
Modify Makefile file
# File automatically-generated by tool: [projectgenerator] version: [3.13.0-B3] date: [Fri Apr 30 08:31:16 CST 2021] ########################################################################################################################## # ------------------------------------------------ # Generic Makefile (based on gcc) # # ChangeLog : # 2017-02-10 - Several enhancements + project update mode # 2015-07-22 - first version # ------------------------------------------------ ###################################### # target ###################################### TARGET = stm32f411core_ninjia ####################################### # paths ####################################### # Build path BUILD_DIR = $(OUT_DIR_PATH) ####################################### # toolchain paths ####################################### # Toolchain path ifneq ($(TOOLCHAIN_DIR_PATH), ) GCC_PATH = $(TOOLCHAIN_DIR_PATH) endif ####################################### # 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. ifneq ($(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) ####################################### # LDFLAGS ####################################### # link script LDSCRIPT = STM32F411CEUx_FLASH.ld # Modify as appropriate!!!!!!!!!!! # libraries # Modify as appropriate!!!!!!!!!!! STATIC_LIB = -larch -lbacktrace -lcmsis -lcore -lcpup -lexchook -lkernel \ -lsec_static -lpm -lstartup_stm32f411xe -lSTM32F4xx_HAL_Driver -lutils \ -lhdf_core -lhdf_osal_lite STATIC_LIB_DIR = -L$(BUILD_DIR)/libs 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 ####################################### $(BUILD_DIR)/$(TARGET).elf: Makefile $(CC) $(STATIC_LIB_DIR) -Wl,--whole-archive -Wl,--start-group $(STATIC_LIB) -Wl,--end-group -Wl,--no-whole-archive $(LDFLAGS) -o $@ $(SZ) $@ $(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR) $(HEX) $< $@ $(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR) $(BIN) $< $@ $(BUILD_DIR): mkdir -p $@ ####################################### # clean up ####################################### clean: -rm -fR $(BUILD_DIR) # *** EOF ***
The ld file generated by LDSCRIPT needs to be modified
STATIC_ The option to link lib to. a file needs to be modified (if you don't know how to write it, you can compile it first, and find the Lib file to link in the out directory of Hongmeng source code)
Configure BUILD.gn script under directories at all levels
Root directory:
import("//build/lite/config/component/lite_component.gni") group("stm32f411core") { } build_ext_component("stm32f411core_ninjia") { exec_path = rebase_path(".", root_build_dir) outdir = rebase_path("$root_out_dir") print("$board_toolchain") if (board_toolchain_path != "") { toolchain_path = rebase_path("$board_toolchain_path") command = "./build.sh ${outdir} ${toolchain_path}" } else { command = "./build.sh ${outdir}" } deps = [ "//build/lite:ohos" ] } static_library("startup_stm32f411xe") { sources = [ "startup_stm32f411xe.s" ] include_dirs = [ "." ] deps = [ "//drivers/adapter/khdf/liteos_m:hdf_lite", "//device/st/stm32f411core/Core:core", "//device/st/stm32f411core/Drivers/STM32F4xx_HAL_Driver:STM32F4xx_HAL_Driver", ] }
Where sources is the name of the. s file generated by cubemx
group and build_ ext_ The component can be modified as appropriate
deps is the list of subordinate gn files
Drivers\STM32F4xx_ HAL_ BUILD.gn under driver:
static_library("STM32F4xx_HAL_Driver") { sources = [ "Src/stm32f4xx_hal_tim.c", "Src/stm32f4xx_hal_tim_ex.c", "Src/stm32f4xx_hal_rcc.c", "Src/stm32f4xx_hal_rcc_ex.c", "Src/stm32f4xx_hal_flash.c", "Src/stm32f4xx_hal_flash_ex.c", "Src/stm32f4xx_hal_flash_ramfunc.c", "Src/stm32f4xx_hal_gpio.c", "Src/stm32f4xx_hal_dma_ex.c", "Src/stm32f4xx_hal_dma.c", "Src/stm32f4xx_hal_pwr.c", "Src/stm32f4xx_hal_pwr_ex.c", "Src/stm32f4xx_hal_cortex.c", "Src/stm32f4xx_hal.c", "Src/stm32f4xx_hal_exti.c", ] include_dirs = [ "Inc", "Inc/Legacy", "../CMSIS/Include", "../CMSIS/Device/ST/STM32F4xx/Include", "//kernel/liteos_m/kal/cmsis", "../../Core/Inc", ] }
source and include_dirs is the directory of c files and header files, which can be modified as appropriate
BUILD.gn under Core:
static_library("core") { sources = [ "Src/main.c", "Src/stm32f4xx_hal_msp.c", "Src/stm32f4xx_it.c", "Src/system_stm32f4xx.c", ] include_dirs = [ "Inc", "../", "../Drivers/STM32F4xx_HAL_Driver/Inc", "../Drivers/CMSIS/Include", "../Drivers/CMSIS/Device/ST/STM32F4xx/Include", "//kernel/liteos_m/kernel/include", "//kernel/liteos_m/utils", "//kernel/liteos_m/kernel/arch/include", "//kernel/liteos_m/kal/cmsis" ] }
source and include_dirs is the directory of c files and header files, which can be modified as appropriate
Modify the main.c file
/* Includes ------------------------------------------------------------------*/ #include "main.h" #include "cmsis_os2.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* 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 */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void *LedTask(const char *arg); static void LedExampleEntry(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* 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 */ osKernelInitialize(); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ /* USER CODE BEGIN 2 */ LedExampleEntry(); /* USER CODE END 2 */ osKernelStart(); /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ osDelay(500); /* 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_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; 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_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief GPIO Initialization Function * @param None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); /*Configure GPIO pin : PC13 */ GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } /* USER CODE BEGIN 4 */ static void *LedTask(const char *arg) { (void)arg; while(1) { osDelay(500); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 0); osDelay(500); HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, 1); } return NULL; } static void LedExampleEntry(void) { osThreadAttr_t attr; MX_GPIO_Init(); attr.name = "LedTask"; attr.attr_bits = 0U; attr.cb_mem = NULL; attr.cb_size = 0U; attr.stack_mem = NULL; attr.stack_size = 1024; attr.priority = 13; if (osThreadNew((osThreadFunc_t)LedTask, NULL, &attr) == NULL) { printf("[LedExample] Falied to create LedTask!\n"); } } /* USER CODE END 4 */ /** * @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 */
The routine uses cmsis, which is the simplest way to create a task and make the light flash in the task.
Standardize the directory structure according to the official requirements of Hongmeng
Modify the stm32cubemx project name to stm32f411core
The rules are:
device / manufacturer name / board name
New in ventor folder
Create the following directory structure:
Write in the config.json file:
{ "product_name": "stm32f411core", "ohos_version": "OpenHarmony 1.0", "device_company": "st", "board": "stm32f411core", "kernel_type": "liteos_m", "kernel_version": "3.0.0", "subsystems": [ { "subsystem": "kernel", "components": [ { "component": "liteos_m", "features":[ "enable_ohos_kernel_liteos_m_fs = false", "enable_ohos_kernel_liteos_m_kal = false" ] } ] } ], "vendor_adapter_dir": "//device/st/stm32f411core", "third_party_dir": "//third_party", "product_adapter_dir": "", "ohos_product_type":"", "ohos_manufacture":"", "ohos_brand":"", "ohos_market_name":"", "ohos_product_series":"", "ohos_product_model":"", "ohos_software_model":"", "ohos_hardware_model":"", "ohos_hardware_profile":"", "ohos_serial":"", "ohos_bootloader_version":"", "ohos_secure_patch_level":"", "ohos_abi_list":"" }
This file is the compilation option configuration of Hongmeng. Please refer to the official documents of Hongmeng
Write in BUILD.gn:
group("gd32f303_qidian") { }
Write in hdf.hcs:
//#include "../../../../device/hisilicon/hispark_taurus/sdk_liteos/config/uart/uart_config.hcs" #include "device_info/device_info.hcs" root { module = "st,stm32_chip"; }
In device_ Write in info.hcs:
root { device_info { match_attr = "hdf_manager"; template host { hostName = ""; priority = 100; template device { template deviceNode { policy = 0; priority = 100; preload = 0; permission = 0664; moduleName = ""; serviceName = ""; deviceMatchAttr = ""; } } } platform :: host { hostName = "platform_host"; priority = 50; device_uart :: device { device0 :: deviceNode { policy = 1; priority = 40; permission = 0644; moduleName = "HDF_PLATFORM_UART"; serviceName = "HDF_PLATFORM_UART_0"; deviceMatchAttr = "hisilicon_hi35xx_uart_0"; } } } } }
3, Move the project files you wrote into Hongmeng source code
Full code is used here
Configurations such as Hongmeng hpm are omitted here (automatic configuration can be achieved through the tools of equipment development 3.0 on Hongmeng's official website)
Download the arm none EABI GCC, gn and ninja tool chains and configure the environment variables
And copy the directory to the corresponding directory of Hongmeng source code
At this time, activate the official python virtual environment of Hongmeng (this step is required if the environment is configured with official tools)
source /opt/Huawei/DevEco-Device-Tool/core/deveco-venv/bin/activate
Enter hb set in the source directory terminal to see the development board compilation options you set
Enter after selection
hb build
You can start compiling
4, Modify error reporting
If not, you will encounter an error
Two mistakes may be due to the carelessness of the staff
Print here_ Err is missing a parameter. I directly supplemented a string. (this problem has now been fixed by the open source community)
There is also an output error, uint32_ Type T prints with% u passed. This may also be a compiler problem
Another thing I guess is that there is a problem with my compilation configuration, but in order to save trouble, I directly blocked a compilation option
Finally, this compilation, the exciting moment has come
You can see the. bin file in the out directory
5, Burn verification
Open STM32 st link utility to burn to the development board
Press the development board rst key
You can see that the led flashes and the transplantation is successful!