嵌入式实时操作系统原理与创新实践 课件 第二章-线程_第1页
嵌入式实时操作系统原理与创新实践 课件 第二章-线程_第2页
嵌入式实时操作系统原理与创新实践 课件 第二章-线程_第3页
嵌入式实时操作系统原理与创新实践 课件 第二章-线程_第4页
嵌入式实时操作系统原理与创新实践 课件 第二章-线程_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

RT-Thread线程创建、调度与生命周期管理第2章线程1、线程作用与创建2、调度原理与启动3、状态迁移与管理4、线程实例与思考目录CONTENTS调度启动状态管理实例思考线程创建线程是RT-Thread的调度单位03线程创建开发者把总体方案拆成相对独立的任务,再由RTOS将这些任务组织为线程。01LCD显示界面刷新与状态呈现02按键扫描周期检测输入并触发处理03总线管理协调外设访问和数据交换调度器按优先级和线程状态安排CPU,提升多任务系统的实时性与稳定性。调度启动状态管理实例思考线程创建一个线程的三个组成部分04线程创建01线程主体函数承载线程需要执行的业务逻辑。周期任务通常在循环中调用延时函数。02线程栈保存线程上下文,包括切换所需的寄存器与运行位置03线程控制块集中记录入口、名称、栈、优先级、时间片、状态、定时器和链表节点。调度启动状态管理实例思考线程创建线程创建与初始化的三个步骤05线程创建01定义线程主体函数。一次性任务可自然退出,周期任务需要循环。02准备线程栈和线程控制块,并确定名称、参数、栈大小、优先级和时间片。03静态线程调用rt_thread_init(),动态线程调用rt_thread_create()。创建与初始化的本质,是把线程信息写入线程控制块。调度启动状态管理实例思考线程创建线程属性决定调度行为06线程创建name线程名称,用于对象管理和调试定位parameter传递给线程主体函数的参数,无参数时使用RT_NULLstack_size线程栈大小,需要覆盖函数调用和局部数据需求priority0至255,数值越小表示优先级越高tick同优先级线程的时间片大小,以系统tick为单位调度启动状态管理实例思考线程创建静态线程与动态线程07线程创建静态线程用户预先定义控制块与线程栈调用rt_thread_init()完成初始化内存生命周期伴随整个程序关闭时使用rt_thread_detach()动态线程创建函数从内存堆申请控制块与线程栈调用rt_thread_create()创建并初始化删除后由空闲线程释放动态内存关闭时使用rt_thread_delete()调度启动状态管理实例思考线程创建rt_thread_init()初始化静态线程08线程创建rt_err_trt_thread_init(structrt_thread*thread,constchar*name,void(*entry)(void*parameter),void*parameter,void*stack_start,rt_uint32_tstack_size,rt_uint8_tpriority,rt_uint32_ttick);静态线程特有参数thread:预先定义的线程控制块stack_start:预先定义的线程栈首地址stack_size:线程栈大小,常用sizeof()取得返回rt_err_t。初始化成功时返回RT_EOK。调度启动状态管理实例思考线程创建rt_thread_create()创建动态线程09线程创建rt_thread_trt_thread_create(constchar*name,void(*entry)(void*parameter),void*parameter,rt_uint32_tstack_size,rt_uint8_tpriority,rt_uint32_ttick);由创建函数管理内存不需要传入线程控制块不需要传入线程栈首地址只需说明需要的栈大小和调度属性返回rt_thread_t。创建失败时返回RT_NULL。调度启动状态管理实例思考线程创建两类线程的创建路径10线程创建动态线程01rt_object_allocate()申请控制块02RT_KERNEL_MALLOC()申请线程栈03_rt_thread_init()写入线程属性静态线程01使用用户预先定义的控制块02使用用户预先定义的线程栈03rt_object_init()后调用_rt_thread_init()两条路径最终都进入内部初始化函数。调度启动状态管理实例思考线程创建动态线程的内存申请11线程创建thread=(structrt_thread*)rt_object_allocate(RT_Object_Class_Thread,name);if(thread==RT_NULL)returnRT_NULL;stack_start=RT_KERNEL_MALLOC(stack_size);if(stack_start==RT_NULL){rt_object_delete((rt_object_t)thread);returnRT_NULL;}_rt_thread_init(thread,name,entry,parameter,stack_start,stack_size,priority,tick);两次申请先申请线程对象再申请线程栈栈申请失败时先删除已申请的线程对象成功后返回控制块地址调度启动状态管理实例思考线程创建静态线程的对象初始化12线程创建RT_ASSERT(thread!=RT_NULL);RT_ASSERT(stack_start!=RT_NULL);rt_object_init((rt_object_t)thread,RT_Object_Class_Thread,name);return_rt_thread_init(thread,name,entry,parameter,stack_start,stack_size,priority,tick);对象类型标记object->type=type|RT_Object_Class_Static;RT_Object_Class_Static的值为0x80。系统通过该位区分静态对象。调度启动状态管理实例思考线程创建生命周期、效率与返回值13线程创建比较项静态线程动态线程内存来源全局变量运行时从堆申请创建开销较低需要完成动态内存申请运行期释放不能释放预定义内存删除后可释放控制块与线程栈函数返回rt_err_t,成功为RT_EOKrt_thread_t,失败为RT_NULL调度启动状态管理实例思考线程创建静态标记影响线程关闭方式14线程创建动态对象object->type=RT_Object_Class_Thread;没有静态标记。关闭后进入失效线程链表,等待空闲线程释放内存。静态对象object->type=RT_Object_Class_Thread|RT_Object_Class_Static;带有0x80静态标记。关闭时只脱离对象链表,不释放预定义内存。调度启动状态管理实例思考线程创建调度器使用的两类数据15调度启动rt_thread_priority_table[]按优先级组织就绪线程。每个数组成员都是一条双向链表,同优先级线程挂在同一链表中。rt_thread_ready_priority_group用位图记录哪些优先级当前存在就绪线程,帮助调度器快速定位最高优先级。线程查找+上下文切换调度启动状态管理实例思考线程创建线程优先级表16调度启动图2.1线程优先级表链表组织优先级码越小,优先级越高同优先级就绪线程构成闭环最低优先级通常保留给IDLE线程链表节点存放在线程控制块中。调度启动状态管理实例思考线程创建双向链表与就绪队列17调度启动structrt_list_node{structrt_list_node*next;structrt_list_node*prev;};typedefstructrt_list_nodert_list_t;RT-Thread的链表节点只保存前后节点地址。实际线程数据仍在线程控制块中。链表头属于线程优先级表线程节点属于各自的线程控制块闭环结构便于插入、移除和轮转调度器从目标优先级链表取出就绪线程调度启动状态管理实例思考线程创建就绪优先级组的位图查找18调度启动每一位对应一个优先级0表示该优先级没有就绪线程,1表示对应链表非空。IDLE所在的最低优先级始终保持就绪。highest_ready_priority=__rt_ffs(rt_thread_ready_priority_group)-1;查找结果01定位最低的置位bit02得到数值最小的优先级码03从对应链表取出首个就绪线程调度启动状态管理实例思考线程创建内核调度中的效率考虑19调度启动图2.2register声明示例一图2.2register声明示例二原稿以register声明说明内核对访问效率的关注。在线程查询阶段,更关键的优化是通过优先级位图避免逐条扫描所有链表。位图定位优先级,链表定位线程调度启动状态管理实例思考线程创建中断中的上下文切换流程20调度启动图2.3线程调度流程调度的核心01保存原线程栈指针02记录目标线程栈指针03触发PendSV异常04在异常处理过程中完成上下文切换调度启动状态管理实例思考线程创建rt_schedule()的两个阶段21调度启动线程查找关闭中断并确认调度器未上锁用__rt_ffs()找到最高优先级从对应链表提取目标线程控制块上下文切换更新当前线程和当前优先级在线程环境发起rt_hw_context_switch()在中断环境记录切换请求,由中断退出路径完成切换目标线程与当前线程相同时不执行切换。调度启动状态管理实例思考线程创建rt_thread_startup()启动线程22调度启动rt_err_trt_thread_startup(rt_thread_tthread);参数thread:需要启动的线程控制块地址01检查线程已经初始化02恢复初始优先级并计算掩码03先挂起,再恢复到就绪列表04调用rt_schedule()触发实时调度初始化只准备控制块,startup才让调度器看到线程。调度启动状态管理实例思考线程创建线程从初始化进入就绪状态23调度启动INIT控制块已经具备完整线程信息,但链表节点尚未进入就绪表startup设置当前优先级与掩码,调用suspend和resume完成队列调整READY线程节点进入优先级链表,就绪优先级组的对应bit被置位schedule如果新线程具有更高优先级,调度器立即切换到该线程调度启动状态管理实例思考线程创建线程的五种状态24状态管理图2.4线程的状态及转化五态INIT初始READY就绪RUNNING运行SUSPEND挂起CLOSE关闭状态由函数调用、调度事件和资源等待共同推动。调度启动状态管理实例思考线程创建INIT、READY与RUNNING的迁移25状态管理INIT→READYrt_thread_startup()把线程节点插入优先级表,并把状态改为就绪READY↔RUNNING优先级最高的就绪线程获得CPU更高优先级线程就绪时,当前线程退回READY同优先级线程的时间片结束后进行轮换READY表示具备运行条件,RUNNING表示正在占用CPU。调度启动状态管理实例思考线程创建挂起、恢复与资源等待26状态管理线程进入SUSPEND,说明它暂时缺少继续运行的条件。常见等待对象延时到期信号量或互斥量可用内存池申请成功邮箱、事件或消息队列到达数据手动管理rt_thread_suspend()把线程移出就绪表rt_thread_resume()把线程恢复为就绪态信号量、邮箱和事件等发送操作也可恢复线程调度启动状态管理实例思考线程创建关闭状态与rt_thread_exit()27状态管理voidrt_thread_exit(void){thread=rt_current_thread;rt_schedule_remove_thread(thread);thread->stat=RT_THREAD_CLOSE;rt_timer_detach(&thread->thread_timer);...rt_schedule();}两种触发方式用户在程序中手动调用线程主体函数运行到末尾时自动调用动态线程先进入rt_thread_defunct链表,空闲线程再释放其线程栈和对象内存,避免线程尚未切走就释放自身栈。调度启动状态管理实例思考线程创建rt_thread_delete()与rt_thread_detach()28状态管理动态线程rt_thread_delete(thread)确认对象没有静态标记移出调度系统并关闭内置定时器进入失效线程链表,等待释放动态内存静态线程rt_thread_detach(thread)确认对象具有RT_Object_Class_Static标记移出调度系统并关闭内置定时器调用rt_object_detach()脱离对象链表调度启动状态管理实例思考线程创建线程关闭后的资源处理29状态管理动态线程对象和线程栈来自内存堆进入defunct链表,由IDLE线程释放静态线程控制块和线程栈是预定义全局变量对象类型置空并脱离链表,内存仍然存在选择线程类型时,需要同时考虑创建开销和运行期资源释放需求。调度启动状态管理实例思考线程创建单线程实例:LED周期闪烁30实例思考静态线程structrt_threadled_thread;rt_uint8_tLED_STACK[512];rt_thread_init(&led_thread,"LED",led_thread_entry,RT_NULL,LED_STACK,sizeof(LED_STACK),2,0);rt_thread_startup(&led_thread);动态线程rt_thread_tled;led=rt_thread_create("LED",led_thread_entry,RT_NULL,512,2,0);if(led!=RT_NULL)rt_thread_startup(led);线程主体中每200ms翻转一次LED,并调用rt_thread_mdelay(200)让出CPU。调度启动

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论