如何移植OpenHarmony 3.0 到星空派开发板上

描述

9 月 30 日,OpenHarmony 3.0 LTS 版本发布。本文将介绍如何移植 OpenHarmony 3.0 到星空派开发板上。

星空派开发板介绍

星空派(GD)开发板是由旗点科技推出的一款 gd32 开发板,板载 GD32F303ZET6 芯片,可直接替代 STM32F103 和 GD32F103 系列。

它支持 WiFi、4G、loRa 等物联通信接口。板载 Flash、eeprom 等,支持 3.2 寸的 TFT-LCD 屏幕。

所有 IO 口均引出,可完整地进行外设开发,包括:JTAG、RTC、I2C、UART、SPI、SDIO、EXMC、DAC、ADC、USB、TFT-LCD 等。

ARM 芯片移植轻量系统基础知识

在做芯片移植工作之前,我们需要掌握一点点基础知识。

①适配 LiteOS-M 轻量系统

GD32F303 系列器件是基于 Arm Cortex-M4 处理器的 32 位通用微控制器。

所以我们使用的是内核是 LiteOS-M,对应的是 OpenHarmony 轻量系统。

事实上,OpenHarmony 已经做好了 Cortex-M4 核相关的通用移植工作,具体代码可以查看文件夹:“kernelliteos_mkernelarcharm”。

可以看到目前已经支持了 cortex-m4 核。所以内核移植工作基本不需要,减少了我们很多工作量,但是我们仍然需要移植 GD32F303 芯片相关的。

②哈佛架构

GD32F303 采用的是哈佛架构,哈佛架构的特点是代码指令和数据分开存储。对于 GD32F303 而言,代码是存放在片内 flash 上,地址是 0x8000000。

数据(也就是代码中用到的各种变量、内存等)是存放在芯片内部内存 RAM 上,地址是 0x20000000,总共 64K,即 0x10000。

③编译结果分析

对于 GD32F303 而言,编译出来的固件一般是 bin 格式、或者 hex 格式。

通常编译最后的结果会产生 4 种不同的内容,有时我们也称为 4 段:

code:即程序代码部分,该内容由所有程序指令组成,也是代码运行的主体,通常是要烧录到 GD32F303 片内 flash 上。

RO-data:只读数据段,例如我们在程序中所定义的全局常量数据和字符串都位于此处。由于这些数据都是只读,不会改变的,那这些只读的全局就没必要放到内存种,可以直接放到 flash 中,可以节省内存。

RW-data:已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。由于内存刚上电后,内存上的数据是未知,所以我们需要事先把这些全局变量、静态变量的初始值先存放到 flash 中,然后上电后,由 CPU 将 flash 中的初始值赋予到内存中的变量中。

ZI-data:未初始化的全局变量或者初始化为0的全局变量,这些变量默认都是 0,我们只需要 CPU 上电后,将这些内存都清零即可。

由上我们可以的出来 2 个结论:

1)我们编译出来的固件要烧录到 GD32F303 的片内 flash,需要由 3 段数据:code、RO-data、RW-data。

2)芯片上电后,GD32F303 需要将 RW-data 的内容复制到内存对应位置,从而保证初始化的全局变量和静态变量的值正确;还要对内存中的 ZI-data 段进行清零操作,最后才能执行 main 函数。

④程序如何启动

对于 ARM Cortex-M 系列的芯片而言,当芯片上电后,ARM 核会将地址为 0x8000000 的数据映射到 0 地址,然后从 0 地址开始读取程序指令。

而 0x8000000 地址是芯片内部 flash 的起始地址。也就是编译生成的固件最终要烧录到的地址。所以我们的固件前面的代码非常重要,它是我们芯片启动后执行的第一条指令。

⑤中断向量表

对于 ARM Cortex-M 系列的芯片而言,0x8000000 地址第一个字节是栈指针,由于栈是从高往下增长的,所以该栈指向芯片最大内存处即可。

接下来从 0x8000000 的第 2 个字节开始是中断向量表,存放着所有中断处理函数指针。

前面 16 个是内核中断,其中第一个中断指针存放的是 Reset_Handler 复位中断处理函数。

