单片机
返回首页

MC9S12G128模块化分层化软件架构之十——TaskSchedule任务调度

2021-08-05 来源:eefocus

1 overview

1.1 目的

本文档用于起点开发板的TaskSchedule周期任务调度模块软件说明。


不局限于硬件功能的实现,着眼于实现高质量、优美的软件。

1.2 述

1. 引入功能安全策略,增加任务运行时间和调用周期时间的监控;


2. 引入AUTOSAR timing event方法,周期调用不同任务;


3.实现任务可配置化,配置与底层代码分离.


2 question

1.如何理解offset?


3 软件实现

3.1 CodingRule

具体可在源码的 ..Sourcescode_rules.txt中可见。

3.2 中间件module层修改

3.2.1 增加mdsys_cfg.h

包括中间层module层放的周期,和一些宏开关。

3.2.2 修改mdrti.c

3.2.2.1 增加mdsys_timer计时器。


注意:这里不需要对mdsys_timer限制最大值,加满UINT32_MAX溢出到0,该值用于测量测试checkpoint之间的时间差。

3.2.3 增加mdsys_time.c

把mdsys_poweron_time_ms和mdsys_poweron_time_s移到本文件,增加mdsys_timer变量。


增加mdsys_time_get_since_ms()来获取时间差,单位为ms。

3.2.4 修改mdtask_cfg.c

change log:

3.2.4.1 修改mdtask_config[]任务配置数组


修改结构体配置参数:


周期任务需要的参数:


①执行周期;


②为了避免在同一时刻一个任务中执行的可运行实体(runnable,实际是一个个处理不同任务的函数,他们的运行周期一样),给每一个在同一个task中运行的实体增加偏移量,具体留到后面的优化中实现;


③任务函数指针;


④任务运行时间的最大阈值;


⑤任务的调用周期的最小阈值;


⑥任务的调用周期的最大阈值;


⑦计算平均运行时间和平均调用周期时间的滤波个数;(多少个值的和算平均值)

3.2.4.2 增加mdtask_basic_2ms_period()


这时module中间层的2ms周期任务,一般用于调用实时性要求很高,但任务量又小的任务,如IO采样;

3.2.4.3 增加mdtask_basic_4ms_period()


中检测module层4毫秒周期任务,一般用于调用实时性次于IO采样的任务,如SPI采样。如果AD要求实时性高,也可以放在2毫秒任务中。

3.2.4.4 增加mdtask_basic_5ms_period()


中间层5毫秒周期任务,可用于调用CAN通信处理任务,ADC采样任务;

3.2.4.5 增加mdtask_basic_10ms_period()


中间层module层10毫秒周期任务,可用于调用实时性一般的任务,如诊断任务;

3.2.4.6 增加mdtask_appl_4ms_period()


用于处理应用层实时性要求高的任务,电机控制,(甚至可以增加2毫秒任务处理,要与AD采样周期一致,保证每次处理的是新的数据,此处不使用,不增加,)这里的LED流水灯任务可以改为10毫秒任务;

3.2.4.7 增加mdtask_appl_5ms_period()

3.2.4.8 增加mdtask_appl_10ms_period()

3.2.5 修改mdtask_cfg.h

3.2.5.1 增加任务周期宏定义

3.2.5.2 增加采集配置表中所有周期任务信息结构体


采集的信息包括:


①上一次的采样时间点;


②运行时间runtime最小时间;


③运行时间runtime最大时间;


④运行时间filter_count次平均之后的时间;


⑤周期时间cycle_time最大时间;


⑥周期时间cycle_time最小时间;


⑦周期时间cycle_time平均时间;


⑧运行时间的错误类型;


⑨周期时间的错误类型;

3.2.5.3 增加时间的错误类型枚举

3.2.5.4 增加taskID


如果要增加task,需要在该枚举中增加taskID。

3.2.6 修改mdtask.c

changelog:

3.2.6.1 修改mdtask_init()


该函数可用于任务调度时,计算所有任务的周期数的最小公倍数。


首先,当系统时间计时器(mdrti_1ms_counter)能整除每个任务的周期数时,该任务会被执行。但是mdrti_1ms_counter的最大值应当为任务的周期数的最小公倍数的2n倍或者UINT16_MAX,一般在设置任务周期时最好是1ms, 2ms, 4ms, 5ms, 10ms, 20ms, 50ms, 100ms,1000ms。

3.2.6.2 新增mdtask_calculate_lcm_peiod ()


用于计算所有周期的最小公倍数的2n倍。

3.2.6.3 增加mdtask_report_task_start()


如果使用任务监控功能(MDTASK_MONITOR_TIME == 1u),该函数应该在每个周期任务一开始的地方调用,这样才能监控的运行时间长度和调用周期才能准确。


主要用于监控调用周期的实际时间,第一次的调用该函数和下一次调用该函数的时间差即为该任务的实际调用周期,并检查该任务的调用周期是否在配置范围内。


但是在mdsys_time_get_since_ms()函数中不能实现微秒级的时间参数,所以该功能不能准确检测出任务执行的微秒级的时间,只能检测数毫秒级的时间。

3.2.6.4 增加mdtask_report_task_run()


如果使用任务监控功能(MDTASK_MONITOR_TIME == 1u),该函数应该在每个周期任务最后结束的地方调用,这样才能监控的运行时间长度才能准确。

