Rt-Thread学习笔记-----线程创建(三)

经过之前的RtThread的移植,我们接下来进行简单地线程创建。从点灯开始吧。
RtThread的API参考书册

一、新建LED底层

野火的bsp_led驱动。由于板子是原子的(我不是花心,我是成年人,小孩子才做选择,我都要)
在这里插入图片描述
所以更改相应配置(LED1/PE5、LED2/PB5)

二、创建单线程——SRAM静态内存

/*
*************************************************************************
*                               静态线程变量
*************************************************************************
*/
/* 定义线程控制块 */
static struct rt_thread led1_thread;

/* 定义线程控栈时要求RT_ALIGN_SIZE个字节对齐 */
ALIGN(RT_ALIGN_SIZE)
/* 定义线程栈 */
static rt_uint8_t rt_led1_thread_stack[1024];

/*
*************************************************************************
*                             函数声明
*************************************************************************
*/
static void led1_thread_entry(void* parameter);


/* 线程示例 */
int Task_Init(void)
{
	
//静态线程
	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(&led1_thread);             /* 启动线程,开启调度 */	
	
	
									 
	return 0;
}

线程里面的延时函数必须使用 RT-Thread 里面提供的延时函数,并不能使用我们裸机编程中的那种延时。这两种的延时的区别是 RT-Thread 里面的延时是阻塞延时,即调用 rt_thread_delay()函数的时候,当前线程会被挂起,调度器会切换到其它就绪的线程,从而实现多线程。如果还是使用裸机编程中的那种延时,那么整个线程就成为了一个死循环,如果恰好该线程的优先级是最高的,那么系统永远都是在这个线程中运行,根本无法实现多线程。目前我们只创建了一个线程,当线程进入延时的时候,因为没有另外就绪的用户线程,那么系统就会进入空闲线程,空闲线程是 RT-Thread 系统自己启动的一个线程,优先级最低。当整个系统都没有就绪线程的时候,系统必须保证有一个线程在运行,空闲线程就是为这个设计的。当用户线程延时到期,又会从空闲线程切换回用户线程。

三、创建单线程——SRAM动态内存

/*
*************************************************************************
*                               动态态线程变量
*************************************************************************
#define THREAD_PRIORITY         25
#define THREAD_STACK_SIZE       512
#define THREAD_TIMESLICE        5
*/
/* 定义线程控制块 */
static rt_thread_t led1_thread_Dynamic = RT_NULL;

/* 线程示例 */
int Task_Init(void)
{
//动态线程
	 /* 创建线程 1,名称是 LED1,入口是 led1_thread_entry*/
	 led1_thread_Dynamic = 							/* 线程控制块指针 */
						rt_thread_create("LED1",	/* 线程名字 */
						led1_thread_entry,			/* 线程入口函数 */
						RT_NULL,					/* 线程入口函数参数 */
						THREAD_STACK_SIZE,			/* 线程栈大小 */
						THREAD_PRIORITY,			/* 线程的优先级 */
						THREAD_TIMESLICE			/* 线程时间片 */			
						);	
		/* 启动线程,开启调度 */
   if (led1_thread_Dynamic != RT_NULL){
		 rt_thread_startup(led1_thread_Dynamic);
		 rt_kprintf("动态内存创建成功\n\n");
	 }else{
			rt_kprintf("动态内存创建失败\n\n");
			return -1;
		}
return 0;
}	

/*
*************************************************************************
*                             线程定义
*************************************************************************
*/
static void led1_thread_entry(void* parameter)
{	
    while (1)
    {
#if 0
        LED1_ON;
        rt_thread_delay(500);   /* 延时500个tick */
        
        LED1_OFF;     
        rt_thread_delay(500);   /* 延时500个tick */		 		
#endif
			LedToggle(LED1_GPIO_PORT,LED1_GPIO_PIN);
			rt_thread_delay(500);
			rt_kprintf("LED1 IS OK\r\n");
    }
}												
											

main函数中代码

#include "board.h"
#include <string.h>
 int main(void)
 {	
	 
	Task_Init(); 
	rt_kprintf("\n\n"); 
	rt_kprintf("单线程动态内存\n\n");
	 
	 
  while(1)
	{
		LedToggle(LED2_GPIO_PORT,LED2_GPIO_PIN);
	  rt_thread_mdelay(1000);
		rt_kprintf("LED2 IS OK\n\n");
	}
 }

