openharmony移植3.1版本系统到stm32(代码片段)

Top嵌入式 Top嵌入式     2022-12-06     799

关键词:

文章目录

【OpenHarmony】STM32F407 移植 3.1版本系统

一、前言

最近 OpenHarmony 3.1 已正式发布,标准系统(LiteOS-A)基础能力增强,小型系统(LiteOS-M)基本没啥变化,趋于稳定,我之前写过一篇移植 LiteOS 移植到 STM32 的文章,当时的 LiteOS 版本还没有归入到 OpenHarmony,有些特性没有支持

移植文章链接:【OpenHarmony】VSCode下移植 LiteOS-M 到STM32

为了弥补这个缺陷,移植最新的 LiteOS-M 到 MCU 上,使用最新的系统特性,我又研究了一下 OpenHarmony 移植到 MCU 的过程,之前移植失败有些细节没有注意到,后面研究后发现其实整体框架还是很清晰的, 顺便将OpenHarmony 移植到 MCU 的过程分享给大家,相关教程和代码放在我的 Gitee 和 Github 仓库

开发环境使用 VSCode + GCC +OpenOCD 开发,环境配置可以看前一篇文章:

博客链接:VSCode 搭建 STM32 开发环境

移植编译的方式使用的 Makefile 进行编译构建,没有使用官方推荐的 najia 进行构建,官方对于的 najia 的构建方式的描写的挺详细,也是主推的方法,有兴趣的可以自行去了解,我个人偏向于使用 Make 方式

二、开发环境

硬件平台

软件环境

VSCode、STM32CubeMX、Git工具

技术基础

  • 会使用 STM32CubeMX 配置生成 Makefile 工程
  • 会使用 Git
  • 懂一点 makefile 语法

三、获取源码、添加第三方依赖

上 Gitee 拉取代码,选 3.1 发布的版本:链接

拉到本地的文件夹:

git clone https://gitee.com/openharmony/kernel_liteos_m.git

拉取:

然后在 git 进入到 kernel_liteos_m 里面,新建 third_party 目录并进入

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 Makefile 工程

用 STM32CubeMX 新建一个 STM32F407ZGT6 的工程,导出到 liteos 目录下面的 targets 目录,STM32CubeMX 导出 Makefile 工程详细教程可以百度自行寻找,我简单的写一下,在 CubeMX 工程中我们配置好时钟树:

开启串口以及串口 DMA,方便进行调试:

修改 HAL 库延时的基础时钟,改为其他非 SysTick 的定时器,避免 HAL 库延时的定时器和系统运行的定时器冲突:

配置工程选项:

将生成的工程放到源码 targets 目录下:

target 下提供了几个基于芯来risc-v和sifive risc-v架构的芯片示例,我们不用管他

五、配置编译文件

在 VSCode 打开源码目录:

在我们的 Target 下的工程目录中新建一个 My_Path.mk 文件,用于辅助进行编译构建,在该文件内依次添加如下的 Makefile 代码

定位顶层目录

# 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

个人的文件和路径,位置预留:

# My file
C_SOURCES    += 

C_INCLUDES   += 

架构相关文件,选择 M4 相关架构文件的目录

# 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 $@

然后在工程的 Makefile 中如下位置调用我们的 makefile 文件:

六、添加工程配置文件

我们要添加一个工程配置文件,用于配置和裁剪内核,在 Targets 下的工程目录内,添加一个 target_config.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 */

这些配置文件的含义和功能,主要是对着 los_config.h 来进行修改的,后面我会进行分析!

配置文件完成后对代码进行编译,编译使用的 task.json 来快速配置的,配置环境那一节我有提到过,修改路径如下:

然后编译,编译完成如下:

七、修改链接脚本

在链接脚本 targets\\OpenHarmony_Demo\\STM32F407ZGTx_FLASH.ld 中定义栈的起始地址为 0x20000000:

/* Lowest address of the user mode stack */
_sstack = 0x20000000;    /* start of RAM */

添加 .text 段的起始地址,这是链接脚本的语法,将当前位置地址赋值给 _stext:

   _stext = .;

具体位置如下:

八、修改中断服务函数

虽然编译完成了,但就算下载了程序,也无法正常运行,因为之前的配置代码写的

/*=============================================================================
                                        Hardware interrupt module configuration
=============================================================================*/
#define LOSCFG_PLATFORM_HWI 0
#define LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT 0
#define LOSCFG_PLATFORM_HWI_LIMIT 128

