完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、线程
1.1 线程的概念 RT-Thread 的线程调度器是抢占式的,保证最高优先级的线程执行。有一下几种抢占的情形: 当一个线程使比它优先级高的线程满足条件,高优先级线程会立刻执行。 如果这个过程发生在中断中,中断结束后高优先级线程立刻执行。 1.2 关于线程的知识点 1.2.1 线程栈 当切换线程时,当前线程上下文会被保存在线程栈中,恢复运行时从线程栈恢复上下文。 线程栈大小确定方法:先分配1k,运行起来后通过finsh输入list_thread查看线程栈的深度,在此基础上加上余量确定线程栈的大小。 线程栈的增长方向:与芯片有关,在3.1.0之前的版本,只支持高地质向低地址增长。 1.2.2 线程状态 RT_THREAD_INIT:初始状态,线程刚创建时的状态。 RT_THREAD_READY:就绪态,当前线程运行完让出cpu时下一个就绪态的线程开始运行。 RT_THREAD_RUNNING:运行态,在单核系统中,rt_thread_self()函数查看当前运行的线程。 RT_THREAD_SUSPEND:挂起态,因为得不到资源或主动延时产生挂起(也称阻塞)。 RT_THREAD_CLOSE:结束态,线程结束。 1.2.3 线程优先级 rtthread最大支持256个线程(一般选择32个),数值越小,优先级越高,0为最高优先级,最低优先级分配给空闲线程。 1.2.4 时间片 仅对优先级相同的线程有用,用于限制线程的运行时长,单位是相同节拍。 1.2.5 入口函数 entry是线程的入口函数,是线程实现预期功能的函数,注意在无限循环线程中要有延时或挂起等操作来让出cpu使用权,否则低优先级的线程无法得到执行。 1.2.6 线程的错误码说明 #define RT_EOK 0 /* 无 错 误 */ #define RT_ERROR 1 /* 普 通 错 误 */ #define RT_EtiMEOUT 2 /* 超 时 错 误 */ #define RT_EFULL 3 /* 资 源 已 满 */ #define RT_EEMPTY 4 /* 无 资 源 */ #define RT_ENOMEM 5 /* 无 内 存 */ #define RT_ENOSYS 6 /* 系 统 不 支 持 */ #define RT_EBUSY 7 /* 系 统 忙 */ #define RT_EIO 8 /* IO 错 误 */ #define RT_EINTR 9 /* 中 断 系 统 调 用 */ #define RT_EINVAL 10 /* 非 法 参 数 */ 二、线程api //动态创建线程 /* name:线程名称 entry:入口函数 parameter:入口函数参数 stack_size:栈大小,单位:字节 priority:优先级 tick:时间片,单位:系统节拍 */ rt_thread_t rt_thread_create(const char* name, void (*entry)(void* parameter), void* parameter, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick); //删除动态创建的线程 /* thread:线程句柄 */ rt_err_t rt_thread_delete(rt_thread_t thread); //初始化线程 /* thread:线程结构体指针 name:线程名称 entry:入口函数 parameter:入口函数参数 stack_start:栈起始地址 stack_size:栈大小 priority:优先级 tick:时间片 */ rt_err_t rt_thread_init(struct rt_thread* thread const char* name, void (*entry)(void* parameter), void* parameter, void* stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick); //初始化出来的线程的脱离 /* thread:线程句柄 */ rt_err_t rt_thread_detach (rt_thread_t thread); //启动线程 /* thread:线程句柄 */ rt_err_t rt_thread_startup(rt_thread_t thread) //获取当前线程 /* 返回当前线程的句柄 */ rt_thread_t rt_thread_self(void); //让出资源 rt_err_t rt_thread_yield(void); //睡眠,可以让线程挂起指定的时间 /* tick:睡眠的时间 */ rt_err_t rt_thread_sleep(rt_tick_t tick); rt_err_t rt_thread_delay(rt_tick_t tick); rt_err_t rt_thread_mdelay(rt_int32_t ms); ` //线程挂起,不推荐使用 /* thread:线程句柄 */ rt_err_t rt_thread_suspend (rt_thread_t thread); //恢复线程 /* thread:线程句柄 */ rt_err_t rt_thread_resume (rt_thread_t thread); //控制线程 /* thread:线程句柄 cmd:控制命令 cmd支持的命令: RT_THREAD_CTRL_CHANGE_PRIORITY:更改线程优先级 RT_THREAD_CTRL_STARTUP:运行线程 RT_THREAD_CTRL_CLOSE:关闭线程 arg:控制参数 */ rt_err_t rt_thread_control(rt_thread_t thread, rt_uint8_t cmd, void* arg); 三、示例 /* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-08-24 yangjie the first version */ /* * 程序清单:创建、初始化/脱离线程 * * 这个例子会创建两个线程,一个动态线程,一个静态线程。 * 静态线程在运行完毕后自动被系统脱离,动态线程一直打印计数。 */ #include #define THREAD_PRIORITY 25 #define THREAD_STACK_SIZE 512 #define THREAD_TIMESLICE 5 static rt_thread_t tid1 = RT_NULL; /* 线程1的入口函数 */ static void thread1_entry(void *parameter) { rt_uint32_t count = 0; while (1) { /* 线程1采用低优先级运行,一直打印计数值 */ rt_kprintf("thread1 count: %dn", count ++); rt_thread_mdelay(500); } } ALIGN(RT_ALIGN_SIZE) static char thread2_stack[1024]; static struct rt_thread thread2; /* 线程2入口 */ static void thread2_entry(void *param) { rt_uint32_t count = 0; /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */ for (count = 0; count < 10 ; count++) { /* 线程2打印计数值 */ rt_kprintf("thread2 count: %dn", count); } rt_kprintf("thread2 exitn"); /* 线程2运行结束后也将自动被系统脱离 */ } /* 线程示例 */ int thread_sample(void) { /* 创建线程1,名称是thread1,入口是thread1_entry*/ tid1 = rt_thread_create("thread1", thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE); /* 如果获得线程控制块,启动这个线程 */ if (tid1 != RT_NULL) rt_thread_startup(tid1); /* 初始化线程2,名称是thread2,入口是thread2_entry */ rt_thread_init(&thread2, "thread2", thread2_entry, RT_NULL, &thread2_stack[0], sizeof(thread2_stack), THREAD_PRIORITY - 1, THREAD_TIMESLICE); rt_thread_startup(&thread2); return 0; } /* 导出到 msh 命令列表中 */ MSH_CMD_EXPORT(thread_sample, thread sample); |
|
相关推荐 |
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
590 浏览 0 评论
AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV
2241 浏览 0 评论
tms320280021 adc采样波形,为什么adc采样频率上来波形就不好了?
1233 浏览 0 评论
1788 浏览 0 评论
1464 浏览 0 评论
74803 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 19:45 , Processed in 0.681422 second(s), Total 70, Slave 53 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号