这个时候我们的单线程动态点灯线程创建完毕,编译一下。
Error: L6218E: Undefined symbol rt_thread_create (referred from task.o).*
what?咋有报错,查看头文件也添加了,路径也添加了怎么还报错?难道是keil的bug。清理编译文件,重新打开再次编译。好吧真的是错了。为什么呢?
原来在rtconfig.h中我们没有把相应宏定义打开

解决方法:
找到rtconfig.h内核配置文件 ——> #define RT_USING_HEAP
在这里插入图片描述
将其注释取消
在这里插入图片描述
再次编译。
在这里插入图片描述
下载验证。
在这里插入图片描述

三、创建多线程——SRAM静态、动态内存

创建一个动态线程初始化一个静态线程,一个线程在运行完毕后自动被系统删除,另一个线程一直打印计数

/*
*************************************************************************
*                               多线程---动态、静态
*************************************************************************
*/
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 Task_Init(void)
{
//动态线程
	 /* 创建线程 1,名称是 LED1,入口是 led1_thread_entry*/
	 led1_thread_Dynamic = 							/* 线程控制块指针 */
						rt_thread_create("LED1",	/* 线程名字 */
						led1_thread_entry,			/* 线程入口函数 */
						RT_NULL,					/* 线程入口函数参数 */
						THREAD_STACK_SIZE,			/* 线程栈大小 */
						THREAD_PRIORITY,			/* 线程的优先级 */
						THREAD_TIMESLICE			/* 线程时间片 */			
						);									 
#if 1									 
	/* 启动线程,开启调度 */
   if (led1_thread_Dynamic != RT_NULL){
		 rt_thread_startup(led1_thread_Dynamic);
		 rt_kprintf("单线程--动态内存创建成功\n\n");
	 }else{
			rt_kprintf("单线程--动态内存创建失败\n\n");
			return -1;
		}
#endif									 									 
//--------------------------------------------------
    /* 创建线程 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);
			rt_kprintf("多线程--动态内存创建成功\n\n");
		}else{
			rt_kprintf("多线程--动态内存创建失败\n\n");
			return -1;			
		}
        								 
    /* 初始化线程 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);	
		rt_kprintf("多线程--静态内存创建成功\n\n");									 
//---------------------------------------------------									 

		
	return 0;
}


下载验证:
在这里插入图片描述

线程 2 计数到一定值会执行完毕,线程 2 被系统自动删除,计数停止。线程 1 一直打印计数
在这里插入图片描述

RTThread线程创建工程

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
RT-Thread 是一个实时操作系统,支持多线程操作。线程RT-Thread 中的基本执行单元,可以通过 RT-Thread 的 API 来创建和管理线程RT-Thread 线程创建 API 主要有以下几个: 1. rt_thread_t rt_thread_create(const char *name, void (*entry)(void *parameter), void *parameter, size_t stack_size, rt_uint8_t priority, rt_uint32_t tick); 该函数用于创建一个线程,参数如下: - name:线程的名称(必填)。 - entry:线程的入口函数(必填)。 - parameter:传递给线程入口函数的参数。 - stack_size:线程栈的大小,以字节为单位。 - priority:线程的优先级,取值范围是 0~31,数值越小优先级越高。 - tick:线程的时间片长度,以系统时钟节拍为单位。 2. void rt_thread_startup(rt_thread_t thread); 该函数用于启动一个线程,参数是线程句柄。 3. rt_thread_t rt_thread_self(void); 该函数返回当前线程的句柄。 4. rt_err_t rt_thread_delete(rt_thread_t thread); 该函数用于删除一个线程,参数是线程句柄。 5. rt_err_t rt_thread_yield(void); 该函数用于让出当前线程的时间片,让其他线程执行。 6. rt_err_t rt_thread_suspend(rt_thread_t thread); 该函数用于挂起一个线程,使其暂停执行。 7. rt_err_t rt_thread_resume(rt_thread_t thread); 该函数用于恢复一个被挂起的线程,使其继续执行。 以上是 RT-Thread 线程创建的几个基本 API,可以根据实际需求选择使用。需要注意的是,线程的优先级和时间片长度是影响线程执行顺序的重要因素,需要根据实际情况进行设置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Terry.Z_1009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值