0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

传统编程结构的局限性,使用“前后台方式”进行编程

h1654155971.7688 来源:未知 作者:李倩 2018-05-25 09:07 次阅读

1 传统编程结构的局限性

当不使用RTOS时,嵌入式软件通常采用两种传统的编程结构进行编程,一种叫“前后台结构”或者叫“超级循环结构”,本质上是事件触发的编程方式,另一种叫时间触发的编程方式,Michael J.Pont的“基于时间触发的编程模式”即属于此。

在实际工作中,当系统稍微复杂时,会发现这两种方式都有一定局限性,下面以一个实际产品设计中遇到的问题为例来说明。

在设计一个用于配电柜的壁装式智能配电仪表时,CPU的程序设计需完成以下任务:

(1)每半秒对前显示屏的显示数据进行一次刷行。

(2)每0.1秒对DI/DO进行一次刷新。

(3)每0.2秒对键盘进行一次扫描。

(4)每半秒对测量数据进行一次重新采集和计算。

(5)异步串行口与上位机使用Modbus通信,速率最高19200bps。

(6)CPU通过IIC总线与时钟芯片和EEprom通信。

(7)CPU通过SPI总线与LED数码管及采集芯片通信。

(8)CPU要对所采集的6路信号进行FFT变换。

(9)当系统掉电时,CPU要能快速响应以把当前的电度底数写入EEprom中。

上述任务中,任务(5)和任务(9)是强实时性的,如果对串口的收发事件得不到及时响应,接收时会导致字节丢失,发送时会导致字节间时间间隔太大造成接收方的Modbus帧定界错误,对系统掉电事件如果不能及时响应会造成EEprom的写入失败。其它任务只要在指定的周期内能得到执行就行,但是任务(8)比较特殊,使用通常的8位CPU进行6种信号的FFT变换,哪怕每种信号只做128点的FFT,运算一次也要好几秒。下面来看用传统编程结构实现上述设计时遇到的困扰。

1.1 使用“前后台方式”进行编程

使用“前后台方式”进行编程时,为保证任务(5)的及时性,使用了UART中断,当UART完成一个字节的收发后产生中断,在中断程序中将接收到的字符保存在接收缓冲区或从发送缓冲区取下一个待发字符装入UART进行发送,对Modbus协议的处理可以单独用一个任务在中断外处理,这保证了中断程序的简短。为保证任务(9)响应的及时性,也必须为它安排一个中断。因为当系统掉电时,系统只有不到10ms的过渡时间,系统如果不能在这个时间内完成相关的操作,系统电压将跌落至有效电压以下而丧失工作能力。

安排好了后台的中断任务后再来看看前台的任务如何完成。这里遇到的最大的挑战是对任务(8)的处理,因为任务(8)需要的执行时间太长了,简单的把它当成一个任务处理将影响系统对其它任务的响应,在超级循环中的代码结构如下:

while(1)

{

任务(1);

任务(2);

………

任务(8);

}

由于任务(8)执行一次要几秒钟的时间,整个超级循环执行一次至少大于任务(8)需要的时间,也就是说这个超级循环循环一次要几秒钟时间,将满足不了各任务响应时间的要求。

要解决这个问题,只有把任务(8)拆分成很多个子任务,将每个子任务的耗时压缩到10个毫秒左右,并定义好各子任务完成后的状态,在超级大循环中每次根据状态只执行一个子任务,程序结构如下

while(1)

{

任务(1);

任务(2);

………

Switch (子任务状态)

{

case 子任务状态1:

子任务1;

break;

case 子任务状态2:

子任务2;

break;

…………

case 子任务状态n:

子任务n;

break;

}

}

这样,就需要把一个耗时几秒的FFT运算任务拆分成几百个耗时10ms左右的子任务,这显然是不可接受的。

除此之外,超级大循环结构隐含地一个缺点就是随着任务的增加,循环体的执行时间是线性增加的,在实际设计中即使没有象任务(8)那样的高耗时任务,当系统功能增加时要保证系统响应的及时性也是一个不小的挑战。

1.1 使用“时间触发编程模式”进行编程

“时间触发编程模式”的核心是建立一个基于时间触发的合作式的任务调度器,在系统中尽量减少事件触发(减少中断的使用),系统通过任务调度器完成各任务的调度执行,下面是“时间触发编程模式”的典型程序结构:

/*--------------------主函数-----------------------*/

Void main(void)

{

SCH_Init();//设置调度器

SCH_Add_Task(任务函数名,任务调度延迟,任务调度周期);//将任务加入调度器的任务队列

SCH_Start();//刷新任务队列

while(1)

{

SCH_Dispatch_Tasks(); //执行任务调度器

}

}

/*-------------------定时中断函数---------------------*/

Void SCH_Update(void) interrupt

{

//刷新任务队列

}

系统中每个任务都定义了优先级、任务循环周期和任务延迟时间,系统时器中断程序SCH_Update()按设定的节拍对任务队列进行刷新,在超级大循环中只执行任务调度器SCH_Dispatch_Tasks(),根据任务队列的状态安排任务的执行。

