嵌入式软件课程笔记

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 不能保证读取数据的任务能够正确的解释数据
  • 队列,管道,信箱已满对嵌入式软件是一种灾难
  • 通过队列,管道,信箱在任务间传递指针可能会创建共享数据

实时操作系统的基本设计