完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
转rtx操作系统
通过前面的几个章节,我们基本已经完成了RTX所有功能的讲解,本章节为大家介绍一种使用独立看门狗监测任务执行状态的方法,借此为大家提供一种RTX系统在软件或者硬件死机时,如何保证系统复位的思路。 本章教程配套的例子含Cortex-M3内核的STM32F103和Cortex-M4内核的STM32F407。 20.1 独立看门狗检测多任务的执行状态 20.2 实验例程说明 20.3 总结 20.1 独立看门狗监测任务的实现思路 20.1.1 什么是独立看门狗 假设有一只饥饿的狗正在看守一座房子,而有人要闯入。如果这个强盗的同谋以2分钟的时间间隔不停的向看门狗扔肉。那么这只狗将忙于吃肉而忽视保卫工作,因此将不会犬叫。然而,如果同谋扔完了肉或者由于其它原因忘了喂肉,狗将开始犬叫,从而惊动邻居,房屋主人或者警察。 嵌入式化的独立看门狗定时器遵循同样的基本方法。非常简单,如果每隔一定间隔不刷新看门狗定时器,它将溢出。在大多数情况下,看门狗定时器的溢出将复位系统。即使经过仔细规划和设计,嵌入式系统也有可能由于出乎预料的问题而死机,看门狗定时器就是用来处理类似情况的。看门狗可用于从这种状态恢复。 教程使用的STM32F103和STM32F407都自带独立看门狗,使用也比较简单,用户初始化好看门狗,并设置好看门狗溢出时间即可,剩下就是在溢出时间的范围内及时喂狗。 下面就提供一种利用独立看门狗监测多任务的执行状态的思路。 |
|
相关推荐
|
|
20.1.2 多任务监测实现思路
为了保证RTX的所有用户任务都在正常的执行,我们通过独立看门的形式来监测,一旦发现有某个任务长时间没有执行,看门狗就会将系统复位。 运行条件: u 创建5个用户任务Task1,Task2,Task3,Task4和Task5。其中Task5的优先级最高,然后依次是Task4,Task3,Task2,Task1。 u 任务Task1到Task4定期发事件标志给任务Task5,表示任务运行正常。 实现思路: u 喂狗程序放在最高优先级的任务Task5里面,其它的4个任务都定期的向最高优先级任务发送事件标志,只有四个任务都发来了事件标志才进行喂狗。 u 看门狗的复位时间设置为多少合适呢,这个要根据四个任务Task1到Task4的最大发送事件标志间隔来确定。假设测试发现,最大的发送事件标志时间间隔是由Task4产生的,间隔是6s,我们可以再设置一些时间容限,把看门的复位时间设置为10s,也就是说,如果四个任务Task1到Task4在10s内给任务Task5发送事件标志,让Task5执行喂狗操作,那么系统将复位。 u 推荐在最高优先级任务里面实现喂狗,这样才可以保证其它低优先级任务发来了事件标志后,Task5可以及时的喂狗,如果放在一个低优先级的任务里面,那么当所有的任务任务都已经发送任务运行正常的事件标志,但是此任务在执行喂狗程序前被其它高优先级的任务抢占了造成不能及时喂狗,从而造成系统复位,这种误判断会造成系统不能够正常工作。 按照上面的实现思路,我们在开发板上面实战演练下。 |
|
|
|
|
|
20.2 实验例程说明
20.2.1 STM32F103开发板实验 配套例子: V4-420_RTX实验_独立看门狗监测任务的执行状态 实验目的: 1. 学习独立看门狗监测任务的执行状态 实验内容: 1.K1按键按下,串口打印。 2.看门狗监测任务执行状态说明: (1). 设置看门狗复位时间是10s,如果10s内不喂狗系统复位。 (2). 使用事件标志组,在最高优先级任务中等待其它所有用户任务发来的事件标志,如果所有任务都发来了事件标志,那么就执行喂狗程序,如果有一个任务10s内没有发来事件标志,那么系统会被复位。 (3). 简单的说就是为了检测任务的执行转态,我们设置每个任务10s内必须发一次事件标志以此来表示任务在执行。如果10s内有一个任务没有发来消息,系统会被复位。 (4). 等待事件标志的任务: xResult= os_evt_wait_and (TASK_BIT_ALL, usMaxBlockTime); 其它四个发送事件标志的任务: os_evt_set(TASK_BIT_0, HandleTaskStart); os_evt_set(TASK_BIT_1, HandleTaskStart); os_evt_set(TASK_BIT_2, HandleTaskStart); os_evt_set(TASK_BIT_3, HandleTaskStart); 3.K2按键按下后将任务AppTaskTaskUserIF延迟20s后执行,从而实现看门狗复位。 4.各个任务实现的功能如下: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里用作LED闪烁。 AppTaskScan任务 :按键扫描。 AppTaskStart任务 :启动任务,也是最高优先级任务,等待其它任务发送来的事件标志。 |
|
|
|
|
|
RTX配置:
RTX配置向导详情如下: u Task Configuration l Number of concurrent running tasks 允许创建5个任务,实际创建了如下5个任务: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里用作LED闪烁。 AppTaskScan任务 :按键扫描。 AppTaskStart任务 :启动任务,也是最高优先级任务,等待其它任务发送来的事件标志。 l Number of tasks with user-provided stack 创建的5个任务都是采用自定义堆栈方式。 |
|
|
|
|
|
程序设计:
u 任务栈大小分配: staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈 */ staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskScanStk[1024/8]; /* 任务栈 */ staticuint64_t AppTaskStartStk[1024/8]; /* 任务栈 */ 将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。 u 系统栈大小分配: |
|
|
|
|
|
RTX初始化:
复制代码 /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main (void) { /* 初始化外设 */ bsp_Init(); /* 创建启动任务 */ os_sys_init_user (AppTaskStart, /* 任务函数 */ 5, /* 任务优先级 */ &AppTaskStartStk, /* 任务栈 */ sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */ while(1); } |
|
|
|
|
|
RTX任务创建:
复制代码 /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */ 2, /* 任务优先级 */ &AppTaskLEDStk, /* 任务栈 */ sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */ HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */ 3, /* 任务优先级 */ &AppTaskMsgProStk, /* 任务栈 */ sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */ HandleTaskScan = os_tsk_create_user(AppTaskScan, /* 任务函数 */ 4, /* 任务优先级 */ &AppTaskScanStk, /* 任务栈 */ sizeof(AppTaskScanStk)); /* 任务栈大小,单位字节数 */ } |
|
|
|
|
|
STM32F103独立看门狗驱动:
复制代码 /* ********************************************************************************************************* * 函 数 名: bsp_InitIwdg * 功能说明: 独立看门狗时间配置函数 * 形 参:IWDGTime: 0 - 0x0FFF,设置的是128分频,LSI的时钟频率按40KHz计算。 * 128分频的情况下,最小3.2ms,最大13107.2ms。 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitIwdg(uint32_t _ulIWDGTime) { /* 检测系统是否从独立看门狗复位中恢复 */ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { /* 清除复位标志 */ RCC_ClearFlag(); } /* 使能LSI */ RCC_LSICmd(ENABLE); /* 等待直到LSI就绪 */ while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET); /* 写入0x5555表示允许访问IWDG_PR 和IWDG_RLR寄存器 */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* LSI/32 分频*/ IWDG_SetPrescaler(IWDG_Prescaler_128); IWDG_SetReload(_ulIWDGTime); /* 重载IWDG计数 */ IWDG_ReloadCounter(); /* 使能 IWDG (LSI oscillator 由硬件使能) */ IWDG_Enable(); } /* ********************************************************************************************************* * 函 数 名: IWDG_Feed * 功能说明: 喂狗函数 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void IWDG_Feed(void) { IWDG_ReloadCounter(); } |
|
|
|
|
|
20.2.2 STM32F407开发板实验
配套例子: V5-420_RTX实验_独立看门狗监测任务的执行状态 实验目的: 1. 学习独立看门狗监测任务的执行状态 实验内容: 1.K1按键按下,串口打印。 2.看门狗监测任务执行状态说明: (1). 设置看门狗复位时间是10s,如果10s内不喂狗系统复位。 (2). 使用事件标志组,在最高优先级任务中等待其它所有用户任务发来的事件标志,如果所有任务都发来了事件标志,那么就执行喂狗程序,如果有一个任务10s内没有发来事件标志,那么系统会被复位。 (3). 简单的说就是为了检测任务的执行转态,我们设置每个任务10s内必须发一次事件标志以此来表示任务在执行。如果10s内有一个任务没有发来消息,系统会被复位。 (4). 等待事件标志的任务: xResult= os_evt_wait_and (TASK_BIT_ALL, usMaxBlockTime); 其它四个发送事件标志的任务: os_evt_set(TASK_BIT_0, HandleTaskStart); os_evt_set(TASK_BIT_1, HandleTaskStart); os_evt_set(TASK_BIT_2, HandleTaskStart); os_evt_set(TASK_BIT_3, HandleTaskStart); 3.K2按键按下后将任务AppTaskTaskUserIF延迟20s后执行,从而实现看门狗复位。 4.各个任务实现的功能如下: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里用作LED闪烁。 AppTaskScan任务 :按键扫描。 AppTaskStart任务 :启动任务,也是最高优先级任务,等待其它任务发送来的事件标志。 |
|
|
|
|
|
RTX配置:
RTX配置向导详情如下: u Task Configuration l Number of concurrent running tasks 允许创建5个任务,实际创建了如下5个任务: AppTaskUserIF任务 :按键消息处理。 AppTaskLED任务 :LED闪烁。 AppTaskMsgPro任务 :消息处理,这里用作LED闪烁。 AppTaskScan任务 :按键扫描。 AppTaskStart任务 :启动任务,也是最高优先级任务,等待其它任务发送来的事件标志。 l Number of tasks with user-provided stack 创建的5个任务都是采用自定义堆栈方式。 |
|
|
|
|
|
程序设计:
u 任务栈大小分配: staticuint64_t AppTaskUserIFStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskLEDStk[256/8]; /* 任务栈 */ staticuint64_t AppTaskMsgProStk[512/8]; /* 任务栈 */ staticuint64_t AppTaskStartStk[512/8]; /* 任务栈 */ 将任务栈定义成uint64_t类型可以保证任务栈是8字节对齐的,8字节对齐的含义就是数组的首地址对8求余等于0。如果不做8字节对齐的话,部分C语言库函数,浮点运算和uint64_t类型数据运算会出问题。 u 系统栈大小分配: |
|
|
|
|
|
RTX初始化:
复制代码 /* ********************************************************************************************************* * 函 数 名: main * 功能说明: 标准c程序入口。 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ int main (void) { /* 初始化外设 */ bsp_Init(); /* 创建启动任务 */ os_sys_init_user (AppTaskStart, /* 任务函数 */ 5, /* 任务优先级 */ &AppTaskStartStk, /* 任务栈 */ sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */ while(1); } |
|
|
|
|
|
RTX任务创建:
复制代码 /* ********************************************************************************************************* * 函 数 名: AppTaskCreate * 功能说明: 创建应用任务 * 形 参: 无 * 返 回 值: 无 ********************************************************************************************************* */ static void AppTaskCreate (void) { HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, /* 任务函数 */ 1, /* 任务优先级 */ &AppTaskUserIFStk, /* 任务栈 */ sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */ HandleTaskLED = os_tsk_create_user(AppTaskLED, /* 任务函数 */ 2, /* 任务优先级 */ &AppTaskLEDStk, /* 任务栈 */ sizeof(AppTaskLEDStk)); /* 任务栈大小,单位字节数 */ HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro, /* 任务函数 */ 3, /* 任务优先级 */ &AppTaskMsgProStk, /* 任务栈 */ sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */ HandleTaskScan = os_tsk_create_user(AppTaskScan, /* 任务函数 */ 4, /* 任务优先级 */ &AppTaskScanStk, /* 任务栈 */ sizeof(AppTaskScanStk)); /* 任务栈大小,单位字节数 */ } |
|
|
|
|
|
STM32F407独立看门狗驱动:
复制代码 /* ********************************************************************************************************* * 函 数 名: bsp_InitIwdg * 功能说明: 独立看门狗时间配置函数 * 形 参:IWDGTime: 0 - 0x0FFF,设置的是32分频,LSI的时钟频率按32KHz计算。 * 32分频的情况下,最小1ms,最大4095ms。 * ---------------------- * 这里没有结合TIM5测得实际LSI频率,LSI = 34000左右 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_InitIwdg(uint32_t _ulIWDGTime) { /* 检测系统是否从独立看门狗复位中恢复 */ if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { /* 清除复位标志 */ RCC_ClearFlag(); } else { /* 标志没有设置 */ } /* 使能LSI */ RCC_LSICmd(ENABLE); /* 等待直到LSI就绪 */ while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET) {} /* 写入0x5555表示允许访问IWDG_PR 和IWDG_RLR寄存器 */ IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); /* LSI/32 分频*/ IWDG_SetPrescaler(IWDG_Prescaler_32); /*特别注意,由于这里_ulIWDGTime的最小单位是ms, 所以这里重装计数的 计数时 需要除以1000 Counter Reload Value = (_ulIWDGTime / 1000) /(1 / IWDG counter clock period) = (_ulIWDGTime / 1000) / (32/LSI) = (_ulIWDGTime / 1000) / (32/LsiFreq) = LsiFreq * _ulIWDGTime / 32000 实际测试LsiFreq = 34000,所以这里取1的时候 大概就是1ms */ IWDG_SetReload(_ulIWDGTime); /* 重载IWDG计数 */ IWDG_ReloadCounter(); /* 使能 IWDG (LSI oscillator 由硬件使能) */ IWDG_Enable(); } /* ********************************************************************************************************* * 函 数 名: IWDG_Feed * 功能说明: 喂狗函数 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void IWDG_Feed(void) { IWDG_ReloadCounter(); } |
|
|
|
|
|
20.3 总结
本章节就为大家介绍了一种使用独立看门狗监测任务执行状态的方法,主要目的是拓展一下大家的思 路,如果有更好的思路也可以尝试一下。 |
|
|
|
|
|
464 浏览 0 评论
478 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
439 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
994 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
1056 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11780 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 06:18 , Processed in 1.026660 second(s), Total 103, Slave 84 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号