[应用相关] stm32 入门RT-Thread内核 空闲线程和两个常用的钩子函数

[复制链接]
1379|20
 楼主| 一路向北lm 发表于 2021-1-10 22:03 | 显示全部楼层 |阅读模式
空闲线程
空闲线程是一个比较特殊的系统线程,它具备最低优先级,当系统中无其他就绪态线程可运行时,调度器将调度到空闲线程。空闲线程还负责一些系统资源的回收以及将一些处于关闭态的线程从线程调度列表中移除的动作。空闲任务在形式上是一个无限循环结构,且永远不被挂起。

 楼主| 一路向北lm 发表于 2021-1-10 22:03 | 显示全部楼层
空闲线程钩子函数
RT-Thread实时操作系统中的空闲线程向用户提供了钩子函数,空闲线程钩子函数可以让系统在空闲的时候执行一些非紧急的事物,例如系统运行指示闪烁,CPU使用率统计等。
 楼主| 一路向北lm 发表于 2021-1-10 22:03 | 显示全部楼层
空闲线程两个钩子函数:
设置钩子函数  rt_err_t rt_thread_idle_sethook(void (*hook)(void));
删除钩子函数  rt_err_t rt_thread_idle_delhook(void (*hook)(void));
 楼主| 一路向北lm 发表于 2021-1-10 22:04 | 显示全部楼层
空闲线程钩子函数使用注意:
    空闲线程是一个线程状态永远为就绪态的线程,所有钩子函数中执行的相关代码必须保证空闲线程在任何时刻都不会被挂起,例如执行rt_thread_delay()、rt_sem_take()等,可能会导致线程挂起,因此不能在钩子函数中使用。此外,空闲线程可以设置多个钩子函数。
 楼主| 一路向北lm 发表于 2021-1-10 22:04 | 显示全部楼层
基于STM32空闲线程钩子函数具体实例(CPU的占用率统计):
统计原理: 在相同时间内,统计CPU在不调度的情况和CPU在调度情况下变量的计数值,得出CPU空闲率,CPU的占用率 = 1 - CPU空闲率。
定义钩子函数 : static void cpu_usage_idle_hook(void);
将钩子函数添加到空闲线程中:  rt_thread_idle_sethook(cpu_usage_idle_hook);
 楼主| 一路向北lm 发表于 2021-1-10 22:04 | 显示全部楼层
定义钩子函数代码实现:
  1. #define CPU_USAGE_TICK     10
  2. #define CPU_USAGE_LOOP     100
  3. rt_uint8_t  cpu_usage_integer = 0;
  4. rt_uint8_t  cpu_usage_decimal = 0;
  5. // 空闲线程钩子函数 ,统计CPU利用率
  6. static void cpu_usage_idle_hook(void)
  7. {
  8.     volatile rt_tick_t   tick  = 0;
  9.     volatile rt_uint32_t count = 0;
  10.     volatile rt_uint32_t loop  = 0;
  11.     if(cpu_usage_count == 0)
  12.     {
  13.         rt_enter_critical();
  14.         tick = rt_tick_get();
  15.         while((rt_tick_get() - tick) < CPU_USAGE_TICK)
  16.         {
  17.             cpu_usage_count++;
  18.             loop = 0;
  19.             while(loop < CPU_USAGE_LOOP)
  20.             {
  21.                 loop++;
  22.             }
  23.         }
  24.         rt_exit_critical();
  25.     }
  26.     count = 0;
  27.     tick  = rt_tick_get();
  28.     while((rt_tick_get() - tick) < CPU_USAGE_TICK)
  29.     {
  30.         count++;
  31.         loop = 0;
  32.         while(loop < CPU_USAGE_LOOP)
  33.         {
  34.             loop++;
  35.         }
  36.     }

  37. /* Calculate STM32 CPU Usage */
  38.     if(count < cpu_usage_count)
  39.     {
  40.         count = cpu_usage_count - count;
  41.         cpu_usage_integer =  (count * 100) / cpu_usage_count;
  42.         cpu_usage_decimal = ((count * 100) % cpu_usage_count) * 100 / cpu_usage_count;
  43.     }
  44.     else
  45.     {
  46.         cpu_usage_count = count;
  47.         cpu_usage_integer = 0;
  48.         cpu_usage_decimal = 0;
  49.     }
  50. }


 楼主| 一路向北lm 发表于 2021-1-10 22:05 | 显示全部楼层