不使用硬件中断接管,所以我们需要在系统运行的两个重要中断服务函数添加内核的接口,让STM32的中断管理可以跳转到内核的处理函数:

进入 targets\\OpenHarmony_Demo\\Core\\Src\\stm32f4xx_it.c 文件,在下面两个函数添加如下函数:

在 PendSV 异常中进入 LiteOS HalPendSV 异常处理函数,进行任务切换操作

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 */

在 SysTick 中断服务函数添加 OsTickHandler 函数,为系统提供时间基准

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 */

添加个头文件包含:

#include "los_arch_context.h"
#include "los_tick.h"

九、修改串口映射

之前我们有开启串口,所以我们再把 printf 的底层映射到串口上,供内核调用,便于调试,在 main.c 中包含头文件 include "stdio.h",然后添加底层接口,底层接口未启动时使用阻塞方式发生数据,系统启动后则使用 DMA 传输,通过信号量防止 DMA 使用冲突:

#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);

十、添加测试任务

然后在main函数中添加一个测试任务和一个信号量:

变量定义:

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,
;

初始化:

    osKernelInitialize();
    UART1_TX_DMA_SemaphoreHandle = osSemaphoreNew(1, 1, &UART1_TX_DMA_Semaphore_attributes);
    uart_taskHandle = osThreadNew(Uart_Task, NULL, &uart_task_attributes);
    osKernelStart();

任务实体:

void Uart_Task(void *argument);
void Uart_Task(void *argument)

    while (1)
    
        printf("System Runing!!!\\r\\n");
        osDelay(1000);
    

编译代码:

十一、实验现象

串口打印系统正常运行信息

十二、工程源码

示例工程的核心代码放到 Gitee 上了,需要自取

Gitee:https://gitee.com/JeckXu666/openharmony-for-mcu

移植qt5.3.1到arm

...也有好长的时间了。当中提供了非常多的特性,所以这次移植的是qt5的最新版本号5.3.1。第一步准备好源代码包,这里须要qt的源代码包。和tslib包。tslib我使用的是开发板提供的包。设置交叉编 查看详情

openharmony移植:如何适配utils子系统之kv存储部件(代码片段)

摘要:本文介绍移植开发板时如何适配utils子系统之KV存储部件,并介绍相关的运行机制原理。本文分享自华为云社区《OpenHarmony移植案例与原理-utils子系统之KV存储部件》,作者:zhushy。Utils子系统是OpenHarmony的公... 查看详情

openharmony移植:buildlite配置目录全梳理(代码片段)

本文分享自华为云社区《移植案例与原理-buildlite配置目录全梳理》,作者:zhushy。命令行工具hb(HarmonyOS|OpenHarmonyBuild编译构建系统的缩写)都很熟悉了。这是一个基于gn和ninja的构建系统,以支持OpenHarmony组件化开发为... 查看详情

[rk3399-evb]rk3399-evb编译与移植yocto-3.1(dunfell)系统(代码片段)

1UbuntuPC准备环境100G磁盘可用空间Git版本要1.8.3.1以上,tar版本要1.28以上,Python3版本要3.5.0以上,gcc版本要5.0以上执行以下命令安装依赖包:sudoapt-getinstall-ygawkwgetgit-corediffstatunziptexinfogcc-multilib\\build-ess 查看详情

openharmony富设备移植指南从postmarketos获取移植资源

开篇引言安卓设备的引导需要boot.img镜像,其中含有内核镜像,设备树,boot配置文件,initrd.img根文件系统镜像,开发板因为是开发用途,系统引导基本没有限制,而成品安卓手机往往有各种限制,我们需要通过刷入postmarketOS进... 查看详情

openharmony内核学习[1]--单独编译openharmony标准系统内核(代码片段)

内核是操作系统的核心,学习掌握OpenHarmony内核对于开发人员至关重要。笔者整理学习OpenHarmony标准系统内核笔记如下:阅读本文大约需要15分钟。(目录)OpenHarmony标准系统内核OpenHarmony标准系统类设备(参考内存≥128MiB),OpenHarmo... 查看详情

基于openharmony的储物精灵

基于openharmony的储物精灵一.项目简介1.产品描述基于openharmony的智能柜物管理系统,可用于不同场景的环境下通过终端检索到物品的出入库信息与通过鸿蒙特性来赋能储物精灵。储物精灵NFC版:这是一个智慧储物系统,终端可以... 查看详情

