当前位置: 首页 > news >正文

Rt-Thread 移植5--空闲线程和线程阻塞(KF32)

5.1原因

线程延时是浪费CPU资源,受否可以考虑延时的时候放弃CPU使用权,这样就充分利用了CPU的资源。
如果线程进入阻塞状态,没有其他线程运行,是否可以运行一个空闲线程来做一些内存的清理等系统工作呢:

5.2 实现

5.2.1 定义空闲线程的栈

src中定义idle.c

#include <rtthread.h>
#include <rthw.h>extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];#define IDLE_THREAD_STACK_SIZE			512ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE];

5.2.2 定义空闲线程的线程控制块

struct rt_thread idle;

5.2.3 定义空闲线程函数


rt_ubase_t rt_idletask_ctr = 0;
void rt_thread_idle_entry(void *parameter)
{parameter = parameter;while(1){rt_idletask_ctr++;}
}

5.2.4 空闲线程初始化

oid rt_thread_idle_init(void)
{rt_thread_init(&idle,"idle",rt_thread_idle_entry,RT_NULL,&rt_thread_stack[0],sizeof(rt_thread_stack),RT_THREAD_PRIORITY_MAX - 1);rt_list_insert_before(&(rt_thread_priority_table[RT_THREAD_PRIORITY_MAX-1]),&(idle.tlist));}

5.3 实现阻塞延时

5.3.1 thread.c中

void rt_thread_delay(rt_tick_t tick)
{struct rt_thread *thread;thread = rt_current_thread;thread->remaining_tick = tick;rt_schedule();
}

5.3.2 struct thread中

添加	rt_ubase_t remaining_tick;成员

5.3.3 schedule.c

/* 系统调度 */
void rt_schedule(void)
{struct rt_thread *to_thread;struct rt_thread *from_thread;if(rt_current_thread == &idle){if(rt_flag1_thread.remaining_tick == 0){from_thread = rt_current_thread;to_thread = &rt_flag1_thread;rt_current_thread = to_thread;}else if(rt_flag2_thread.remaining_tick == 0){from_thread = rt_current_thread;to_thread = &rt_flag2_thread;rt_current_thread = to_thread;}else{return ;}}else{if(rt_current_thread == &rt_flag1_thread){if(rt_flag2_thread.remaining_tick == 0){from_thread = rt_current_thread;to_thread = &rt_flag2_thread;rt_current_thread = to_thread;}else if(rt_current_thread->remaining_tick == 0){from_thread = rt_current_thread;to_thread = &idle;rt_current_thread = to_thread;}else{return;}}else if(rt_current_thread == &rt_flag2_thread){if(rt_flag1_thread.remaining_tick == 0){from_thread = rt_current_thread;to_thread = &rt_flag1_thread;rt_current_thread = to_thread;}else if(rt_current_thread->remaining_tick == 0){from_thread = rt_current_thread;to_thread = &idle;rt_current_thread = to_thread;}else{return;}}}rt_hw_context_switch((rt_uint32_t)&from_thread->sp,(rt_uint32_t)&to_thread->sp);/* 产生上下文切换 */}

5.3.4 main.c中添加systick

void __attribute__((interrupt)) _SysTick_exception (void)
{rt_interrupt_enter();rt_tick_increase();rt_interrupt_leave();
}void SysTick_Config(uint32_t Reload)
{SYSTICK_Cmd (FALSE);SYSTICK_Reload_Config(Reload);SYSTICK_Counter_Updata();                           //向ST_CV寄存器写任意值,以清零当前值寄存器SYSTICK_Clock_Config(SYSTICK_SYS_CLOCK_DIV_1);      //系统节拍定时器时钟源选择,SCLK作为时钟源SYSTICK_Systick_INT_Enable(TRUE);SYSTICK_Cmd(TRUE);INT_Interrupt_Enable(INT_SysTick,TRUE);				//使能SYSTICK中断INT_All_Enable (TRUE);
}

5.3.5 系统时基更新函数

clock.c

