完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
我最近在持续关注XR806这颗IC,也确实打算用这颗IC做产品,奈何自身才疏学浅,对XR806 鸿蒙OS下的启动过程不甚了解,也理不清头绪,有没有对着代码详细解读XR806在鸿蒙LiteOS下的启动过程的资料或文章呢,,
还请各位大师指点迷津!!!!!! |
|
相关推荐
1个回答
|
|
相关文章还没找到,但大致流程如下:
1、首先是芯片启动,芯片启动后内部会有一段引导程序,最终引导到main函数,也就是device/xradio/xr806/xr_skylark/project/common/startup/gcc/retarget.c这个文件下的 int __wrap_main(void)->void main_task_start(void)->static void main_task(void *arg)。 2、liteOS的启动代码在kernel/liteos_m/kernel/arch/arm/cortex-m33/gcc/los_dispatch.S,是使用汇编写的,大致流程和其他RTOS差不多,先是吧堆栈指针从MSP切换到PSP,然后把空闲任务的地址给到PC,然后跳转PC,就启动了liteos。 3、接下来是Harmony的启动。Harmony的启动是调用void OHOS_SystemInit(void)这个函数,位置是在base/startup/bootstrap_lite/services/source/system_init.c。要详细理解Harmony的启动需要花点时间看看源码。如果熟悉LD脚本的话会比较好理解。 OHOS_SystemInit()的第一行代码是MODULE_INIT(bsp);,bsp在806中没有用到,806_OpenHarmony主要用了MODULE_INIT(run)。 MODULE_INIT(name)是个宏,本体是MODULE_CALL(name, 0); MODULE_CALL(name, 0)也是一个宏,本体是 #define MODULE_CALL(name, step) do { InitCall *initcall = (InitCall *)(MODULE_BEGIN(name, step)); //这是个宏 InitCall *initend = (InitCall *)(MODULE_END(name, step)); //这也是个宏 for (; initcall < initend; initcall++) { (*initcall)(); } } while (0) 上面的for循环很好理解,就是从 initcall运行到initend,也就是从MODULE_BEGIN运行到MODULE_END。他们的宏展开后如下: #define MODULE_BEGIN(name, step) ({ extern InitCall _zinitcall##name##_start; InitCall *initCall = &_zinitcall##name##_start; (initCall); }) #define MODULE_END(name, step) ({ extern InitCall _zinitcall##name##_end; InitCall *initCall = &_zinitcall##name##_end; (initCall); }) 前面说了这是用run替换掉name,就变成了 InitCall *initCall = &__zinitcall_run_start; InitCall *initCall = &__zinitcall_run_end; 这两个符号都在ld链接脚本(device/xradio/xr806/xr_skylark/project/linker_script/gcc/appos.ld)中定义好的。 接下来的疑问是怎么把代码放在__ zinitcall_run_start和__zinitcall_run_end这两个地址的中间,用到的函数其实就是SYS_RUN(),其实这个也不是函数,只是一个宏。一层层展开如下: #define SYS_RUN(func) LAYER_INITCALL_DEF(func, run, "run") #define LAYER_INITCALL_DEF(func, layer, clayer) LAYER_INITCALL(func, layer, clayer, 2) #define LAYER_INITCALL(func, layer, clayer, priority) static const InitCall USED_ATTR _zinitcall##layer##_##func attribute((section(".zinitcall." clayer #priority ".init"))) = func 其实SYS_RUN()就是把括号内的字符拼接成一个地址,然后存放在zinitcall.run2.init这个位置。 例如SYS_RUN(LEDMain),意思就是设定一个函数地址为__ zinitcall _ run _ LEDMain,然后位段位于zinitcall.run2.init。 ld文件里面有一段的代码: __zinitcall_run_start = .; KEEP ((.zinitcall.run0.init)) KEEP ((.zinitcall.run1.init)) KEEP ((.zinitcall.run2.init)) KEEP ((.zinitcall.run3.init)) KEEP (*(.zinitcall.run4.init)) __zinitcall_run_end = .; 可以看到Harmony把任务启动的优先级分为5个等级,SYS_RUN默认是等级2,如果任务有启动优先级,那么久可以用SYS_RUN_PRI(func, priority)调整初始化顺序。 对于做产品时如果有外设需要初始化的,就可以使用SYS_BSP。通过这种机制,Harmony实现了裁剪功能。 |
|
|
|
只有小组成员才能发言,加入小组>>
639 浏览 0 评论
630 浏览 0 评论
757 浏览 0 评论
全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS系统定制开发
1433 浏览 0 评论
全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS编译开发说明
804 浏览 0 评论
全志V85x硬件设计大赛作品精选第二期,快来Pick你心目中的最佳方案
92444浏览 3评论
2846浏览 1评论
5119浏览 1评论
Yuzuki Lizard 全志V851S开发板 –移植 QT5.12.9教程
16402浏览 1评论
关于全志T113开发板接7寸LCD屏幕显示异常问题的解决方案
1137浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 05:57 , Processed in 0.513824 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号