linux系统移植:原厂kernel移植到开发板(代码片段)

文章目录Linux系统移植:原厂Kernel移植到开发板一、获取原厂内核并编译二、内核启动测试三、添加自己板子文件3.1板子配置文件3.2板子设备树3.3编译四、重要配置修改4.1主频修改4.2EMMC驱动修改4.3网络驱动修改4.4保存修改后... 查看详情

基础能力分布式能力系统应用…openharmony3.1release版本带来全方位升级

 作为开发者,不管你是否接触跟开源相关的事情,在过去的2021年应该能感受到开源“发烫”的热度。2022年,开源大潮继续滚滚向前。2022年3月30日,开放原子开源基金会发布了具有“里程碑式”的OpenHarmony3.1Releas... 查看详情

鸿蒙openharmony-hi3861l移植教程(代码片段)

HI3861有两款单片机 一个是HI3861,一个是HI3861L,HI3861L是HI3861的低功耗版本HI3861芯片上的丝印是:HI3861RNLV100HI3861L芯片上的丝印是:HI3861LRNLV100所以大家在选择模块的时候一定要看清楚自己选择的是哪一款,HI3861... 查看详情

openharmony移植案例与原理:如何适配服务启动引导部件bootstrap_lite(代码片段)

摘要:本文介绍移植开发板时如何适配服务启动引导部件bootstrap_lite,并介绍相关的运行机制原理。本文分享自华为云社区《OpenHarmony移植案例与原理-startup子系统之bootstrap_lite服务启动引导部件(1)》,作者&#... 查看详情

ohoslts3.0移植到raspberrypi4b(代码片段)

:::hljs-centerOHOSLTS3.0移植到RaspberryPi4Bliangkz:::1.简介  《沉浸式剖析OpenHarmony源代码》一书没有涉及系统移植方面的内容,因此在交了书稿到出版社之后,我就开始考虑系统移植方面的事情。在了解一些情况后综合考量,我决... 查看详情

如何在dayu200上安装浏览器-基于openharmony3.1release版本

前言:终于!OpenHarmony有自己的浏览器应用了!可以查看视频演示:先看下效果:打开某宝:可以扫码登录:安装教程:1.DAYU200升级最新的3.1Release版本固件升级教程:DAYU200升级OpenHarmony系统࿰... 查看详情

openharmony移植案例:buildlite源码分析之hb命令__entry__.py(代码片段)

摘要:本文介绍了buildlite轻量级编译构建系统hb命令的源码,主要分析了_\\entry__.py文件。本文分享自华为云社区《移植案例与原理-buildlite源码分析之hb命令__entry__.py》,作者:zhushy。hb命令可以通过pythonpip包管理... 查看详情

openharmony应用开发技巧-如何安装serviceextensionability

概述文档环境开发环境:Windows11DevEcoStudio版本:DevEcoStudio3.1Beta1(3.1.0.200)SDK版本:3.2.10.7(OpenHarmony3.2Beta5FullSDK)应用模型:Stage开发板型号:DAYU200系统版本:OpenHarmony3.2Beta5示例工程:​​ServiceExtAbility的创建与使用(OpenHarmony3.2... 查看详情

开源鸿蒙系统能打电话了!openharmony离手机os越来越近

参考技术A电子发烧友网报道(文/黄晶晶)最近OpenHarmony社区的专家连志安发表了一个视频。视频是说使用润和DAYU200开发套件,搭载OpenHarmony3.1Release版本,能够在拨号界面打出电话,还表示这个新版本越来越像手机了。自华为手... 查看详情

基于openharmony/harmonyos操作系统的arkui框架——harmony原生开发

一.基于OpenHarmony/HarmonyOS操作系统的ArkUI框架——Harmony原生开发开发需要的IDE:1.1什么是ArkUI框架?ArkUI是一套构建分布式应用界面的声明式UI开发框架。它使用极简的UI信息语法、丰富的UI组件、以及实时界面预览工具,帮助您提... 查看详情

openharmony轻量系统开发初始openharmony

本文简单介绍OpenHarmony、轻量系统、小型系统、标准系统的差异,以及相关的官方资料和文档适合群体:第一次接触OpenHarmony、或者想要对OpenHarmony有一个全面的认知的。后续将给大家陆续分享轻量系统开发相关内容目录&#... 查看详情