嵌入式软件开发(二)——裸机程序开发

前言

  嵌入式应用软件的开发中裸机程序的开发是一个比较让人“酸爽”的体验,为何要用“酸爽”这个词,且听分解。

一、裸机程序开发的特点

  裸机程序开发很简单,因为没有多任务,可以一个流程跑到黑,入口函数就是main(),所有的工作流程 都可以在main()中依次调用,顺序执行,就像车间流水线那么简单,无需太多逻辑。
  但裸机程序开发又非常麻烦,习惯上位机编程的人遇到估计要口吐芬芳。因为裸机程序简单,所以没有应用 API可以调用,想干什自己实现,如果所选的MCU厂家够良心,可能开发SDK中会携带部分发开lib库供调用,如果遇到大撒 把的MCU厂商,那呵呵,自求多福吧。
  举个最简单的例子,如果想打印一串字符,大家肯定会说用print()啊,对不起还真不见得有,这时候就 需要开发者自己构建打印函数的API了,以串口打印为例:
1)实现串口单字节输出函数uart_send_byte();
2)实现串口多字节输出函数uart_send_ multi_bytes();
3)ascii码转换函数value2ascii();
4)打印函数print();
其调用关系为:
1
2
3
4
print()
-->value2ascii()
-->uart_send_ multi_bytes()
-->uart_send_byte()
  所以,裸机程序的开发简单、自由,让有些开发者可以天马行空不拘一格,但同时也很麻烦,好多事情都需要 自己实现,开发效率低,让一些开发者苦不堪言。也正是因为开放自由,嵌入式裸机程序开发没有标准,代码风格全凭工程师 的编程风格,尤其是在项目交接时,让人岂一个“靠”字了得。
  虽然裸机程序开发如此自由,但如果涉及多人开发时,还是建议统一开发标准,尽量做到分层化、模块化。

二、裸机开发中的伪操作系统思想

  何为伪操作系统思想?其实伪操作系统就是在构建裸机程序架构时借鉴操作系统的思想。
  我们知道裸机程序是没有多任务的,那如果在不上操作系统的情况下是否可以实现裸机程序的多任务?在某些特 定环境下的任务是可以的,我们看一下如下伪码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
mian()
{
while(1)
{
get_taskid();
switch(TASK_ID)
{
case TASK_1:
{
process1();
next_taskid();
break;
}
case TASK_2:
{
process2();
next_taskid();
break;
}
case TASK_3:
{
process3();
next_taskid();
break;
}
.
.
.
default:
{
process_default();
next_taskid();
break;
}
}
}
}
  通过上述伪码,我们构建了一个软件状态机,通过修改TASK_ID的值来改变执行流程,但有人要问,这个可以 执行多任务么?如果配合上中断,这个结构是可以执行多任务的。如果中断处理我们同样按照Linux系统的上、下半部的处理原 则,中断处理函数中只做TASK_ID的状态标记,不做其他任务处理,那这个架构可以理解为不会抢占的多任务架构。
  那可否在上述结构上加上时间片呢?当然可以,这需要借助一个定时中断。
  假设定时中断定时为10毫秒触发一次,同样定时中断处理函数中只做状态标记TASK_ID=TASK_TIMER,下半 部的处理函数为time_process(),那只需要在函数get_taskid();下面加上如下伪码:
1
2
3
4
if(TASK_ID == TASK_TIMER){
time_process();
next_taskid();
}
  这样就实现时间片轮询了么?
  我们知道定时器10毫秒触发一次,所以time_proces()每隔10ms执行一次,那其他流程处理函数共同享有 10ms减去time_proces()执行的时间。
  那time_proces()以外的其他流程执行时间超过10ms怎么办,这个架构下要求一个处理流程不易过长,尽量切 分成最小执行单元,整体放入大流程中。

嵌入式软件开发(二)——裸机程序开发
https://leo-hou.github.io/2022/02/15/嵌入式软件开发(二)——裸机程序开发/
作者
Leo Hou
发布于
2022年2月15日
许可协议