移植鸿蒙系统到STM32L476RG_NUCLEO开发板的建议

https://gitee.com/walker2048/hmos_iot
移植鸿蒙的建议:
步骤一步来 , 别想一口吃成胖子 , 给自己定计划 。多看源码以及编译日志 , 多想 , 多动手 。源码既是文档 , 别想着百度或者谷歌能帮你直接解决问题 。修改完代码后 , 完成了小部分功能的 , 也要及时提交GIT中 。
1  , 首先肯定是创建厂商文件夹
首先按移植LiteOS教程里的说明 , 使用CubeMX工具生成makefile格式的项目(包含stm32l4xx标准hal库和ll库实现代码及makefile) , 并把项目文件复制到供应商/ st / stm32l4xx目录里 。这就是2020- 11-06日dbbaf5f这个提交所包含的内容 。然后在该目录执行命令make> build.log , 这样一是测试代码是否能正常编译 , 二是可以把stm官方提供的makefile实际执行指令信息存储到build.log文件里 , 方便以后修改gn系统的编译配置时做参考用

移植鸿蒙系统到STM32L476RG_NUCLEO开发板的建议
文章插图
2 , 第二步配置编译环境及组件
根据以前的阅读makefile和嵌入式开发经验 , 应该先确定编译工具链 。不同的硬件架构 , 需要的编译工具链并不一样 , 哪怕是一个最简单的helloworld , 也没办法实现同一个bin文件 , 能在不同架构的硬件上直接运行 。目前鸿蒙2.0配置好的两套编译工具(主要是gcc) , 并不能完成stm32的编译工作 。
打开build / lite / toolchain /目录 , 复制gcc.gni文件的内容到arm_none_eabi_gcc.gni , 进入第14行的ohos_kernel_type(内核类型)修改成liteos_m , 进入15行的ohos_build_compiler_
prefix设置为正确的gcc工具设置为arm-none-eabi 。其他内容暂时没动 , 然后根据其他开发板的设置 , 又复制了几遍配置 , 例如
构建/精简版/配置/板/ stm32l476rg_nucleo.gni
等等配置先抄一遍hi3861的 , 期间各种尝试使用编译命令蟒蛇build.py stm32l476rg_nucleo , 直到不再提示找不到stm32l476rg_nucleo目标板 , 进入下一个确认工具链环节为止 。这一环节中 , 比较重要的应该是build / lite / product / stm32l476rg_nucleo.json文件 , 该文件定义了目标板名称 , 编译工具链 , 内核等重要信息 。
当编译命令提示arm-none-eabi-gcc不是OHOS的编译器时 , 我也没有楞一会儿 。翻了生成目录下的各种配置也找不到对应的配置时 , 我就放弃找配置了 。直接在VScode中插入搜索不包含OHOS编译器的大部分文件 , 最终在build / lite / config中 。py的124行和158行找到了对应的判断语句 , 并增加了arm-none-eabi-gcc的判断语句 。
随后测试编译时 , 又发现编译脚本会针对ohos_kernel_type进行各种优化和设置 。没办法 , 就只能搜索ohos_kernel_type ==“ liteos_riscv” , 指向文件一一修改 。涉及到的文件也很多 , 详细请看gitee上的变更记录 。
最终各组件的配置判断语句没问题了 , 能顺利进入到编译状态 , 出现类似以下信息了
===开始构建===
做完了 648毫秒内从41个文件中取得39个目标
忍者:进入目录`/ mnt / out / stm32l476rg_nucleo'
[112分之1]交叉编译OBJ / APPLICA TI组件/样品/ WiFi的IOT /应用/ demolink / helloworld.o
【移植鸿蒙系统到STM32L476RG_NUCLEO开发板的建议】 [2/112] AR libs / libdemolink.a
因此能出现[1/112]之类的 , 恭喜你 , 编译配置已经完成了80%了 。期间还删除并容易出现问题的组件 , 例如wifi功能等等一堆组件
3 , 调整头文件配置
为了减少以后找文件找目录头疼 , 我在二进制目录新建了一个包括文件夹 , 链接疑似应该从厂商目录中提取出来的头文件放在该目录的hal目录下 , 从而难以解决的头文件错误组件去掉 , 不编译对应组件 。最终编译命令都顺利通过了 , 只差最后一步生成小精灵和箱文件了 。
4 , 根据原厂生成文件和修改编译调整细节
重头戏的英文此文件生成/精简版/工具链/ arm_none_eabi_gcc.gni , 查看原厂makefile的build.log文件 , 可以裁剪编译过程为.c文件=> 。o文件 , 然后.S文件=> 。o文件 , 然后将所有的.o文件以及STM32L476RGTx_FLASH.ld文件一起链接成elf文件 。最后再由elf文件生成bin和hex 。
多次尝试修改后 , 最终调整为以下内容
template(“ gcc_toolchain”){
工具链(target_name){
断言(已定义(invoker.cc) , “ gcc工具链必须指定一个“ cc ”值“)
断言(已定义(invoker.cxx) , “ gcc工具链必须指定一个“ cxx ”值“)
断言(已定义(invoker.ld) , “ gcc工具链必须指定一个“ ld ”值“)
断言(已定义(invoker.ar) , “ gcc工具链必须指定一个“ ar ”值“)
断言(定义(invoker.as) , ““工具链必须指定一个” as “值”)
断言(定义(invoker.cp) , ““工具链必须指定一个“ cp ”值”)
ar = invoker.ar
as =调用者
cc = invoker.cc
cxx = invoker.cxx
ld = invoker.ld
cp = invoker.cp
need_strip =否
if(defined(invoker.strip)){
剥离= invoker.strip
need_strip = true
}
如果(defined(invoker.extra_
ldflags)&&invoker.extra_ldflags!=“”){
extra_ldflags =“”
}其他{
extra_ldflags =“”
}
工具(“ cc”){
命令=“ $ cc -c {{cflags}} {{defines}} {{include_dirs}} {{cflags_c}}” +
#“ -MMD -MP -MF'{{source_out_dir}} / {{source_name_part}} 。d'” +
#“ -Wa , -a , -ad , -alms = {{source_out_dir}} / {{source_name_part}} 。lst” +
“ {{source}} -o {{output}}”
depsformat =“ gcc”
description =“跨编译器{{output}}”
输出= [
“ {{source_out_dir}} / {{source_name_part}} 。o” , 
]
}
工具(“ cxx”){
depfile =“ {{output}} 。d”
命令=“ $ cxx -c {{cflags}} {{defines}} {{include_dirs}} {{cflags_c}}” +
#“ -MMD -MP -MF'{{source_out_dir}} / {{source_name_part}} 。d'” +
#“ -Wa , -a , -ad , -alms = {{source_out_dir}} / {{source_name_part}} 。lst” +
“ {{source}} -o {{output}}”
depsformat =“ gcc”
description =“ CXX {{output}}”
输出= [
“ {{source_out_dir}} / {{target_output_name}} 。{{source_name_part}} 。o” , 
]
}
工具(“ asm”){
depfile =“ {{output}} 。d”
command =“ $ as -c {{cflags}} {{defines}} {{include_dirs}} {{asmflags}} {{source}} {{cflags_c}}” +
“ -o {{输出}}”
depsformat =“ gcc”
description =“跨编译器{{output}}”
输出= [
“ {{source_out_dir}} / {{source_name_part}} 。o”
]
}
工具(“链接”){
outfile =“ {{output_dir}} / {{target_output_name}} {{output_extension}}”
rspfile =“ {{output}} 。rsp”
rspfile_content =“ {{inputs}}”
命令=“ $ ar cr {{输出}} @ ” $ rspfile “”
description =“ AR {{output}}”
输出= [
超越
]
default_output_dir =“ {{root_out_dir}} / libs”
default_output_extension =“ .a”
output_prefix =“ lib”
}
工具(“链接”){
outfile =“ {{output_dir}} / bin / {{target_output_name}} 。elf”
rspfile =“ $ outfile.rsp”
command =“ $ ld {{inputs}} {{ldflags}} $ extra_ldflags -specs = nano.specs” +
#在供应商路径中设置ld文件补丁
“ -lc -lm -lnosys {{libs}} -Wl , -Map = {{target_output_name}} 。map , -cref” +
“ -Wl , -gc-sections -o $ outfile”
if(need_strip){
命令+ =“ && $ cp -O二进制-S $ outfile {{output_dir}} / bin / {{target_output_name}} 。bin”
}
description =“ LINK $ outfile”
default_output_dir =“ {{root_out_dir}}”
rspfile_content =“ {{inputs}}”
输出= [
超越
]
}
工具(“邮票”){
如果(host_os ==“ win”){
命令=“ cmd / c类型nul> ” {{输出}} “”
}其他{
命令=“ / usr / bin / touch {{输出}}”
}
description =“ STAMP {{output}}”
}
工具(“复制”){
命令=“ $ cp -O二进制-S {{源}} {{输出}} 。bin && echo $ strip”
description =“ COPY {{源}} {{输出}}”
}
}
同时在stm32l4xx / Src / BUILD.gn文件中添加ldflags , 实现ld文件在厂商文件内部设置 。
ldflags = [
“ -T” , 
“ ../../vendor/st/stm32l4xx/STM32L476RGTx_FLASH.ld”
]
最终 , 顺利生成了一个elf文件 , bin文件以及hex文件 。其实gn配置相对来说 , 命令行的提示 , 以及配置的定位性都是相当不错的 。还是建议大家多动手 , 多看 , 多想 。
责任编辑:xj
原文标题:移植鸿蒙系统到STM32L476RG_NUCLEO开发板的一点小经验
文章出处:【微信公众号:HarmonyOS社区】欢迎添加关注!文章转载请注明出处 。
.dfma {position: relative;width: 1000px;margin: 0 auto;}.dfma a::after {position: absolute;left: 0;bottom: 0;width: 30px;line-height: 1.4;text-align: center;background-color: rgba(0, 0, 0, .5);color: #fff;font-size: 12px;content: "广告";}.dfma img {display: block;}
移植鸿蒙系统到STM32L476RG_NUCLEO开发板的建议
文章插图

    推荐阅读