硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3149|回复: 2
收起左侧

[RL-RTX] 【RTX操作系统教程】第20章     独立看门监测多任务的执行状态

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2016-1-8 15:42:13 | 显示全部楼层 |阅读模式
第20章    独立看门监测多任务的执行状态


    通过前面的几个章节,我们基本已经完成了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的所有用户任务都在正常的执行,我们通过独立看门的形式来监测,一旦发现有某个任务长时间没有执行,看门狗就会将系统复位。
20.1.png

运行条件:
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可以及时的喂狗,如果放在一个低优先级的任务里面,那么当所有的任务任务都已经发送任务运行正常的事件标志,但是此任务在执行喂狗程序前被其它高优先级的任务抢占了造成不能及时喂狗,从而造成系统复位,这种误判断会造成系统不能够正常工作。

按照上面的实现思路,我们在开发板上面实战演练下。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2016-1-8 15:49:10 | 显示全部楼层
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配置向导详情如下:
20.2.png

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个任务都是采用自定义堆栈方式。
RTX任务调试信息:
20.3.png

程序设计:
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  系统栈大小分配:
20.4.png

u  RTX初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main (void)
  10. {   
  11.      /* 初始化外设 */
  12.      bsp_Init();
  13.    
  14.      /* 创建启动任务 */
  15.      os_sys_init_user (AppTaskStart,             /* 任务函数 */
  16.                        5,                        /* 任务优先级 */
  17.                        &AppTaskStartStk,         /* 任务栈 */
  18.                        sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
  19.      while(1);
  20. }
复制代码
u  RTX任务创建:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskCreate
  4. *    功能说明: 创建应用任务
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. static void AppTaskCreate (void)
  10. {
  11.      HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF,             /* 任务函数 */
  12.                                            1,                         /* 任务优先级 */
  13.                                            &AppTaskUserIFStk,         /* 任务栈 */
  14.                                            sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
  15.    
  16.      HandleTaskLED = os_tsk_create_user(AppTaskLED,              /* 任务函数 */
  17.                                         2,                       /* 任务优先级 */
  18.                                         &AppTaskLEDStk,          /* 任务栈 */
  19.                                         sizeof(AppTaskLEDStk));  /* 任务栈大小,单位字节数 */
  20.    
  21.      HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro,             /* 任务函数 */
  22.                                            3,                         /* 任务优先级 */
  23.                                            &AppTaskMsgProStk,         /* 任务栈 */
  24.                                            sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
  25.    
  26.      HandleTaskScan = os_tsk_create_user(AppTaskScan,             /* 任务函数 */
  27.                                          4,                       /* 任务优先级 */
  28.                                          &AppTaskScanStk,         /* 任务栈 */
  29.                                          sizeof(AppTaskScanStk)); /* 任务栈大小,单位字节数 */
  30. }
复制代码
u  STM32F103独立看门狗驱动:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_InitIwdg
  4. *    功能说明: 独立看门狗时间配置函数
  5. *    形    参:IWDGTime: 0 - 0x0FFF,设置的是128分频,LSI的时钟频率按40KHz计算。
  6. *             128分频的情况下,最小3.2ms,最大13107.2ms。
  7. *    返 回 值: 无              
  8. *********************************************************************************************************
  9. */
  10. void bsp_InitIwdg(uint32_t _ulIWDGTime)
  11. {
  12.         
  13.      /* 检测系统是否从独立看门狗复位中恢复 */
  14.      if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
  15.      {      
  16.          /* 清除复位标志 */
  17.          RCC_ClearFlag();
  18.      }
  19.    
  20.      /* 使能LSI */
  21.      RCC_LSICmd(ENABLE);
  22.    
  23.      /* 等待直到LSI就绪 */
  24.      while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
  25.      /* 写入0x5555表示允许访问IWDG_PR 和IWDG_RLR寄存器 */
  26.      IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  27.    
  28.      /*  LSI/32 分频*/
  29.      IWDG_SetPrescaler(IWDG_Prescaler_128);
  30.    
  31.      IWDG_SetReload(_ulIWDGTime);
  32.    
  33.      /* 重载IWDG计数 */
  34.      IWDG_ReloadCounter();
  35.    
  36.      /* 使能 IWDG (LSI oscillator 由硬件使能) */
  37.      IWDG_Enable();        
  38. }
  39. /*
  40. *********************************************************************************************************
  41. *    函 数 名: IWDG_Feed
  42. *    功能说明: 喂狗函数
  43. *    形    参:无
  44. *    返 回 值: 无              
  45. *********************************************************************************************************
  46. */
  47. void IWDG_Feed(void)
  48. {
  49.      IWDG_ReloadCounter();
  50. }
复制代码
u  五个RTX任务的实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskUserIF
  4. *    功能说明: 按键消息处理     
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *   优 先 级: 1  (数值越小优先级越低,这个跟uCOS相反)
  8. *********************************************************************************************************
  9. */
  10. __task void AppTaskUserIF(void)
  11. {
  12.      uint8_t ucKeyCode;
  13.     while(1)
  14.     {
  15.          ucKeyCode = bsp_GetKey();
  16.         
  17.          if (ucKeyCode != KEY_NONE)
  18.          {
  19.               switch (ucKeyCode)
  20.               {
  21.                    /* K1键按下,打印调试说明 */
  22.                    case KEY_DOWN_K1:
  23.                        printf("K1键按下,使用MDK中自带的RTX调试组件,请务必使用MDK4.74版本进行调试\\r\\n");
  24.                        break;  
  25.                   
  26.                    /* K2按键按下,让AppTaskUserIF任务延迟20s,以实现看门狗复位情况 */
  27.                    case KEY_DOWN_K2:
  28.                        printf("K2按键按下,让AppTaskUserIF任务延迟20s,以实现看门狗复位情况\\r\\n");
  29.                        os_dly_wait(20000);
  30.                        break;
  31.                   
  32.                    /* 其他的键值不处理 */
  33.                    default:                    
  34.                        break;
  35.               }
  36.          }
  37.         
  38.          /* 发送事件标志,表示任务正常运行 */
  39.          os_evt_set(TASK_BIT_0, HandleTaskStart);
  40.          os_dly_wait(20);
  41.      }
  42. }
  43. /*
  44. *********************************************************************************************************
  45. *    函 数 名: AppTaskLED
  46. *    功能说明: LED闪烁。
  47. *    形    参: 无
  48. *    返 回 值: 无
  49. *   优 先 级: 2
  50. *********************************************************************************************************
  51. */
  52. __task void AppTaskLED(void)
  53. {
  54.      const uint16_t usFrequency = 1000; /* 延迟周期 */
  55.    
  56.      /* 设置延迟周期 */
  57.      os_itv_set(usFrequency);
  58.    
  59.     while(1)
  60.     {
  61.          bsp_LedToggle(2);
  62.          bsp_LedToggle(3);
  63.         
  64.          /* 发送事件标志,表示任务正常运行 */
  65.          os_evt_set(TASK_BIT_1, HandleTaskStart);
  66.         
  67.          /* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
  68.          os_itv_wait();
  69.     }
  70. }
  71. /*
  72. *********************************************************************************************************
  73. *    函 数 名: AppTaskMsgPro
  74. *    功能说明: 消息处理,LED闪烁
  75. *    形    参: 无
  76. *    返 回 值: 无
  77. *   优 先 级: 3
  78. *********************************************************************************************************
  79. */
  80. __task void AppTaskMsgPro(void)
  81. {
  82.      const uint16_t usFrequency = 500; /* 延迟周期 */
  83.    
  84.      /* 设置延迟周期 */
  85.      os_itv_set(usFrequency);
  86.    
  87.     while(1)
  88.     {
  89.          bsp_LedToggle(1);
  90.          bsp_LedToggle(4);
  91.         
  92.          /* 发送事件标志,表示任务正常运行 */
  93.          os_evt_set(TASK_BIT_2, HandleTaskStart);
  94.          /* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
  95.          os_itv_wait();
  96.     }
  97. }
  98. /*
  99. *********************************************************************************************************
  100. *    函 数 名: AppTaskScan
  101. *    功能说明: 按键扫描。
  102. *    形    参: 无
  103. *    返 回 值: 无
  104. *   优 先 级: 4
  105. *********************************************************************************************************
  106. */
  107. __task void AppTaskScan(void)
  108. {
  109.     while(1)
  110.     {
  111.          /* 按键扫描 */
  112.          bsp_KeyScan();
  113.         
  114.          /* 发送事件标志,表示任务正常运行 */
  115.          os_evt_set(TASK_BIT_3, HandleTaskStart);
  116.         
  117.         os_dly_wait(10);
  118.     }
  119. }
  120. /*
  121. *********************************************************************************************************
  122. *    函 数 名: AppTaskStart
  123. *    功能说明: 启动任务,也就是最高优先级任务。
  124. *    形    参: 无
  125. *    返 回 值: 无
  126. *   优 先 级: 4
  127. *********************************************************************************************************
  128. */
  129. __task void AppTaskStart(void)
  130. {
  131.      OS_RESULT xResult;
  132.      const uint16_t usMaxBlockTime = 500; /* 延迟周期 */
  133.    
  134.      /* 获取启动任务的句柄 */
  135.      HandleTaskStart = os_tsk_self();
  136.    
  137.      /* 创建任务 */
  138.      AppTaskCreate();
  139.    
  140.      /*
  141.    
  142.        开始执行启动任务主函数前使能独立看门狗。
  143.        设置LSI是128分频,下面函数参数范围0-0xFFF,分别代表最小值3.2ms和最大值13107.2ms
  144.        下面设置的是10s,如果10s内没有喂狗,系统复位。
  145.      */
  146.      bsp_InitIwdg(0xC35);
  147.    
  148.      /* 打印系统开机状态,方便查看系统是否复位 */
  149.      printf("=====================================================\\r\\n");
  150.      printf("=系统开机执行\\r\\n");
  151.      printf("=====================================================\\r\\n");
  152.    
  153.     while(1)
  154.     {
  155.          /* 等待所有任务发来的事件标志 */
  156.          xResult = os_evt_wait_and(TASK_BIT_ALL, usMaxBlockTime);
  157.         
  158.          switch (xResult)
  159.          {
  160.               /* 接收到所有任务都发来的事件标志 */
  161.               case OS_R_EVT:
  162.                    IWDG_Feed();
  163.                    printf("五个用户任务都正常运行\\r\\n");
  164.                    break;  
  165.               /* 超时 */
  166.               case OS_R_TMO:
  167.                    break;
  168.             
  169.               /* 其他值不处理 */
  170.               default:                    
  171.                    break;
  172.          }   
  173.      }
  174. }
复制代码

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配置向导详情如下:
20.5.png

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个任务都是采用自定义堆栈方式。
RTX任务调试信息:
20.6.png

程序设计:
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  系统栈大小分配:
20.7.png

u  RTX初始化:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: main
  4. *    功能说明: 标准c程序入口。
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. int main (void)
  10. {   
  11.      /* 初始化外设 */
  12.      bsp_Init();
  13.    
  14.      /* 创建启动任务 */
  15.      os_sys_init_user (AppTaskStart,             /* 任务函数 */
  16.                        5,                        /* 任务优先级 */
  17.                        &AppTaskStartStk,         /* 任务栈 */
  18.                        sizeof(AppTaskStartStk)); /* 任务栈大小,单位字节数 */
  19.      while(1);
  20. }
复制代码
u  RTX任务创建:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskCreate
  4. *    功能说明: 创建应用任务
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. static void AppTaskCreate (void)
  10. {
  11.      HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF,             /* 任务函数 */
  12.                                            1,                         /* 任务优先级 */
  13.                                            &AppTaskUserIFStk,         /* 任务栈 */
  14.                                            sizeof(AppTaskUserIFStk)); /* 任务栈大小,单位字节数 */
  15.    
  16.      HandleTaskLED = os_tsk_create_user(AppTaskLED,              /* 任务函数 */
  17.                                         2,                       /* 任务优先级 */
  18.                                         &AppTaskLEDStk,          /* 任务栈 */
  19.                                         sizeof(AppTaskLEDStk));  /* 任务栈大小,单位字节数 */
  20.    
  21.      HandleTaskMsgPro = os_tsk_create_user(AppTaskMsgPro,             /* 任务函数 */
  22.                                            3,                         /* 任务优先级 */
  23.                                            &AppTaskMsgProStk,         /* 任务栈 */
  24.                                            sizeof(AppTaskMsgProStk)); /* 任务栈大小,单位字节数 */
  25.    
  26.      HandleTaskScan = os_tsk_create_user(AppTaskScan,             /* 任务函数 */
  27.                                          4,                       /* 任务优先级 */
  28.                                          &AppTaskScanStk,         /* 任务栈 */
  29.                                          sizeof(AppTaskScanStk)); /* 任务栈大小,单位字节数 */
  30. }
复制代码
u  STM32F407独立看门狗驱动:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: bsp_InitIwdg
  4. *    功能说明: 独立看门狗时间配置函数
  5. *    形    参:IWDGTime: 0 - 0x0FFF,设置的是32分频,LSI的时钟频率按32KHz计算。
  6. *             32分频的情况下,最小1ms,最大4095ms。
  7. *             ----------------------
  8. *             这里没有结合TIM5测得实际LSI频率,LSI = 34000左右
  9. *    返 回 值: 无              
  10. *********************************************************************************************************
  11. */
  12. void bsp_InitIwdg(uint32_t _ulIWDGTime)
  13. {
  14.         
  15.      /* 检测系统是否从独立看门狗复位中恢复 */
  16.      if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)
  17.      {      
  18.          /* 清除复位标志 */
  19.          RCC_ClearFlag();
  20.      }
  21.      else
  22.      {
  23.          /* 标志没有设置 */
  24.      }
  25.    
  26.      /* 使能LSI */
  27.      RCC_LSICmd(ENABLE);
  28.    
  29.      /* 等待直到LSI就绪 */
  30.      while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
  31.      {}
  32.    
  33.      /* 写入0x5555表示允许访问IWDG_PR 和IWDG_RLR寄存器 */
  34.      IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
  35.    
  36.      /*  LSI/32 分频*/
  37.      IWDG_SetPrescaler(IWDG_Prescaler_32);
  38.    
  39.      /*特别注意,由于这里_ulIWDGTime的最小单位是ms, 所以这里重装计数的
  40.        计数时 需要除以1000
  41.       Counter Reload Value = (_ulIWDGTime / 1000) /(1 / IWDG counter clock period)
  42.                            = (_ulIWDGTime / 1000) / (32/LSI)
  43.                            = (_ulIWDGTime / 1000) / (32/LsiFreq)
  44.                            = LsiFreq * _ulIWDGTime / 32000
  45.       实际测试LsiFreq = 34000,所以这里取1的时候 大概就是1ms
  46.      */
  47.      IWDG_SetReload(_ulIWDGTime);
  48.    
  49.      /* 重载IWDG计数 */
  50.      IWDG_ReloadCounter();
  51.    
  52.      /* 使能 IWDG (LSI oscillator 由硬件使能) */
  53.      IWDG_Enable();        
  54. }
  55. /*
  56. *********************************************************************************************************
  57. *    函 数 名: IWDG_Feed
  58. *    功能说明: 喂狗函数
  59. *    形    参:无
  60. *    返 回 值: 无              
  61. *********************************************************************************************************
  62. */
  63. void IWDG_Feed(void)
  64. {
  65.      IWDG_ReloadCounter();
  66. }
复制代码
u  五个RTX任务的实现:
  1. /*
  2. *********************************************************************************************************
  3. *    函 数 名: AppTaskUserIF
  4. *    功能说明: 按键消息处理     
  5. *    形    参: 无
  6. *    返 回 值: 无
  7. *   优 先 级: 1  (数值越小优先级越低,这个跟uCOS相反)
  8. *********************************************************************************************************
  9. */
  10. __task void AppTaskUserIF(void)
  11. {
  12.      uint8_t ucKeyCode;
  13.     while(1)
  14.     {
  15.          ucKeyCode = bsp_GetKey();
  16.         
  17.          if (ucKeyCode != KEY_NONE)
  18.          {
  19.               switch (ucKeyCode)
  20.               {
  21.                    /* K1键按下,打印调试说明 */
  22.                    case KEY_DOWN_K1:
  23.                        printf("K1键按下,使用MDK中自带的RTX调试组件,请务必使用MDK4.74版本进行调试\\r\\n");
  24.                        break;  
  25.                   
  26.                    /* K2按键按下,让AppTaskUserIF任务延迟20s,以实现看门狗复位情况 */
  27.                    case KEY_DOWN_K2:
  28.                        printf("K2按键按下,让AppTaskUserIF任务延迟20s,以实现看门狗复位情况\\r\\n");
  29.                        os_dly_wait(20000);
  30.                        break;
  31.                   
  32.                    /* 其他的键值不处理 */
  33.                    default:                    
  34.                        break;
  35.               }
  36.          }
  37.         
  38.          /* 发送事件标志,表示任务正常运行 */
  39.          os_evt_set(TASK_BIT_0, HandleTaskStart);
  40.          os_dly_wait(20);
  41.      }
  42. }
  43. /*
  44. *********************************************************************************************************
  45. *    函 数 名: AppTaskLED
  46. *    功能说明: LED闪烁。
  47. *    形    参: 无
  48. *    返 回 值: 无
  49. *   优 先 级: 2
  50. *********************************************************************************************************
  51. */
  52. __task void AppTaskLED(void)
  53. {
  54.      const uint16_t usFrequency = 1000; /* 延迟周期 */
  55.    
  56.      /* 设置延迟周期 */
  57.      os_itv_set(usFrequency);
  58.    
  59.     while(1)
  60.     {
  61.          bsp_LedToggle(2);
  62.          bsp_LedToggle(3);
  63.         
  64.          /* 发送事件标志,表示任务正常运行 */
  65.          os_evt_set(TASK_BIT_1, HandleTaskStart);
  66.         
  67.          /* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
  68.          os_itv_wait();
  69.     }
  70. }
  71. /*
  72. *********************************************************************************************************
  73. *    函 数 名: AppTaskMsgPro
  74. *    功能说明: 消息处理,LED闪烁
  75. *    形    参: 无
  76. *    返 回 值: 无
  77. *   优 先 级: 3
  78. *********************************************************************************************************
  79. */
  80. __task void AppTaskMsgPro(void)
  81. {
  82.      const uint16_t usFrequency = 500; /* 延迟周期 */
  83.    
  84.      /* 设置延迟周期 */
  85.      os_itv_set(usFrequency);
  86.    
  87.     while(1)
  88.     {
  89.          bsp_LedToggle(1);
  90.          bsp_LedToggle(4);
  91.         
  92.          /* 发送事件标志,表示任务正常运行 */
  93.          os_evt_set(TASK_BIT_2, HandleTaskStart);
  94.          /* os_itv_wait是绝对延迟,os_dly_wait是相对延迟。*/
  95.          os_itv_wait();
  96.     }
  97. }
  98. /*
  99. *********************************************************************************************************
  100. *    函 数 名: AppTaskScan
  101. *    功能说明: 按键扫描。
  102. *    形    参: 无
  103. *    返 回 值: 无
  104. *   优 先 级: 4
  105. *********************************************************************************************************
  106. */
  107. __task void AppTaskScan(void)
  108. {
  109.     while(1)
  110.     {
  111.          /* 按键扫描 */
  112.          bsp_KeyScan();
  113.         
  114.          /* 发送事件标志,表示任务正常运行 */
  115.          os_evt_set(TASK_BIT_3, HandleTaskStart);
  116.         
  117.         os_dly_wait(10);
  118.     }
  119. }
  120. /*
  121. *********************************************************************************************************
  122. *    函 数 名: AppTaskStart
  123. *    功能说明: 启动任务,也就是最高优先级任务。
  124. *    形    参: 无
  125. *    返 回 值: 无
  126. *   优 先 级: 4
  127. *********************************************************************************************************
  128. */
  129. __task void AppTaskStart(void)
  130. {
  131.      OS_RESULT xResult;
  132.      const uint16_t usMaxBlockTime = 500; /* 延迟周期 */
  133.    
  134.      /* 获取启动任务的句柄 */
  135.      HandleTaskStart = os_tsk_self();
  136.    
  137.      /* 创建任务 */
  138.      AppTaskCreate();
  139.    
  140.      /*
  141.    
  142.        开始执行启动任务主函数前使能独立看门狗。
  143.        设置LSI是128分频,下面函数参数范围0-0xFFF,分别代表最小值3.2ms和最大值13107.2ms
  144.        下面设置的是10s,如果10s内没有喂狗,系统复位。
  145.      */
  146.      bsp_InitIwdg(0xC35);
  147.    
  148.      /* 打印系统开机状态,方便查看系统是否复位 */
  149.      printf("=====================================================\\r\\n");
  150.      printf("=系统开机执行\\r\\n");
  151.      printf("=====================================================\\r\\n");
  152.    
  153.     while(1)
  154.     {
  155.          /* 等待所有任务发来的事件标志 */
  156.          xResult = os_evt_wait_and(TASK_BIT_ALL, usMaxBlockTime);
  157.         
  158.          switch (xResult)
  159.          {
  160.               /* 接收到所有任务都发来的事件标志 */
  161.               case OS_R_EVT:
  162.                    IWDG_Feed();
  163.                    printf("五个用户任务都正常运行\\r\\n");
  164.                    break;  
  165.               /* 超时 */
  166.               case OS_R_TMO:
  167.                    break;
  168.             
  169.               /* 其他值不处理 */
  170.               default:                    
  171.                    break;
  172.          }   
  173.      }
  174. }
复制代码
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2016-1-8 15:50:05 | 显示全部楼层
20.3 总结

    本章节就为大家介绍了一种使用独立看门狗监测任务执行状态的方法,主要目的是拓展一下大家的思
路,如果有更好的思路也可以尝试一下。
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-11 14:34 , Processed in 0.333036 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表