这种编程结构避免了超级大循环结构循环时间随代码量的增加而线性增加的问题,但是,由于任务是不可剥夺的,一旦任务启动执行,任务调度器只有在当前任务完成后才有机会执行,这就要求每个任务占用CPU的时间不能太长,否则将影响整个系统的响应速度。所以,FFT运算在这种编程模式下还是必须进行有效的拆分,否则就必须提高CPU的档次或使用可剥夺型的抢先式RTOS,这势必造成系统成本的增加。那么有没有更好的解决办法呢?

下面的编程结构对“时间触发编程模式”进行了改进,使之在不提高硬件成本的情况下,使编程人员更直观地定义任务,减少任务特性对系统程序结构的冲击,使程序结构简单明了并提高系统的实时响应速度。

2 对“时间触发编程模式”的改进

根据多年嵌入式系统编程的经验,通常嵌入系统的任务可以划分成3种类型:

(1)及时型任务;

(2)周期型任务;

(3)背景型任务;

及时型任务的特点:这类任务是事件触发型的,一旦事件发生,系统必须在限定的时间内进行响应,对这类任务,最自然的方法就是使用中断来完成,即定义成“前后台方式”中的后台任务。

周期型任务的特点:这类任务是时间触发式周期型的,系统必须保证在指定的周期内执行任务,“时间触发编程模式”可以很好地满足这类任务的需求。

背景型任务的特点:这类任务是非实时型的,实时性不是非常重要,系统在运行过程中可随时中断这类任务以便执行前两类任务,系统只要能充分利用资源尽最大可能快速完成这类任务即可,这类任务最适合定义成“前后台方式”中的前台任务。

根据以上任务分类,对“时间触发编程模式”的改进可概括成以下需求:

(1)任务分3类,1类任务优先级最高,3类任务优先级最低;

(2)高优先级的任务可中断低优先级任务的执行,同级的任务之间不可相互剥夺。

(3)实际设计中为提高系统的可预测性,应尽量减少1类任务的数量及1类任务的执行时间。

(4)为降低系统资源的占用,系统不给任务划分单独的堆栈空间。

以上改进的本质是设计一个3优先级的简单的任务调度机制,高优先级的任务可中断低优先级的任务,同优先级的任务之间不能相互剥夺,该调度机制不为每个单独的任务保存任务上下文和单独的堆栈,这样可以减少该编程模式对系统资源的需求。

可剥夺式RTOS中的一个高优先级任务中断一个低优先级的任务时,会保存好低优先级任务的上下文并把该低优先级任务的局部变量保存在本任务单独的堆栈中,如果系统不给任务分配单独的堆栈,如何保证高优先级任务退出后低优先级任务执行环境的恢复呢?

对这个问题,可以借鉴中断的处理机制用以下办法予以解决:

(1)在系统中设计一个定时中断函数,该函数的功能就是执行周期性任务的调度,该定时中断在所有中断中优先级最低;

(2)在系统中设计另一个定时中断函数,该函数的功能是刷新周期型任务的任务管理队列,为任务调度提供支持,本定时中断函数的优先级在系统中次低;

(3)周期型任务就是一个函数,该函数入口的第一个操作是开中断(问:这个中断指的是触发及时性任务的中断,那么在周期性任务外,是开还是关?如果是开,),允许任务执行期间被中断以便响应及时型任务。

(4)背景型任务就是在主函数超级循环中执行的代码,该代码可随时被及时型和周期型任务中断,当系统没有及时型任务和周期型任务时才循环执行背景型任务的代码。

通过以上措施,“改进型时间触发编程模式”的程序结构如下:

/*--------------------主函数-----------------------*/

Void main(void)

{

SCH_Init();//设置调度器

SCH_Add_Task(任务函数名,任务调度延迟,任务调度周期);//将任务加入调度器的任务队列

SCH_Start();//刷新任务队列

while(1)

{

背景型任务1;

………

背景型任务n;

}

}

/*-------------------次低优先级定时中断函数---------------------*/

Void SCH_Update(void) interrupt

{

//刷新任务队列

}

/*-------------------最低优先级的定时中断函数---------------------*/

Void SCH_Dispatch_Tasks(void) interrupt

{

//调度周期型任务

}

/*-------------------周期型任务典型结构---------------------*/

Void SCH_Cycle_Task1(void)

{

//开中断 /*此函数中可以靠中断触发来执行及时性任务*/

//执行任务

return;//任务返回

}

结 语

使用“改进型时间触发编程模式”进行小型嵌入式系统编程,就像使用RTOS进行编程一样,设计者规划好任务后,就可以专心于每个任务的设计,任务对处理器时间的占用可以由系统统一管理,减少任务之间的耦合,使产品的程序设计和改动都变得简洁清楚。使用该编程模式很好地解决了壁装式智能配电仪表所面临的复杂的设计问题,证明该方法简单有效。

