嵌入式软件课程笔记
bootloader 的作用
参考资料:https://blog.csdn.net/zxnsirius/article/details/52166558
https://blog.csdn.net/qq_35769944/article/details/81979980
BootLoader就是在操作系统运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统做好准备。对于 Bootloader 的启动过程又分为两个阶段 stage1 和 stage2。
stage1 全部由汇编编写,它的主要工作是(1)初始化硬件设备、(2)为加载 Bootlodader 的 stage2 准备 RAM 空间(3)拷贝 Bootloader 的 stage2 到 RAM 空间(4)设置好堆栈段为 stager2 的 C 语言环境做准备。
stage2 全部由 C 语言编写,其的主要工作是(1)初始化本阶段要使用到的硬件设备(2)将内核映像和根文件系统映像从 flash 上读到 RAM (3)调用内核
通俗解释
其实 bootloader 主要的必须的作用只有一个:就是把操作系统映像文件拷贝到 RAM 中去,然后跳转到它的入口处去执行。
而操作系统文件的来源,可以是 flash,sd card,PC(可以通过网络,USB,甚至串口传输)等等,所谓的 EBOOT,UBOOT,其实就是表明了系统文件是通过 Ethernet 或者 USB 从 PC 传输过去的。
当然,为了实现这个功能(以及其它附加功能),我们必须对硬件做一些必要的初始化,这个也是必须的(废话!)。除了这个必须的,现在的 bootloader 还常常会加入以下功能:
1.将操作系统映像文件写入 FLASH/硬盘等:读取过来的操作系统文件,除了可以拷贝到 RAM 中直接运行,还可以烧录到 FLASH,或者写入硬盘永久保存,这样下次就可以直接从本机来读取操作系统映像。
2.硬件诊断:如同 PC 的 BIOS 一样,检测硬件是否正常功能。
3.显示一个 LOGO,因为拷贝操作系统文件和启动操作系统需要时间,所以产品化的设备,一般需要在这段时间显示一个 LOGO。
操作系统服务
- 消息队列
- 信箱
- 管道
消息队列
细节:
- 绝大多是 RTOS 都需要一个特定函数来初始化队列
- 大多数 RTOS 允许建立多个队列
- 如果要写入的队列已经满了,则 RTOS 返还一个错误信息,表明写操作失败;或者阻塞该任务,直到队列释放空间
- 若想要读的队列为空,则返回错误码
- 写入数据量问题:向队列写 char,int 或者自己定义的 struct 怎么办?不能都写一个对应的方法来处理:C++泛型,重载;c 语言 void 指针,用宏包装函数(不好调试)
指针和队列:
将数据放在缓冲区,用指针指向这个缓冲区,把指针放在队列中
信箱
和队列的区别:信箱的数据有优先级,按优先级先后取出
管道
- 一些 rtos 允许写入管道的消息长度不限
- 面向字节的
- 一些 rtos 使用标准的 fread 和 fwrite 来读出,写入管道
- 由于面向字节,如何实现两个任务之间的数据传输量符合期望?制定通信协议。
printf 就是用的管道
缺陷
- 许多 rtos 不限制任务可以读写给定的队列,管道,信箱的权利
- rtos 不能保证读取数据的任务能够正确的解释数据
- 队列,管道,信箱已满对嵌入式软件是一种灾难
- 通过队列,管道,信箱在任务间传递指针可能会创建共享数据