【STM32】STM32 移植鸿蒙操作系统

这篇具有很好参考价值的文章主要介绍了【STM32】STM32 移植鸿蒙操作系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

随着 OpenHarmony3.1 的正式发布,其功能也在不断完善。OpenHarmony LiteOS-M 内核是面向IoT领域构建的轻量级物联网操作系统内核,具有小体积、低功耗、高性能的特点,其代码结构简单,主要包括内核最小功能集、内核抽象层、可选组件以及工程目录等,分为硬件相关层以及硬件无关层,硬件相关层提供统一的HAL(Hardware Abstraction Layer)接口,提升硬件易适配性,不同编译工具链和芯片架构的组合分类,满足AIoT类型丰富的硬件和编译工具链的拓展。本文主要介绍如何在STM32上移植 OpenHarmony LiteOS-M 内核,及其注意事项。


一、开发环境

硬件:
- STM32F429I-DISC1 开发板
【STM32】STM32 移植鸿蒙操作系统
软件:
- VSCode:用于编辑代码
- STM32CubeMX:用于生成工程
- make、arm-none-eabi-gcc:用于编译工程
- STM32Cubeprogrammer:用于下载工程
- Git:用于获取 OpenHarmony LiteOS-M 内核源码

二、移植内核

1. 操作流程

  1. 拉取仓库代码。
  2. 使用STM32CubeMX在 /target 目录下生成工程。
  3. 修改Makefile文件,工程加入 OpenHarmony LiteOS-M 内核所需的文件。
  4. 添加用户代码以支持printf。添加用户自定义任务。
  5. 编译下载程序

2. 获取源码

  • 进入https://gitee.com/openharmony/kernel_liteos_m,获取Git仓库地址。
https://gitee.com/openharmony/kernel_liteos_m.git

【STM32】STM32 移植鸿蒙操作系统

  • 使用Git Bush,拉取内核源码到本地。
    【STM32】STM32 移植鸿蒙操作系统
  • 创建 /third_party 目录,用于存放第三方依赖文件(STM32 所需的 CMSIS 等),拉取第三方依赖文件。
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

【STM32】STM32 移植鸿蒙操作系统
到这里 OpenHarmony LiteOS-M 内核源码就获取完毕了。

3. 生成工程

  1. 进入/targets 目录,使用 STM32CubeMX 生成工程 STM32F429ZI_Harmony_LiteOS_M
    【STM32】STM32 移植鸿蒙操作系统

  2. 与FreeRTOS类似,由于LiteOS会占用SysTick定时器,因此需要修改HAL库延时的基础时钟,改为其他非SysTick的定时器,避免HAL库延时的定时器和系统运行的定时器冲突。【STM32】STM32 移植鸿蒙操作系统

  3. 配置:下载调试端口SW、串口USART、LED_GPIO、时钟树。
    【STM32】STM32 移植鸿蒙操作系统

  4. 开发环境选择 Makefile
    【STM32】STM32 移植鸿蒙操作系统

  5. Code Generator 中一定要选择 Copy only necessary library files 如果选择所有库文件都添加的话,那么就会生成很多模板文件。由于我们需要在 Makefile 中添加文件,如果目录中有模板文件的话,我们就无法直接使用筛选功能将所有源文件快速添加到工程中了。
    【STM32】STM32 移植鸿蒙操作系统
    至此工程配置已结束,点击 Generate 即可生成工程。

4. 修改工程文件

  1. 使用 VS Code 打开targets下的工程目录,新建liteos_file_path.mk用于将内核源码文件添加到工程Makefile中,该文件相当于C语言中的头文件,主 Makefile 文件可以直接包含该文件。
    【STM32】STM32 移植鸿蒙操作系统
  2. 添加内核源文件目录到 liteos_file_path.mk 中。
# Topdir 顶层目录
LITEOSTOPDIR := ../../
LITEOSTOPDIR := $(realpath $(LITEOSTOPDIR))

# Common 内核源文件及头文件目录
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)

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


