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 
 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学习笔记-----线程创建(三)_第1张图片
将其注释取消
在这里插入图片描述
再次编译。
Rt-Thread学习笔记-----线程创建(三)_第2张图片
下载验证。
Rt-Thread学习笔记-----线程创建(三)_第3张图片

三、创建多线程——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学习笔记-----线程创建(三)_第4张图片

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

RTThread线程创建工程

你可能感兴趣的:(RTOS)