RT-Thread—创建线程的俩种方式

文章目录

  • 概述
  • 静态创建
    • 定义线程栈
    • 定义线程函数
    • 定义线程控制块
    • 初始化线程
    • 启动线程函数
  • 动态创建

概述

创建线程三要素:
1.线程栈
2.线程控制块
3.线程主体函数

在RTT中线程的创建方式有俩种:

  • 静态创建
  • 动态创建

从字面意思上还是比较好理解俩种方法的,静态创建就是提前申请好一点的空间,动态创建就是根据所需空间大小自动分配空间。

静态创建

所谓静态创建,就是在SRAM中提前给线程划分一部分内存空间,与线程有关的所有内存都在那一块内存空间中。此处模拟创建一个线程点亮led。

定义线程栈

RTT中,每一个线程都是独立的,所以每一个线程都有其单独的运行环境,线程的运行环境都保存在其栈空间中。线程的栈占用的是MCU内部的RAM,所以一款MCU能支持多少线程,就看其RAM有多大了。
定义线程栈的函数如下:

/* 栈空间地址对齐 */
ALIGN( RT_ALIGN_SIZE )
/* 定义一个数组,栈的空间大小就是1024*8字节 */
static rt_uint8_t rt_led_thread_stack[1024];

定义线程函数

线程实际上就是一个无限循环且不带返回值的C函数,所以定义线程函数如下:

static void led_thread_entry( void *parameter )
{
	LED_ON;
	rt_thread_delay( 500 );

	LED_OFF;
	rt_thread_delay( 500 );
}

线程函数让LED以500个tick为间隔闪烁。

定义线程控制块

线程控制块就像线程的身份证,里面包含了线程的所有信息。

static struct rt_thread led_thread

初始化线程

线程的三要素:线程栈、线程函数、线程控制块,是通过线程初始化函数联系到一起的,通过初始化线程函数后,线程可以被系统启动。(初始化后,线程就处于就绪态)

rt_thread_init(&led1_thread, /* 线程控制块 */ 
 "led1", /* 线程名字 */ 
 led1_thread_entry, /* 线程入口函数 */ 
 RT_NULL, /* 线程入口函数参数 */ 
 &rt_led1_thread_stack[0], /* 线程栈起始地址 */ 
 sizeof(rt_led1_thread_stack), /* 线程栈大小 */ 
 3, /* 线程的优先级 */ 
 20); /* 线程时间片 */

启动线程函数

rt_thread_startup(&led_thread);

通过rt_thread_startup()函数来启动线程

动态创建

在静态创建线程时,线程控制块和线程栈的内存空间都是从内部SRAM里面分配的,具体分配到哪个地址由编译器决定,动态创建时使用的是动态内存——堆,堆也属于SRAM,可以在SRAM中定义一个大数组供RTT的动态内存分配函数使用。

使用动态内存时,线程栈在线程创建的时候创建,也就是线程栈是根据创建线程的大小来给定的,线程创建函数会返回一个指针,指向该线程的线程控制块,所以要预先定义一个线程控制块指针。

/* 定义线程控制块指针 */
static rt_thread_t led_thread = RT_NULL;

动态创建线程时用的是rt_thread_create()函数,会返回一个线程控制块指针。

二者在main函数中:

int main(void)
{	
	
/**************************** 静态创建 **************************************/	
    ///* 线程初始化函数,将线程栈空间、线程函数、线程控制块 三者联系在一起 */
rt_thread_init( &led1_thread,  //线程控制块指针
                "led1",
								led1_thread_entry,
								RT_NULL,
								&rt_led1_thread_stack[0],//静态创建线程时需要线程栈的起始地址,动态创建时会根据提供的线程栈大小自动创建
								sizeof( rt_led1_thread_stack ),
								3,//0的优先级最高
								20//当有相同优先级的俩个线程时,它们的运行时间由时间片的大小决定
								);

								
						
/* 启动线程,开始调度 */
/* 在这之前线程还处于初始态,需要将线程转换为 就绪态 才可以进行调度,通过rt_thread_startup()函数实现线程的就绪态转换 */
rt_thread_startup( &led1_thread );	
								
/***************************** 动态创建 ******************************************/
/* 利用rt_thread_create() 函数动态创建线程,会返回线程控制块指针 */
led1_thread = rt_thread_create( "led1",
								                led1_thread_entry,
								                RT_NULL,
								                512,
								                3,
								                20);								
								
if( led1_thread != RT_NULL )
	/* rt_thread_startup() 的形参是一个线程控制块指针,动态创建线程时返回的就是线程控制块指针,所以直接传入即可 */
	rt_thread_startup( led1_thread );
else
	return -1;


你可能感兴趣的:(RT-Thread)