3.2.6.5 修改mdtask_schedule()


注意:这里一定要用uint16 tick_count =mdtask_get_tick();获取当前的mdrti_1ms_counter,因为这个全局变量是一直在变的,如果在判断task开始是否开始执行时该全局变量增加了,下一个task就会错过本次执行的机会。例如,taskA的周期是5ms,offset是1,taskB的周期是10ms秒,offset是1,此时mdrti_1ms_counter为11。


此时((mdrti_1ms_counter % period_of_taskA) ==offset_of_taskA),所以taskA可以执行,但是taskA的运行时间runtime为2ms,当taskA结束后,mdrti_1ms_counter为13,本来没有执行taskA时,(mdrti_1ms_counter % period_of_taskB) == offset_of_taskB是成立的,但是因为taskA执行时间过长,导致taskB不能执行。而如果使用局部变量获取tick_count= mdtask_get_tick()就会避免由于某一个task执行时间过长导致其他其他task无法执行的问题。

3.2.7 修改mdio.c

去掉mdio_input_sample()中的对周期的判断,因为改为了周期调用mdio_input_sample(),不需要函数内部自己判断。

3.3  common公共文件夹

3.3.1 新建math.c

3.3.1.1 新增calculate_least_common_multiple_u16()

4 基础内容

4.1 缩略语

image.png

4.2    TimingEventactivated runnables

TimingEvent:用于启动RunnableEntity的事件。


TimingEvent用于在RunnableEntity中执行重复动作。简单来说就是每次TimingEvent发生时触发RunnableEntity的执行。


4.3     Autosar: Activation Offset forRunnable Entity

In order to allow optimizations(smooth cpu load, mapping of runnableentitysand BswSchedulableEntitys with different periods in the same task to avoid datasharing, etc), the RTE has to handle the activation offset information from atask shared reference point only for tim trigger RannableEntitys and BswSchedulableEntitys.The maximum period of a task can be calculated automatically as the greatestcommon divisor(GCD) of all runnables period and offset. It is assumed that therunnables worst case execution is less than the GCD. In case of the worst caseexecution is greater than the GCD, the behavior becomes undefined.


为了让CPU负载更加平均分布,为了避免在同一个task中但有不同的周期的runnableentity共享数据,对于那些时间触发的runnableentitys并且共享同一个时间参考点的runnableEntitys,RTE应当处理好激活时偏移量参数。该任务的周期应当为所有runnable周期和偏移量的最大公约数(GCD)。最差情况是runnable执行时间少于最大公约数(GCD)。如果执行时间查过最大公约数,系统表现无法确定。


翻译的很晦涩难懂,不过可以图解不断含义。


例1:


一个task中有3个runnable,每个activation offset定义如下:

image.png

runnable R1, R2和R3都在T1任务中调用,T1的周期为20ms,20ms是3个runnable周期和激活偏移量(activationoffset)的最大公约数。


①参考时间为0ms时,任务T1开始运行,当前没有runnable应当被执行;


②参考时间为20ms时(0和20ms之间任务T1不会被执行),任务T1开始运行,当前的offset为20ms,R1被执行;


③参考时间为40ms时,任务T1开始运行,当前没有runnable应当被执行;


④参考时间为60ms时,任务T1开始运行,当前offset为60ms,R2被执行;


⑤参考时间为80ms时,任务T1开始运行,当前没有runnable应当被执行;


⑥参考时间为100ms时,任务T1开始运行,当前offset为100ms,R2被执行;

例2:


4个runnable在同一个task中被调用,激活偏移量和任务中的调用位置定义如下:

image.png

runnable R1,R2和R3在同一个任务T1中被调用,任务T1的周期为10ms,10ms是4个runnable周期和激活偏移量的最大公约数(GCD)。

5 软件测试及调试

当前配置参数:

5.1 任务调用

例:


当mdtask_old_tick_count不等于mdrti_1ms_counter时,此时tick_count整除mdtask_config[]中mdtask_appl_4ms_period ()任务周期APPL_TASK_4MS_PERIOD,如下图在mdtask_appl_4ms_period ()设置断点,mdrti_1ms_counter为22016,整除4。


5.2 task monitor配置错误

将mdtask_appl_4ms_period最大cycle time阈值设置为3,最小cycle time阈值设置为4,应该是报MdtaskCycletimeError_WrongConfig。

5.3    taskmonitorruntime错误

在mdtask_appl_4ms_period ()中增加mdsys_delay_ms(4u)延时4ms,mdtask_appl_4ms_period ()runtime就会大于4ms,mdtask_config[]中配置mdtask_appl_4ms_period ()最大runtime阈值为2ms,此时应当报MdtaskRuntimeError_OverMaxTime。

5.4 taskmonitorcycletime错误

在mdtask_appl_4ms_period ()中增加mdsys_delay_ms(6u)延时6ms,mdtask_appl_4ms_period ()runtime就会大于6ms,会影响mdtask_appl_4ms_period ()下一个激活点,导致跳过一个周期,会导致时序混乱。mdtask_config[]中配置mdtask_appl_4ms_period ()最大cycletime阈值为5ms,此时应当报MdtaskCycletimeError_OverMaxTime。

6 实物展示

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • 如何构建一个触摸传感器电路

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章