芯片一上电、或者复位,都会先从该中断函数开始运行,所以这个函数是我们最重要的,我们需要在该函数中完成 RW-data、ZI-data 数据的操作,同时初始化好芯片时钟、最后进入 main 函数。

移植GD32F303到OpenHarmony 3.0

这里提供移植好的相关代码,下载链接:

https://gitee.com/qidiyun/gd32-f303-for-open-harmony-3.0

①先按官网教程搭建好 Ubuntu 下的开发环境

下载arm交叉编译器:git clone。

https://gitee.com/harylee/gcc-arm-none-eabi-10-2020-q4-major.git

将交叉编译器环境变量 bin 目录配置到 .bashrc 文件中或者配置 device/st/stm32l4r9i_disco/liteos_m/config.gni 文件中 board_toolchain_path 宏为交叉编译器 bin 路径。

②下载上方移植好的代码

 

将 device 文件夹下的 gd 文件夹复制到 OpenHarmony 3.0 代码的 device 文件夹下。

将 vendor 文件夹下的 gd 文件夹复制到 OpenHarmony 3.0 代码的 vendor 文件夹下。

复制后,OpenHarmony 3.0 的 device 文件夹内容

OpenHarmony 3.0 的 vendor 文件夹内容

③编译

进入 OpenHarmony 3.0 源码根目录,输入 hb set 可以看到由 gd32f303_qidian 的编译选项。选择。

HarmonyOS

输入 hb build -f 开始全编译:

HarmonyOS

有看到 [OHOS INFO] gd32f303_qidian build success 表示编译成功。

编译完成后,可以在“outgd32f303_qidiangd32f303_qidian”文件夹下看到编译结果,其中“gd32f303_qidian_ninjia.hex”就是可以直接烧录到开发板的固件。

HarmonyOS

vendor 文件夹

该文件下最重要的文件是“config.json”:

HarmonyOS

内如如下,主要是配置相关组件:

HarmonyOS

device 代码解析:

device 文件夹:该文件夹下是星空派开发板的重要代码部分,其中就有启动文件、main 函数、中断处理等。

HarmonyOS

由于移植内容较长,本文重点介绍启动文件、链接脚本。

①启动文件

启动文件 startup_gd32f30x.s 。最重要的是将 RW-data 的内容复制到内存对应位置,从而保证初始化的全局变量和静态变量的值正确;还要对内存中的 ZI-data 段进行清零操作,最后才能执行 main 函数。

代码都是汇编,参考自 st 和 gd 相关启动文件,重要代码如下:

HarmonyOS

②链接脚本

链接脚本是“gd32f30x_qidian.ld”,用于指定code、RO-data、RW-data、ZI-data 如何分布。

首先指定内存地址为 0x20000000,大小为 64K、片上 flash 地址为:0x8000000,大小为 512K,这里跟芯片相关,需要正确修改,否则可能起不来。

HarmonyOS

这里跟芯片相关,需要正确修改,否则可能起不来。

③固件生成规则

同时链接脚本也指定了固件的生成规则:

HarmonyOS

这里只截取了部分,可以看到生成的固件最开始存放的 isr_vector,这个是中断向量表,在启动文件中定义:

HarmonyOS

接下来就是 text,也就是代码段,还有 rodata,只读数据段。后面还有其它定义,我们下一篇再细节。至此我们的启动文件、链接脚本中比较关键的部分已经说明完。

liteos-m 内核配置

进入“devicegdgd32f303_qidianliteos_m”文件夹,可以看到有这个文件“config.gni”,该文件用于配置 liteos-m 内核。

其中比较重要部分是指定我们的处理器架构和交叉编译工具链,如下:

HarmonyOS

我们使用的交叉编译工具链是 “arm-none-eabi-”。

下面还配置了相关宏定义和 gd 标准库头文件路径,需要大家修改。

HarmonyOS

好了,初步移植要点讲完了,下一篇文章讲 OpenHarmony 内核配置文件、main 函数启动后如何进入鸿蒙轻量内核~

责任编辑:haq

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分