欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-02-22 18:44:58
...

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

一、新建LED底层

野火的bsp_led驱动。由于板子是原子的(我不是花心,我是成年人,小孩子才做选择,我都要)
Rt-Thread学习笔记-----线程创建(三)
所以更改相应配置(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
Rt-Thread学习笔记-----线程创建(三)
将其注释取消
Rt-Thread学习笔记-----线程创建(三)
再次编译。
Rt-Thread学习笔记-----线程创建(三)
下载验证。
Rt-Thread学习笔记-----线程创建(三)

三、创建多线程——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;
}


下载验证:
Rt-Thread学习笔记-----线程创建(三)

线程 2 计数到一定值会执行完毕,线程 2 被系统自动删除,计数停止。线程 1 一直打印计数
Rt-Thread学习笔记-----线程创建(三)

RTThread线程创建工程

相关标签: RTOS