diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day2/main.c" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day2/main.c" new file mode 100644 index 0000000000000000000000000000000000000000..e2e63c41ff77bf4f1e80e7be9c78e9b67e926aed --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day2/main.c" @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-06 Supperthomas first version + * 2023-12-03 Meco Man support nano version + */ + +#include +#include +#include +#ifndef RT_USING_NANO +#include +#endif /* RT_USING_NANO */ + +//----------优先级抢占&时间片轮转---------- +//线程入口函数 +void usr_thread1(void* para) +{ + rt_uint32_t count = 0; + + for (count = 0; count < 10 ; count++) + { + rt_kprintf("thread1 count: %d\r\n", count); + } +} + +void usr_thread2(void* para) +{ + while(1) + { + rt_kprintf("run in usr thread2\r\n"); + rt_thread_mdelay(500); + } +} + +void usr_thread3(void* para) +{ + while(1) + { + rt_kprintf("run in usr thread3\r\n"); + rt_thread_mdelay(500); + } +} + +rt_thread_t tid1 = RT_NULL; +rt_thread_t tid2 = RT_NULL; +rt_thread_t tid3 = RT_NULL; + +int main(void) +{ + //创建线程 + tid1 = rt_thread_create("usr1", usr_thread1, RT_NULL, 1024, 11, 5); + + if(tid1 != RT_NULL) + { + rt_thread_startup(tid1); + } + + tid2 = rt_thread_create("usr2", usr_thread2, RT_NULL, 1024, 12, 5); + + if(tid2 != RT_NULL) + { + rt_thread_startup(tid2); + } + + tid3 = rt_thread_create("usr3", usr_thread3, RT_NULL, 1024, 12, 5); + + if(tid3 != RT_NULL) + { + rt_thread_startup(tid3); + } + + rt_kprintf("run in main thread\r\n"); + return RT_EOK; +} diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202254104.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202254104.png" new file mode 100644 index 0000000000000000000000000000000000000000..ee8d4ec191d6765790efaf42f7bb489677ab0426 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202254104.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202546882.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202546882.png" new file mode 100644 index 0000000000000000000000000000000000000000..f36a9a8f4a88721b8f5ea1de9a8ca5d696c3af76 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722202546882.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722204307831.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722204307831.png" new file mode 100644 index 0000000000000000000000000000000000000000..80464454ca107223c40bdf95e14df3a1233325ea Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722204307831.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722211750896.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722211750896.png" new file mode 100644 index 0000000000000000000000000000000000000000..d56796850c12c90686377682693392aa2060ea47 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722211750896.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722212046379.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722212046379.png" new file mode 100644 index 0000000000000000000000000000000000000000..8bbc46ad95b6a027cb8889c8055b0db84fbd853b Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250722212046379.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723093753523.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723093753523.png" new file mode 100644 index 0000000000000000000000000000000000000000..26080a18fcad62c473dfb43767e8ab38dbd86914 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723093753523.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723100539985.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723100539985.png" new file mode 100644 index 0000000000000000000000000000000000000000..5759db499b1c39ddcb51491b4d6e5247452e1c25 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723100539985.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723101341265.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723101341265.png" new file mode 100644 index 0000000000000000000000000000000000000000..746274fc4015d765411a51f8ed783e51fbf1e573 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723101341265.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103101245.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103101245.png" new file mode 100644 index 0000000000000000000000000000000000000000..9254fad0cdc0987f9e2910ec6051b2431811cb6d Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103101245.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103318506.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103318506.png" new file mode 100644 index 0000000000000000000000000000000000000000..cc4a084a7790bf81087228350389ebe28aaebeb4 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723103318506.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723112155294.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723112155294.png" new file mode 100644 index 0000000000000000000000000000000000000000..f50be322f589ed3a9b88c9140d539f20cc352a99 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723112155294.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141647899.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141647899.png" new file mode 100644 index 0000000000000000000000000000000000000000..b2cf36a5a116e0f785fd62319bdb8474799f3f38 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141647899.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141753116.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141753116.png" new file mode 100644 index 0000000000000000000000000000000000000000..e0560a55276258d4211d9818d0ad60a4ae1e4d0a Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141753116.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141842774.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141842774.png" new file mode 100644 index 0000000000000000000000000000000000000000..bd6863fc22b570cf4ba645ddb8deb9c6fdf710d2 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723141842774.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723154235955.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723154235955.png" new file mode 100644 index 0000000000000000000000000000000000000000..e7ae6888045fbd39c0eb5a3ed66a0a14625f969e Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723154235955.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723200216270.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723200216270.png" new file mode 100644 index 0000000000000000000000000000000000000000..d5d8daf949aa99ded2690d9e225f05efcf8a24e1 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723200216270.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723202054892.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723202054892.png" new file mode 100644 index 0000000000000000000000000000000000000000..ccb8d275f7654ddb9d2a2e0dda9923f0980cf470 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250723202054892.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/\347\272\277\347\250\213\345\210\233\345\273\272\345\222\214\347\256\241\347\220\206.md" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/\347\272\277\347\250\213\345\210\233\345\273\272\345\222\214\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..bedc5c47ef1eb02c08ced3afdbc9a1854bc34b02 --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/\347\272\277\347\250\213\345\210\233\345\273\272\345\222\214\347\256\241\347\220\206.md" @@ -0,0 +1,255 @@ +# 线程创建和管理 + +## 准备工作 + +下载RT-Thread Studio:https://www.rt-thread.org/download.html#download-rt-thread-studio + +也可以通过打包好的文件打开Code和ConEmu: + +![image-20250722202546882](./image/image-20250722202546882.png) + +* scons -j8编译,编译完成后如下图所示: + +![image-20250722204307831](./image/image-20250722204307831.png) + +## RT-Thread启动流程 + +rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺序是:系统先从启动文件开始运行,然后进入 RT-Thread 的启动函数 rtthread_startup() ,最后进入用户入口函数 main(),如下图所示: + +![启动流程](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/basic/figures/rtt_startup.png) + +按照下图示例找到启动文件: + +![image-20250722212046379](./image/image-20250722212046379.png) + +## 线程管理 + +在 RT-Thread 中,线程是实现任务的载体,它是 RT-Thread 中最基本的调度单位,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级,重要的任务可设置相对较高的优先级,非重要的任务可以设置较低的优先级,不同的任务还可以设置相同的优先级,轮流运行。 + +当线程运行时,它会认为自己是以独占 CPU 的方式在运行,线程执行时的运行环境称为上下文,具体来说就是各个变量和数据,包括所有的寄存器变量、堆栈、内存信息等。 + +### 线程管理的功能特点 + +![对象容器与线程对象](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/thread/figures/04Object_container.png) + +RT-Thread 的线程调度器是抢占式的,主要的工作就是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到 CPU 的使用权。 + +当一个运行着的线程使一个比它优先级高的线程满足运行条件,当前线程的 CPU 使用权就被剥夺了,或者说被让出了,高优先级的线程立刻得到了 CPU 的使用权。 + +如果是中断服务程序使一个高优先级的线程满足运行条件,中断完成时,被中断的线程挂起,优先级高的线程开始运行。 + +当调度器调度线程切换时,先将当前线程上下文保存起来,当再切回到这个线程时,线程调度器将该线程的上下文信息恢复。 + +### 线程优先级 + +RT-Thread 线程的优先级是表示线程被调度的优先程度。每个线程都具有优先级,线程越重要,赋予的优先级就应越高,线程被调度的可能才会越大。 + +RT-Thread 最大支持 256 个线程优先级 (0~255),数值越小的优先级越高,0 为最高优先级。在一些资源比较紧张的系统中,可以根据实际情况选择只支持 8 个或 32 个优先级的系统配置;对于 ARM Cortex-M 系列,普遍采用 32 个优先级。最低优先级默认分配给空闲线程使用,用户一般不使用。在系统中,当有比当前线程优先级更高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处理器运行。 + +### 线程的入口函数 + +* **无限循环模式:** + +在实时系统中,线程通常是被动式的:这个是由实时系统的特性所决定的,实时系统通常总是等待外界事件的发生,而后进行相应的服务: + +```C +void thread_entry(void* paramenter) +{ + while (1) + { + /* 等待事件的发生 */ + + /* 对事件进行服务、进行处理 */ + } +} +``` + +线程看似没有什么限制程序执行的因素,似乎所有的操作都可以执行。但是作为一个实时系统,一个优先级明确的实时系统,如果一个线程中的程序陷入了死循环操作,那么比它优先级低的线程都将不能够得到执行。 + +所以在实时操作系统中必须注意的一点就是:**线程中不能陷入死循环操作,必须要有让出 CPU 使用权的动作,如循环中调用延时函数或者主动挂起。** + +* **顺序执行或有限次循环模式:** + +如简单的顺序语句、do while() 或 for()循环等,此类线程不会循环或不会永久循环,可谓是 “一次性” 线程,一定会被执行完毕。在执行完毕后,线程将被系统自动删除。 + +```C +static void thread_entry(void* parameter) +{ + /* 处理事务 #1 */ + … + /* 处理事务 #2 */ + … + /* 处理事务 #3 */ +} +``` + +### 线程状态切换 + +RT-Thread 提供一系列的操作系统调用接口,使得线程的状态在这五个状态之间来回切换。几种状态间的转换关系如下图所示: + +![线程状态转换图](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/thread/figures/04thread_sta.png) + +### 主线程 + +在系统启动时,系统会创建 main 线程,它的入口函数为 main_thread_entry(),用户的应用入口函数 main() 就是从这里真正开始的,系统调度器启动后,main 线程就开始运行,过程如下图,用户可以在 main() 函数里添加自己的应用程序初始化代码。 + +![主线程调用过程](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/thread/figures/04main_thread.png) + +### 线程管理方式 + +下图描述了线程的相关操作,包含:创建 / 初始化线程、启动线程、运行线程、删除 / 脱离线程。可以使用 rt_thread_create() 创建一个动态线程,使用 rt_thread_init() 初始化一个静态线程,动态线程与静态线程的区别是:动态线程是系统自动从动态内存堆上分配栈空间与线程句柄(初始化 heap 之后才能使用 create 创建动态线程),静态线程是由用户分配栈空间与线程句柄。 + +![线程相关操作](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/thread/figures/04thread_ops.png) + +## 创建线程示例 + +按下图路径查看RT-Thread 操作系统中的线程创建示例函数: + +![image-20250723093753523](./image/image-20250723093753523.png) + +### 动态创建线程1 + +```C +tid1 = rt_thread_create("thread1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY, THREAD_TIMESLICE); +``` + +线程入口函数: `thread1_entry`,按住Ctrl点击入口函数名跳转到定义 + +![image-20250723103101245](./image/image-20250723103101245.png) + +### 静态创建线程2 + +```C +rt_thread_init(&thread2, + "thread2", + thread2_entry, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); +``` + +线程入口函数: `thread2_entry`,按住Ctrl点击入口函数名跳转到定义 + +![image-20250723103318506](./image/image-20250723103318506.png) + + 因为`MSH_CMD_EXPORT` 将这个函数导出为 RT-Thread 的 msh(类似 shell)命令,所以用户可以在终端直接输入 `thread_sample` 来执行这个函数。 + +```C +/* export the msh command */ +MSH_CMD_EXPORT(thread_sample, thread sample); +``` + +在VsCode按F5调试,页面会自动跳转到主函数,点击全速运行。 + +![image-20250723100539985](./image/image-20250723100539985.png) + +在MobaXterm输入`thread_sample`查看调试信息,可以按Tab查看命令。 + +![image-20250723101341265](./image/image-20250723101341265.png) + +### 运行结果 + +1. 线程2先运行(优先级更高),打印0-9后退出 +2. 线程1持续运行,每隔500ms打印一个递增的计数 +3. 线程2退出后会被系统的空闲线程自动回收 + +## 调度器的工作 + +![image-20250723112155294](./image/image-20250723112155294.png) + +### 优先级抢占 + +![image-20250723141842774](./image/image-20250723141842774.png) + +#### 线程优先级抢占调度示例 + +我们在rtconfig.h中找到main的优先级`RT_MAIN_THREAD_PRIORITY` + +![image-20250723154235955](./image/image-20250723154235955.png) + +将新创建的线程优先级设置为`RT_MAIN_THREAD_PRIORITY - 1` + +```C +//线程入口函数 +void usr_thread(void* para) +{ + while(1) + { + rt_kprintf("run in usr thread\r\n"); + rt_thread_delay(5); + } +} +rt_thread_t tid = RT_NULL; +int main(void) +{ + //创建线程 + tid = rt_thread_create("usr", usr_thread, RT_NULL, 1024, RT_MAIN_THREAD_PRIORITY - 1, 5); + + if(tid != RT_NULL) + { + rt_thread_startup(tid); + } + + rt_kprintf("run in main thread\r\n"); + return RT_EOK; +} +``` + +保存代码,在Cmd编译后回到Code按F5调试,打开MobaXterm查看调试信息。 + +![image-20250723200216270](./image/image-20250723200216270.png) + +### 时间片轮转 + +![image-20250723141647899](./image/image-20250723141647899.png) + +#### 线程时间片轮转调度示例 + +```C +//线程入口函数 +void usr_thread1(void* para) +{ + while(1) + { + rt_kprintf("run in usr thread1\r\n"); + } +} + +void usr_thread2(void* para) +{ + while(1) + { + rt_kprintf("run in usr thread2\r\n"); + } +} + +rt_thread_t tid1 = RT_NULL; +rt_thread_t tid2 = RT_NULL; + +int main(void) +{ + //创建线程 + tid1 = rt_thread_create("usr1", usr_thread1, RT_NULL, 1024, 11, 5); + + if(tid1 != RT_NULL) + { + rt_thread_startup(tid1); + } + + tid2 = rt_thread_create("usr2", usr_thread2, RT_NULL, 1024, 11, 5); + + if(tid2 != RT_NULL) + { + rt_thread_startup(tid2); + } + + rt_kprintf("run in main thread\r\n"); + return RT_EOK; +} +``` + +![image-20250723202054892](./image/image-20250723202054892.png) \ No newline at end of file