Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
学习笔记
【rthread学习笔记系列】第零篇:线程
发布于 2021-05-11 15:00:38 浏览:4835
订阅该版
[tocm] # 一、线程 ## 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: %d\n", 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: %d\n", count); } rt_kprintf("thread2 exit\n"); /* 线程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); ```
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
happycode999
这家伙很懒,什么也没写!
文章
28
回答
6
被采纳
0
关注TA
发私信
相关文章
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
10
个答案
3
次被采纳
xiaorui
3
个答案
2
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
8
个答案
1
次被采纳
KunYi
8
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
9
次点赞
swet123
1
篇文章
4
次点赞
Days
1
篇文章
4
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部