# Third party related 第三方依赖文件及头文件目录
C_SOURCES    += \
	$(wildcard 	$(LITEOSTOPDIR)/third_party/bounds_checking_function/src/*.c)\
    $(wildcard $(LITEOSTOPDIR)/kal/cmsis/*.c)\
    $(wildcard $(LITEOSTOPDIR)/kal/posix/src/*.c)

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)/kal/cmsis \
    -I$(LITEOSTOPDIR)/kal/posix/include \
    -I$(LITEOSTOPDIR)/kal/posix/musl_src/internal


# Arch related 
ASM_SOURCES   += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.s)

ASMS_SOURCES  += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.S)

C_SOURCES     += $(wildcard $(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc/*.c)

C_INCLUDES    += -I. \
                 -I$(LITEOSTOPDIR)/arch/include \
                 -I$(LITEOSTOPDIR)/arch/arm/cortex-m4/gcc

CFLAGS        += -nostdinc -nostdlib
ASFLAGS       += -imacros $(LITEOSTOPDIR)/kernel/include/los_config.h -DCLZ=CLZ

# list of ASM .S program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMS_SOURCES)))

$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) $(ASFLAGS) $< -o $@

这里注意:最后一行前面的缩进必须为tab,而不是空格。否则编译会报错。

  1. 修改项目Makefile
  • 在Makefile中包含liteos_file_path.mk
    【STM32】STM32 移植鸿蒙操作系统
  • 增加*.S文件的编译规则
# list of ASM .S program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASMS_SOURCES:.S=.o)))
vpath %.S $(sort $(dir $(ASMS_SOURCES)))

$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) $(ASFLAGS) $< -o $@

【STM32】STM32 移植鸿蒙操作系统

  1. 添加 target_config.h 用于配置裁剪内核。该文件相当于FreeRTOS的FreeRTOSConfig.h
/**@defgroup los_config System configuration items
 * @ingroup kernel
 */

#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 */
  1. 修改链接脚本文件 STM32F407ZGTx_FLASH.ld
  • 添加程序起始地址 _sstack = 0x20000000; /* start of RAM */
  • 添加.text 段的起始地址,这是链接脚本的语法,将当前位置地址赋值给_stext。_stext = .;
    【STM32】STM32 移植鸿蒙操作系统
  1. 修改中断服务函数 Core\Src\stm32f4xx_it.c
  • 添加 LiteOS 头文件
  • 在PendSV异常中进入LiteOS HalPendSV 异常处理函数,进行任务切换操作
  • 在SysTick中断服务函数添加OsTickHandler函数,为系统提供时间基准
#include "los_arch_context.h"
#include "los_tick.h"
/*
.........
*/
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 */
}
/*
.........
*/
void SysTick_Handler(void)
{
    /* USER CODE BEGIN SysTick_IRQn 0 */
    OsTickHandler();
    /* USER CODE END SysTick_IRQn 0 */
    /* USER CODE BEGIN SysTick_IRQn 1 */
    /* USER CODE END SysTick_IRQn 1 */
}
/*
.........
*/
  1. 修改串口映射 Core\Src\main.c
  • 包含头文件#include "stdio.h"
  • 修改串口映射以支持printf
/* USER CODE BEGIN 0 */
#if 1
int _write(int fd, char *ptr, int len)
{
    osStatus_t result;
    osKernelState_t state;

    if (osKernelGetState() == osKernelInactive)
    {
        //系统未启动时不使用DMA
        HAL_UART_Transmit(&huart1, ptr, len, 0xFFFF);
        return len;
    }
    else
    {
        //获取信号,如果上一个DMA传输完成
        //信号就能获取到,没有传输完成任务就挂起
        //等到传输完成再恢复
        result = osSemaphoreAcquire(UART1_TX_DMA_SemaphoreHandle, 0xFFFF);
        if (result == osOK)
        {
            HAL_UART_Transmit_DMA(&huart1, ptr, len); //获取成功,发送数据
            return len;
        }
        else
        {
            return -1; //获取失败
        }
    }
}
#endif