目前该设计模式仅仅设计了任务调度器,任务间的变量传递还需要使用全局变量,如果能加入信号量和消息机制,那么该模式将更加完善,会使低成本的小型嵌入式系统的编程更加方便和清晰。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式系统
    +关注

    关注

    40

    文章

    3427

    浏览量

    128213
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10437

    浏览量

    206527
  • 编程
    +关注

    关注

    88

    文章

    3439

    浏览量

    92377

原文标题:换个角度来嵌入式编程 对事件和时间触发的改进

文章出处:【微信号:weixin21ic,微信公众号:21ic电子网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    34063的局限性

    由34063构成的开关电源虽然价格便宜、应用广泛,但它的局限性也是显而易见的。主要有以下几点:(1)效率偏低。对于降压应用,效率一般只有70%左右,输出电压低时效率更低。这就使它不能用在某些对功耗
    发表于 06-12 10:41

    FPGA的优势与局限性

    。减少板级走线,有效降低布局布线难度。当然了,在很多情况下,FPGA不是万能的。FPGA技术也存在着一些固有的局限性。从以下这些方面看,选择FPGA技术来实现产品的开发设计有时并不是明智的决定。●在某些
    发表于 12-20 10:07

    无线网络有什么局限性

    以无线方式发送数据的方法有很多。从遥控无钥匙进入(RKE)和车库开门装置(GDO)等简单命令和控制方案到WLAN,您有很多种选择。本文主要探讨各种可用的无线网络选项和必须在应用过程中解决的局限性,旨在为设计师提供一些选择工业应用的无线网络时所需的实用信息。
    发表于 08-23 06:13

    MySQL优化之查询性能优化之查询优化器的局限性与提示

    MySQL优化三:查询性能优化之查询优化器的局限性与提示
    发表于 06-02 06:34

    超声波液位计的局限性及安装要求

      超声波液位计的局限性  距离测量、密闭容器内液位检测、障碍物检测、透明物体检测、汽车防撞系统、医疗影像技术等等领域,都是超声波传感器大施拳脚的场景。而作为非接触测量的超声波液位计,由于具有安装
    发表于 06-19 11:49

    运算放大器的精度局限性是什么

    日益普遍。本文将介绍运算放大器的精度局限性,以及如何选择为数不多的有可能达到 1 ppm 精度的运算放大器。另外,我们还将介绍一些针对现有运算放大器局限性的应用改善。
    发表于 03-11 06:10

    贴片机转塔式结构的优缺点是什么?有什么局限性

    贴片机转塔式结构的优缺点是什么贴片机转塔式结构局限性有哪些?
    发表于 04-25 06:12

    基于FPGA的神经网络的性能评估及局限性

    FPGA实现神经网络关键问题分析基于FPGA的ANN实现方法基于FPGA的神经网络的性能评估及局限性
    发表于 04-30 06:58

    STM32编程方式在线编程

    、SPI等)下载程序或应用数据到存储器中STM32允许用户在应用程序中烧录FLASH中的内容局限性:使用前需要有bootloader被以ICP方式烧录进FLASH中前置知识:FLASH结构块名称块基地址大小主存储器扇区00x08
    发表于 08-19 06:11

    平台ASIC架构突破传统ASIC设计局限性

    平台ASIC架构突破传统ASIC设计局限性 采用先进半导体工艺,结构化ASIC平台可以提供更多经预定义、预验证和预扩散的金属层,并支持各种存储器接口,能简化接口设计
    发表于 12-27 13:33 1166次阅读
    平台ASIC架构突破<b class='flag-5'>传统</b>ASIC设计<b class='flag-5'>局限性</b>

    如何通过Atmel Studio 6进行统编程

    如何通过Atmel Studio 6进行统编程
    的头像 发表于 07-04 09:50 2739次阅读

    WSN中LEACH协议局限性的分析与改进

    WSN中LEACH协议局限性的分析与改进(电源技术答案)-WSN中LEACH协议局限性的分析与改进               
    发表于 09-15 11:12 3次下载
    WSN中LEACH协议<b class='flag-5'>局限性</b>的分析与改进

    ES0260_STM32F328C8单片机的局限性

    ES0260_STM32F328C8单片机的局限性
    发表于 11-23 20:39 1次下载
    ES0260_STM32F328C8单片机的<b class='flag-5'>局限性</b>

    ES0251_STM32L063x8单片机的局限性

    ES0251_STM32L063x8单片机的局限性
    发表于 11-23 20:39 1次下载
    ES0251_STM32L063x8单片机的<b class='flag-5'>局限性</b>

    千兆光模块存在哪些局限性

    千兆光模块,作为网络设备中常用的一个配件,在实际应用中,由于其存在一定的局限性,可能会对网络传输速度、信号接收等方面产生影响。本文将就千兆光模块的局限性进行探讨,并提供一些可能的解决方案。
    的头像 发表于 10-16 12:10 340次阅读