在之前文章 ECU 应用层软件模型如何自动生成代码2 提到了 ECU 应用层软件模型生成代码不需要main_function,这是因为ECU 应用层软件会被底层软件配置好的任务调度。本文来具体了解下到底是怎么回事。
1 ECU应用层软件如何周期性运行?
ECU应用层软件代码(函数)如何被周期性运行,其实现方式如下图示意的这样:
ECU底层软件配置好不同时间周期的任务函数,比如10ms周期的Task_10ms,20ms周期的Task_20ms等。
周期型任务是指在固定的时间间隔内定期执行的任务。例如,1ms任务、10ms任务、100ms任务等,即每个任务的执行周期决定了任务的频率。
首先需要硬件支持。定时器,用于生成周期性的中断,可以设置为在特定的时间间隔内产生中断,当定时器产生中断时,CPU会跳转到预先定义的中断服务例程(ISR),执行相应的任务。具体代码的实现示意如下:
1) 配置定时器。配置定时器的周期,使其在指定的时间间隔内产生中断。
void configureTimer(uint32_t period) {
// 设置定时器周期
Timer_setPeriod(period);
// 启动定时器
Timer_start();
}
2)定义中断服务例程。即在定时器中断发生时,执行相应的任务。
void timerISR(void) {
// 清除定时器中断标志
Timer_clearInterruptFlag();
// 执行周期型任务
execute1msTask();
execute10msTask();
execute100msTask();
}
3)创建周期型任务。定义任务函数:定义每个周期型任务的执行函数。
void execute1msTask(void) {
// 执行1ms周期的任务
}
void execute10msTask(void) {
// 执行10ms周期的任务
}
void execute100msTask(void) {
// 执行100ms周期的任务
}
4)使用RTOS进行任务管理。在RTOS中创建多个任务,每个任务有自己的优先级和执行周期。
void createTasks(void) {
// 创建1ms任务
os_createTask(1, execute1msTask, 1000); // 优先级1,周期1000us
// 创建10ms任务
os_createTask(2, execute10msTask, 10000); // 优先级2,周期10000us
// 创建100ms任务
os_createTask(3, execute100msTask, 100000); // 优先级3,周期100000us
}
这里任务调度策略有几种形式:
优先级调度:RTOS根据任务的优先级进行调度,高优先级的任务会优先执行。 时间片轮转:对于同优先级的任务,可以使用时间片轮转的方式进行调度,确保每个任务都能得到执行机会。 抢占式调度:高优先级的任务可以抢占低优先级任务的执行,确保实时性。
除了上述这些工作,还有几个点需要注意,一是任务执行时间,需要确保每个任务的执行时间远小于其周期,避免任务堆积导致系统崩溃;二是资源竞争,需要处理好任务之间的资源竞争,避免死锁和竞态条件;三是调试和测试,进行充分的调试和测试,确保任务按预期执行,系统稳定可靠。以此来确保系统的实时性和可靠性。
5)代码程序。上面几个部分的代码是单独的,为了更好理解周期型调度如何实现的,下面将这些代码联合起来看如何使用定时器和中断服务例程实现周期型调度,如下:
// 定义周期型任务
void execute1msTask(void) {
// 执行1ms周期的任务
}
void execute10msTask(void) {
// 执行10ms周期的任务
}
void execute100msTask(void) {
// 执行100ms周期的任务
}
// 中断服务例程
void timerISR(void) {
// 清除定时器中断标志
Timer_clearInterruptFlag();
// 执行周期型任务
static uint32_t counter = 0;
counter++;
if (counter % 1 == 0) {
execute1msTask();
}
if (counter % 10 == 0) {
execute10msTask();
}
if (counter % 100 == 0) {
execute100msTask();
}
}
// 配置定时器
void configureTimer(uint32_t period) {
// 设置定时器周期
Timer_setPeriod(period);
// 启动定时器
Timer_start();
}
// 创建任务
void createTasks(void) {
// 创建1ms任务
os_createTask(1, execute1msTask, 1000); // 优先级1,周期1000us
// 创建10ms任务
os_createTask(2, execute10msTask, 10000); // 优先级2,周期10000us
// 创建100ms任务
os_createTask(3, execute100msTask, 100000); // 优先级3,周期100000us
}
int main(void) {
// 初始化定时器
configureTimer(1000); // 1ms周期
// 初始化RTOS
os_init();
// 创建任务
createTasks();
// 启动RTOS调度
os_start();
return 0;
}
汽车研发交流群,有兴趣的朋友请添加群主:prOmiseyes,备注:公司+职务入群。仅限汽车从业人员。