#include <rtthread.h>
#include <rthw.h>
#include "debug.h"static rt_tick_t rt_tick = 0;
extern rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX];void rt_tick_increase(void)
{rt_ubase_t i;struct rt_thread *thread;rt_tick++;for(i = 0;i < RT_THREAD_PRIORITY_MAX;i++){thread = rt_list_entry(rt_thread_priority_table[i].next,struct rt_thread,tlist);if(thread->remaining_tick > 0){thread->remaining_tick--;}rt_schedule();}}

5.3.6 中断函数

irq.c

#include <rthw.h>
#include <rtthread.h>volatile rt_uint8_t rt_interrupt_nest;
void rt_interrupt_enter(void)
{rt_base_t level;// RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq coming..., irq nest:%d\n",//   rt_interrupt_nest));level = rt_hw_interrupt_disable();rt_interrupt_nest ++;//RT_OBJECT_HOOK_CALL(rt_interrupt_enter_hook,());rt_hw_interrupt_enable(level);
}/*** This function will be invoked by BSP, when leave interrupt service routine** @note please don't invoke this routine in application** @see rt_interrupt_enter*/
void rt_interrupt_leave(void)
{rt_base_t level;// RT_DEBUG_LOG(RT_DEBUG_IRQ, ("irq leave, irq nest:%d\n",//  rt_interrupt_nest));level = rt_hw_interrupt_disable();rt_interrupt_nest --;//  RT_OBJECT_HOOK_CALL(rt_interrupt_leave_hook,());rt_hw_interrupt_enable(level);
}

5.4 案例

main.c

rt_hw_interrupt_disable();
SysTick_Config(SystemCoreClock/RT_TICK_PER_SECOND);
void flag1_thread_entry( void *p_arg )
{for( ;; ){P_DBG("flag1 thread\n");flag2 = 1;P_DBG("flag1 thread will dela1\n");rt_thread_delay(10);flag2 = 0;P_DBG("flag1 thread will dela2\n");rt_thread_delay(10);}
}/* 线程2 */
void flag2_thread_entry( void *p_arg )
{for( ;; ){P_DBG("flag2 thread\n");flag2 = 1;rt_thread_delay(2);flag2 = 0;P_DBG("flag2 thread will dela1\n");rt_thread_delay(2);}
}		
http://www.lryc.cn/news/210193.html

相关文章:

  • Web3 治理实践探讨:如何寻找多元化发展路径?
  • 探索Vue 3和Vue 2的区别
  • 中微爱芯74逻辑兼容替代TI/ON/NXP工规品质型号全
  • 聊一下Word2vec-训练优化篇
  • Julia元组、字典、集合
  • EfficientViT:高分辨率密集预测的多尺度线性关注
  • 每日一道算法题:26. 删除有序数组中的重复项
  • 吴恩达《机器学习》2-2->2-4:代价函数
  • 软考 系统架构设计师系列知识点之设计模式(6)
  • use renv with this project create a git repository
  • 摄像头种类繁多,需要各自APP
  • Openssl数据安全传输平台010:jasoncpp 0.10.7的编译 - Windows-vs2022 / Ubuntu/ Centos8 -含测试代码
  • GSCoolink GSV6182 带嵌入式MCU的MIPI D-PHY转HDMI 2.0
  • ABBYY FineReader PDF15免费版图片文件识别软件
  • 如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样,蓝牙接近了电脑,电脑自动解锁无需输入开机密码
  • 几道面试题记录20231023
  • c++ 线程安全的string类
  • linux上安装apktool反编译apk解析AndroidManifest.xml得到首页Activity
  • 代码随想录算法训练营第4天| 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交 、142.环形链表II
  • 【面向对象程序设计】Java大作业 汽车租赁管理系统V4.0
  • golang模拟QQ退出后自动重启
  • jQuery中ajax如何使用
  • redis集群的多key原子性操作如何实现?
  • 密码学与网络安全:量子计算的威胁与解决方案
  • GoLong的学习之路(十二)语法之标准库 flag的使用
  • mac git ssh
  • 栈、共享栈、链式栈(C++实现)
  • MySQL实战2
  • 【面试经典150 | 栈】简化路径
  • 无线电编码和记录和静音检测器 PlayOutONE LiveStream 5.0