// DMA 传输完成后会调用传输完成回调函数,在该函数中我们释放信号
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == huart1.Instance)
        osSemaphoreRelease(UART1_TX_DMA_SemaphoreHandle);
}
/* USER CODE END 0 */
  1. 添加测试任务 Core\Src\main.c
  • 包含os头文件#include "cmsis_os.h"
  • 增加测试任务
/*
.........
*/
#include "cmsis_os.h"
/*
.........
*/
/* 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,
    .priority = (osPriority_t)osPriorityNormal3,
};
/* USER CODE END PV */
/*
.........
*/
/* USER CODE BEGIN 0 */
/*
.........
*/
void Uart_Task(void *argument)
{
    HAL_GPIO_WritePin(LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET);
    HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET);
    while (1)
    {
        HAL_GPIO_TogglePin(LED_G_GPIO_Port, LED_G_Pin);
        HAL_GPIO_TogglePin(LED_R_GPIO_Port, LED_R_Pin);
        printf("System Runing!!!\r\n");
        osDelay(1000);
    }
}
/* USER CODE END 0 */
/*
.........
*/
int main(){
/*
.........
*/
	/* USER CODE BEGIN 2 */
    osKernelInitialize();
    printf("System Init!\r\n");
    UART1_TX_DMA_SemaphoreHandle = osSemaphoreNew(1, 1, &UART1_TX_DMA_Semaphore_attributes);
    uart_taskHandle = osThreadNew(Uart_Task, NULL, &uart_task_attributes);
    osKernelStart();
    /* USER CODE END 2 */
/*
.........
*/
}

5. 编译下载

  1. 使用make命令编译工程,这里的-j12表示使用多线程编译,可以提高速度,12表示电脑核心数。
make -j12

【STM32】STM32 移植鸿蒙操作系统
2. 使用STM32Cubeprogrammer下载位于/build中的固件STM32F429ZI_Harmony_LiteOS_M.hex
【STM32】STM32 移植鸿蒙操作系统
3. 观察到LED交替闪烁,串口助手打印出了调试信息。

  • LED 交替闪烁
    【STM32】STM32 移植鸿蒙操作系统

  • 串口输出信息
    【STM32】STM32 移植鸿蒙操作系统


总结

总的来说,移植的难点还是在于对 Makefile 相关工具链的理解与应用。由于有CMSIS_OS的封装,轻度使用时,与FreeRTOS感受相差不大。对新手来说使用FreeRTOS进行入门还是不错的选择,建议基本了解 FreeRTOS 之后再深入学习 LiteOS-M 并掌握二者之间的差别。文章来源地址https://www.toymoban.com/news/detail-490599.html

