良许Linux教程网 干货合集 一些嵌入式软件设计经验

一些嵌入式软件设计经验

1、什么是框架?

程序框架类似于文件大纲或模板,它为编写程序提供了结构和指导。就像写文章一样,如果没有大纲或模板,编写程序将会更加困难。

2、为什么需要框架?

框架的存在可以节省时间并减少错误。因为对于某一类型的程序而言,它们的代码结构和逻辑通常是相似的,包含大量相似或共同的部分。我们可以将这些共同的部分提取出来形成一个固定的程序框架,然后在开发同一类型的新程序时可以重用这个框架。

这样做可以大大提高开发效率,并且由于这个框架是经过广大用户使用和维护的,所以使用它可以使代码逻辑更加可靠,减少出错的可能性。

3、嵌入式系统的组成

嵌入式控制系统基本上由普通任务和中断任务组成。

  • 普通任务指的是对时间响应要求不高,或者说是周期性执行的任务。
  • 中断任务指对时间响应要求高,必须立即处理的任务。

4、常见的框架

4.1、轮询无中断

说明:所有的任务都是按照顺序执行,为了减少整个系统的响应时间有两种方法:

  1. 任务中不要使用等待式的延时函数;
  2. 任务无法一次执行完的情况下应该将任务分解成若干个小任务每次执行一个小任务循环直到任务完成;

上述两种方法都会消耗内存,本来局部变量可以解决的事,现在只能用静态或者全局变量来处理。

image-20240110191618892
image-20240110191618892

优点:程序执行流程简单清晰;

缺点:对于系统修改功能非常不方便,同时如果任务数量增加的话会影响整个系统的响应时间,就会显得系统卡顿;

伪代码实现:

int main(void)
{
    while(1)
    {
        doSomething_1(); //任务1
        doSomething_2(); //任务2
        doSomething_3(); //任务3
        /*其他各种任务*/
    }
    return 0;
}
4.2、只有中断

说明:在“只有中断“的系统中,主函数main的循环中是不做任何操作的。

优点:可以实时响应异常的任务(事件)

缺点:中断资源有限,当任务过多时会响应不及时。

伪代码实现:

int main(void)
{
    while(1)
    {
        ;
    }
}
 
/*中断服务函数1*/
void ISR1_IRQHandler(void)
{
    doSomething_1();
}
 
/*中断服务函数2*/
void ISR2_IRQHandler(void)
{
    doSomething_2();
}
4.3、只有中断框架的变种

说明:采用状态机的机制来执行任务。中断函数中设置状态机的状态,而main函数主循环中根据不同的状态值执行不同的任务。这个其实不属于真正只有中断的形式。

int main(void)
{
    while(1)
    {
        if(flag_1)
        {
            doSomething_1();
        }
        if(flag_2)
        {
            doSomething_2();
        }
        if(flag_3)
        {
            doSomething_3();
        }
        /*其他各种任务*/
    }
    return 0;
}
 
/*********中断服务函数1************/
void ISR1_IRQHandler(void)
{
    flag_1 = ~flag_1;
}
 
/*********中断服务函数2************/
void ISR2_IRQHandler(void)
{
    flag_2 = ~flag_2;
}
 
/*********中断服务函数3************/
void ISR3_IRQHandler(void)
{
    flag_3 = ~flag_3;
}
4.4、轮询有中断

说明:将一些周期性的任务放置在main函数中的主循环中执行:

image-20240110191615309
image-20240110191615309

优点:合理的利用资源,将常规任务与紧急任务分开来了。

缺点:程序结构与逻辑比较复杂,在任务分配以及协作之间需要花费很大精力。

伪代码实现:

int main(void)
{
    while(1)
    {
        if(flag_1)
        {
            doSomething_1();
        }
        if(flag_2)
        {
            doSomething_2();
        }
        if(flag_3)
        {
            doSomething_3();
        }
        /*其他各种任务*/
    }
    return 0;
}
 
/*********定时器中断服务函数************/
void ISR1_IRQHandler(void)
{
    
}
4.5、轮询有中断——虚拟定时器
image-20240110191612386
image-20240110191612386

说明:利用不同的”虚拟定时器“的定时时间来调用不同任务,当定时器的定时时间到时则执行回调函数或者调用任务函数。

这对于一些周期性运行的任务是非常适合的,同时中断可以应对外界的突发事件。这样实时性也可以得到保障,但要注意不要使用等待式延时。一般虚拟定时器的时基为1ms。

优点:任务的时间间隔可以相对精确的控制,同时由于中断使用整个系统的实时性也很不错。

缺点:任务的执行时间无法掌控,当定时任务执行时间过长时会影响到虚拟定时器的定时精度。

虚拟定时器实现代码:

https://codeload.github.com/0x1abin/MultiTimer/zip/master

4.6、非抢占式实时操作系统
image-20240110191609202
image-20240110191609202

说明:任务之间没有优先级之分,每个任务都是依次执行。但是任务的执行时间是由操作系统严格控制的。即使任务没有执行完,当时间片时间达到时任务便会被挂起。

优点:不用再处心积虑的减少任务中的延时,我们只需要将精力放置在业务逻辑上。

缺点:任务之间是平级的,这就会导致有些任务无法得到紧急处理。

伪代码实现:

https://blog.csdn.net/twx11213030422/article/details/104637273

4.7、抢占式实时操作系统

说明:每个任务之间是一个“死循环”同时任务都有一个优先级。高优先级的任务可以打断低优先级的任务,这个就类似于中断一样。所以整个系统的实时性就非常好,同时每个任务都还受时间片的控制也就是说它们的执行时间是可以预测的。它也支持中断可以响应紧急的事件。

image-20240110191606282
image-20240110191606282

优点:实时响应,工程师只需要将精力放置在业务逻辑的实现上

缺点:需要移植且对单片机硬件资源有一定要求;使用比较复杂。

常用的抢占式实时操作系统:Keil RTX、FreeRTOS、uCosII/III等等。

4.8、回调函数

什么是回调函数?

答:函数指针作为函数的形参,然后函数的调用通过此函数指针来实现。

回调函数中注册与回调是什么?

答:注册其实就是使用一个全局的函数指针,然后给此函数指针赋值(将我们自定义的函数名称赋值给它)。然后在中断或者其他地方通过此全局的函数指针来调用我们原先自定义的函数且这个自定义的函数我们也叫回调函数。

image-20240110191603150
image-20240110191603150

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部