上电后DJYOS如何从第一步跑到熟悉的main函数里

      不知有多少搞嵌入式软件程序猿都是从main函数开始自己的第一行代码。遥想当年,第一次编写嵌入式软件代码还是在IAR的开发环境下写的,当时按照傻瓜式说明从安装开发IAR,配置开发环境到建立工程。还记得IAR自动生成了一个main.c文件,并且该文件中自动生成了voidmain();函数,只需在main函数中编写自己的代码,编译,烧录,调试,系统会自动从main函数的第一行开始运行,看到流水灯跑起来时的兴奋之情依然历历在目。很长一段时间均想当然的认为程序理所当然的应该从main函数开始运行啊。哎,现在想想真是soyoung so naïve啊~~~殊不知上电后从第一行代码到main函数第一行代码之间隔了十万八千里啊。有幸接触到DJYOS,那鄙人就在这里班门弄斧,谈谈DJYOS是怎么走完这十万八千里的吧,如有不当之处,请轻拍~~~

废话少说,从DJYOS官方提供的MCB1700工程为例。上电后CPU从启动地址处取出第一条指令开始运行(关于启动方式在这里就不展开了),MCB1700工程是将中断向量表放在启动地址处(这个在lds文件中指定,想想,貌似很多都是从中断向量表开始的)。

可以看出,上电之后首先给主栈指针赋值(msp_top也是在lds中指定的),接着就调用Init_Cpu函数。在Init_Cpu函数中初始化栈指针、时钟初始化等等,在这部分可能根据不同CPU需要初始化存储器、映射存储器、cache、mmu等。完成了这些,就可以加载代码了,将代码搬到运行地址去。

不得不说DJYOS加载代码蛮有特色的,它分为两个步骤,在正式加载之前,多了个预加载(Load_Preload),这么做据说是为了实现安全钩子,即某些紧急代码先于操作系统执行。想想工业控制领域,这个功能确实还蛮有用的,毕竟不同于消费电子产品,手机开机,来个十多秒没关系,可工业控制领域,恐怕有些还是吃不消的。废话少说,继续看代码~~~紧急代码包括critical.c以及中断相关的代码,在Load_Preload函数中将紧急代码搬到执行区之后,调用了Pre_Start函数,在该函数中依次初始化了准静态内存分配、异常组件以及中断模块(也就是操作系统加载之前就可以使用中断来处理一些紧急事情了)。接着就开始运行critical函数了,这个函数放在user目录下,用户可以根据实际需要在这里添加需要先于操作系统运行的代码。目前MCB1700源码默认保留了加载工程中喂狗相关的代码(DJYOS看门狗组件也是蛮NB的,以后再聊了)。搞完了这些了,就可以正式加载了,调用loader函数。加载过程无非就是搬代码了,将代码及数据从加载地址搬到执行地址中去,这些在lds文件中指定(lds文件还是值得好好琢磨的)。

搬完代码就可以启动系统了(在Sys_Start函数中实现),在Sys_Start函数中初始化了系统事件链表、资源树、锁、内存等等神马玩意,然后调用Sys_ModuleInit函数,在这个函数里依次初始化各个组件,如果因为内存,flash不够用不想使用某个组件,直接在Sys_ModuleInit函数中将该组件加载函数注释掉就可以,相当easy啊~~~在Sys_ModuleInit函数最后注册了“mainfunction”事件并且弹出了该事件。

接下来终于开始开始启动OS啦,在__Djy_StartOs函数中,先初始化了系统tick,然后从就绪事件链表中选出了一个事件开始运行,在__asm_start_thread初始化了事件虚拟机(也就是该线程对应的栈了),然后就直接跳转到djy_main函数第一行开始运行啦,终于到熟悉的main函数了,尼玛,慢慢长路,一把辛酸泪啊~~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值