到了这里,关于【STM32】STM32 移植鸿蒙操作系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • STM32基于HAL库和STM32CubeMX的实时操作系统FreeRtOS开发

    STM32基于HAL库和STM32CubeMX的实时操作系统FreeRtOS开发

    1、FreeRTOS RTOS是一类操作系统,µC/OS,FreeRTOS,RTX,RT-Thread 等这些都是RTOS 类的操作系统 FreeRTOS 是众多RTOS 类操作系统中的一种,FreeRTOS 十分的小巧,可以在资源有限的微控制器中运行,FreeRTOS 也不仅仅局限于在微控制器中使用。就单从文件数量上来看FreeRTOS 要比µC/OS 少得多

    2024年02月21日
    浏览(9)
  • 简单介绍STM32上的FreeRTOS实时操作系统

    FreeRTOS是一款广泛使用的开源实时操作系统(RTOS),它为嵌入式系统提供了可靠的任务调度和并发管理。在嵌入式领域中,STM32微控制器广受欢迎,并且与FreeRTOS的结合使用可以提供强大的功能和灵活性。在本篇博客中,我们将深入探究STM32上的FreeRTOS,并了解其核心概念、任

    2024年02月16日
    浏览(9)
  • STM32初学者入门FreeRTOS操作系统,多任务实时系统

    STM32初学者入门FreeRTOS操作系统,多任务实时系统

            FreeRTOS(Free Real-Time Operating System)是一个开源的嵌入式实时操作系统,它专门设计用于在资源有限的嵌入式系统中运行。FreeRTOS提供了一些用于任务管理、调度、同步和通信的功能,使开发者能够轻松地创建可靠的嵌入式系统。 以下是FreeRTOS的一些特点和功能: 轻量

    2024年02月11日
    浏览(12)
  • STM32操作系统FreeRTOS学习——基于hal库

    STM32操作系统FreeRTOS学习——基于hal库

    目录 一、基础概念 1、FreeRTOS 2、单片机编程的系统概念 a、裸机系统,包括轮询系统(不包括中断)和前后台系统(中断为前台,轮询为后台) b、多任务系统 3、FreeRTOS编程风格 a、数据类型 b、变量名的定义 c、函数名 d、宏定义 二、Cubemx创建工程 1、创建任务 2、创建队列

    2024年02月10日
    浏览(18)
  • 使用STM32CubeMX生成ThreadX实时操作系统工程模板

    使用STM32CubeMX生成ThreadX实时操作系统工程模板

    文章发布于博客园,主页:https://www.cnblogs.com/-fcy-/。转载请注明出处! 由于需要在stm32上使用USB Host CDC-ECM,连接EC20发送数据到服务器,接触到了ThreadX实时操作系统。 在调研过程中,发现stm32官方USB库内只有Device ECM类,无法作为host连接网卡; 电脑上经常使用的tinyusb,对st

    2024年02月04日
    浏览(6)
  • STM32简单的四则运算计算器,不需要操作系统

    STM32简单的四则运算计算器,不需要操作系统

    能实现简单的四则运算,加减乘除,不需要操作系统,五个按键加上一个LCD屏幕就可以解决。 1.按键初始化  因为设置的是上拉输入,所以是接地。 2.按键处理函数 3.主函数 KEY2按键。按下去之后标志位flag就会发生变化,当确定flag变成1的时候在按下KEY0和KEY1时,x,y的值就是

    2024年02月11日
    浏览(7)
  • STM32嵌入式系统:将数据保存到SD卡的操作

    STM32嵌入式系统:将数据保存到SD卡的操作 嵌入式系统在现代科技中扮演着重要角色,而STM32单片机是一种常用的嵌入式系统解决方案。本文将介绍如何使用STM32单片机将采集到的数据以TXT文件的格式保存到SD卡中,并且能够方便地读取这些本地数据。 硬件准备 为了实现数据保

    2024年02月01日
    浏览(22)
  • 基于stm32单片机和rt-thread操作系统的智能灯

    基于stm32单片机和rt-thread操作系统的智能灯

    目    录 一、 总体概况 二、 各部分介绍 2.1  STM32F4开发板 2.2  光敏模块 2.3  麦克风模块 2.4  超声波模块 三、 RT-Thread介绍 四、 开发过程 五、 未来设想 六、 开发心得 总体概况 本次测试技术与信号处理课程作业,我利用了stm32单片机和rt-thread实时操作系统进行实践。

    2023年04月16日
    浏览(11)
  • LWIP——无操作系统移植

    LWIP——无操作系统移植

    目录 移植说明 LwIP前期准备  以太网DMA描述符 LwIP移植流程 添加网卡驱动程序 添加LwIP源文件  移植头文件 网卡驱动编写 移植总结  LwIP的移植可以分为两大类:第一类是只移植内核核心,此时用户应用程序编写只能基于RaW/CallBack API进行;第二类是移植内核核心和上层API函数

    2024年02月12日
    浏览(8)
  • LwIP带操作系统的移植

    LwIP带操作系统的移植

    目录 LwIP移植前期准备 LwIP移植流程 修改lwipopts.h 修改lwip_comm.c文件 修改ethernetif.c/h文件 修改ethernetif_input函数 修改ethernet.c文件 添加应用程序 LwIP是支持操作系统的,在操作系统的支持下我们可以使用LwIP提供的另外两种API编程接口编程。没有操作系统的时候,我们只能使用R

    2024年02月07日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包