效果展示:我只点亮了两个灯
430425ffb099373270.png
 楼主| 一路向北lm 发表于 2021-1-10 22:05 | 显示全部楼层
系统调度钩子函数
系统的上下文切换是系统运行过程中最普遍的事件,有时候可能会想知道在某一个时刻发生了什么样的线程切换,RT-Thread向用户提供了一个系统调度钩子函数,这个钩子函数在系统任务切换时运行,通过这个钩子函数,我们可以了解到系统任务调度的一些信息。
void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to));
 楼主| 一路向北lm 发表于 2021-1-10 22:06 | 显示全部楼层
基于STM32系统调度钩子函数具体实例:
  1. static rt_thread_t  led1_thread = RT_NULL;
  2. static rt_thread_t  led2_thread = RT_NULL;
  3. // 入口函数
  4. void led1_task(void *parameter)
  5. {
  6.     while(1)
  7.                 {
  8.       LED1_TURN;
  9.                    rt_thread_mdelay(1000);         
  10.                 }        
  11. }
  12. void led2_task(void *parameter)
  13. {
  14.     while(1)
  15.                 {
  16.                   LED2_TURN;
  17.                   rt_thread_mdelay(500);
  18.                 }       
  19. }
  20. // 系统调度钩子函数
  21. static void hook_of_scheduler(struct rt_thread *from, struct rt_thread *to)
  22. {
  23.          rt_kprintf("form %s---> to %s\n",from->name,to->name);
  24. }

  25. // 添加系统调度钩子函数,创建线程并开启
  26. rt_scheduler_sethook(hook_of_scheduler);
  27.         led1_thread = rt_thread_create("led1",led1_task,RT_NULL,256,3,10);
  28.         led2_thread = rt_thread_create("led2",led2_task,RT_NULL,256,3,5);
  29.        
  30.         if(led1_thread != RT_NULL)
  31.                   rt_thread_startup(led1_thread);
  32.   else
  33.                  return -1;
  34.         if(led2_thread != RT_NULL)
  35.                   rt_thread_startup(led2_thread);
  36.   else       
  37.            return -1;


 楼主| 一路向北lm 发表于 2021-1-10 22:06 | 显示全部楼层
系统任务调度的一些信息效果如下:
974235ffb09dfa3832.png
guanjiaer 发表于 2021-2-3 23:06 | 显示全部楼层
一直以为空闲的是一直被挂起的呢
heimaojingzhang 发表于 2021-2-3 23:08 | 显示全部楼层
偶没有可能永远不会执行空闲任务呢
keaibukelian 发表于 2021-2-3 23:10 | 显示全部楼层
最后的哪个调度信息是怎么显示的呢
labasi 发表于 2021-2-3 23:13 | 显示全部楼层
一直连接不了钩子的定义
paotangsan 发表于 2021-2-3 23:16 | 显示全部楼层
没有接触过的人很难理解
 楼主| 一路向北lm 发表于 2021-2-4 17:06 | 显示全部楼层
guanjiaer 发表于 2021-2-3 23:06
一直以为空闲的是一直被挂起的呢

这会知道了吧
 楼主| 一路向北lm 发表于 2021-2-4 17:06 | 显示全部楼层
paotangsan 发表于 2021-2-3 23:16
没有接触过的人很难理解

是的,感觉来逛ST论坛的大部分都知道
 楼主| 一路向北lm 发表于 2021-2-4 17:07 | 显示全部楼层
labasi 发表于 2021-2-3 23:13
一直连接不了钩子的定义

理解不了?
 楼主| 一路向北lm 发表于 2021-2-4 17:07 | 显示全部楼层
keaibukelian 发表于 2021-2-3 23:10
最后的哪个调度信息是怎么显示的呢

可以深入研究一下源码
 楼主| 一路向北lm 发表于 2021-2-4 17:08 | 显示全部楼层
heimaojingzhang 发表于 2021-2-3 23:08
偶没有可能永远不会执行空闲任务呢

那CPU的利用率不就是 100%了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部