RT-Thread之创建线程

7.4k words

一、静态线程创建

1、thread_task.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "thread_task.h"
#include "main.h"
#include <stdio.h>
#include "rtthread.h"

/******************************************** 线程 1 ******************************************************/
#define THREAD_1_PRIORITY 5 /* 进程优先级 */
#define THREAD_1_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_1_TIMESLICE 1 /* 进程执行时间片个数 */
static char thread_1_stack[THREAD_1_STACK_SIZE]; /* 进程栈 */
static struct rt_thread thread_1_handle; /* 进程句柄 */

/******************************************** 线程 2 ******************************************************/
#define THREAD_2_PRIORITY 5 /* 进程优先级 */
#define THREAD_2_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_2_TIMESLICE 1 /* 进程执行时间片个数 */
static char thread_2_stack[THREAD_1_STACK_SIZE]; /* 进程栈 */
static struct rt_thread thread_2_handle; /* 进程句柄 */

uint8_t count_1 = 0;
uint8_t count_2 = 0;


/**
* @brief 线程1入口函数
* @param 无
* @retval 无
*/
void thread_1_entry(void* param)
{
while(1)
{
rt_tick_t now_tick = rt_tick_get(); /* 获取当前时间 */

HAL_GPIO_TogglePin(GPIOC, LED1_Pin);


rt_thread_delay_until(&now_tick, 1000); /* 精准延时1000时间片 */
}
}

/**
* @brief 线程2入口函数
* @param 无
* @retval 无
*/
void thread_2_entry(void* param)
{
while(1)
{
rt_tick_t now_tick = rt_tick_get(); /* 获取当前时间 */

HAL_GPIO_TogglePin(GPIOC, LED2_Pin);

rt_thread_delay_until(&now_tick, 1000); /* 精准延时1000时间片 */
}

}

/**
* @brief 创建线程任务并启动
* @param 无
* @retval 无
*/
void ThreadStart(void)
{
/* 初始化静态线程*/
rt_thread_init(
&thread_1_handle, /* 线程句柄*/
"thread_1", /* 线程句柄名称*/
thread_1_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
&thread_1_stack[0], /* 线程栈地址 */
THREAD_1_STACK_SIZE, /* 线程栈大小 */
THREAD_1_PRIORITY, /* 线程优先级 */
THREAD_1_TIMESLICE); /* 线程时间片大小 */

rt_thread_startup(&thread_1_handle); /* 启动线程 */

/* 初始化静态线程*/
rt_thread_init(
&thread_2_handle, /* 线程句柄*/
"thread_2", /* 线程句柄名称*/
thread_2_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
&thread_2_stack[0], /* 线程栈地址 */
THREAD_2_STACK_SIZE, /* 线程栈大小 */
THREAD_2_PRIORITY, /* 线程优先级 */
THREAD_2_TIMESLICE); /* 线程时间片大小 */

rt_thread_startup(&thread_2_handle); /* 启动线程 */
}

2、thread_task.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef __THREAD_TASK_H
#define __THREAD_TASK_H

#ifdef __cplusplus
extern "C" {
#endif

void ThreadStart(void);

#ifdef __cplusplus
}
#endif

#endif /* __THREAD_TASK_H */

二、静态创建线程(自定义实现调度)

1、thread_task.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "thread_task.h"
#include "main.h"
#include <stdio.h>
#include "rtthread.h"

/******************************************** 线程 1 ******************************************************/
#define THREAD_1_CYCLE 1000 /* 进程执行周期 */
#define THREAD_1_PRIORITY 5 /* 进程优先级 */
#define THREAD_1_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_1_TIMESLICE 1 /* 进程执行时间片个数 */
static char thread_1_stack[THREAD_1_STACK_SIZE]; /* 进程栈 */
static struct rt_thread thread_1_handle; /* 进程句柄 */

/******************************************** 线程 2 ******************************************************/
#define THREAD_2_CYCLE 1000 /* 进程执行周期 */
#define THREAD_2_PRIORITY 5 /* 进程优先级 */
#define THREAD_2_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_2_TIMESLICE 1 /* 进程执行时间片个数 */
static char thread_2_stack[THREAD_1_STACK_SIZE]; /* 进程栈 */
static struct rt_thread thread_2_handle; /* 进程句柄 */

uint8_t count_1 = 0;
uint8_t count_2 = 0;

/**
* @brief 线程1入口函数
* @param 无
* @retval 无
*/
void thread_1_entry(void* param)
{
while(1)
{
HAL_GPIO_TogglePin(GPIOC, LED1_Pin);

rt_thread_suspend(&thread_1_handle); //挂起线程
rt_schedule(); //启动调度器
}
}

/**
* @brief 线程2入口函数
* @param 无
* @retval 无
*/
void thread_2_entry(void* param)
{
while(1)
{
HAL_GPIO_TogglePin(GPIOC, LED2_Pin);

rt_thread_suspend(&thread_2_handle); //挂起线程
rt_schedule(); //启动调度器
}

}

/**
* @brief 创建线程任务并启动
* @param 无
* @retval 无
*/
void ThreadStart(void)
{
/* 初始化静态线程*/
rt_thread_init(
&thread_1_handle, /* 线程句柄*/
"thread_1", /* 线程句柄名称*/
thread_1_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
&thread_1_stack[0], /* 线程栈其实地址 */
THREAD_1_STACK_SIZE, /* 线程栈大小 */
THREAD_1_PRIORITY, /* 线程优先级 */
THREAD_1_TIMESLICE); /* 线程时间片大小 */

rt_thread_startup(&thread_1_handle); /* 启动线程 */

/* 初始化静态线程*/
rt_thread_init(
&thread_2_handle, /* 线程句柄*/
"thread_2", /* 线程句柄名称*/
thread_2_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
&thread_2_stack[0], /* 线程栈其实地址 */
THREAD_2_STACK_SIZE, /* 线程栈大小 */
THREAD_2_PRIORITY, /* 线程优先级 */
THREAD_2_TIMESLICE); /* 线程时间片大小 */

rt_thread_startup(&thread_2_handle); /* 启动线程 */
}

/*任务调度*/
void Task_Schedule(void)
{
static uint32_t task_count = 0;

if(task_count%1000 == 0) rt_thread_resume(&thread_1_handle);
if(task_count%2000 == 0) rt_thread_resume(&thread_2_handle);

rt_schedule();
task_count++;
//计数值达到一定值后清零,防止任务调度错乱
if(task_count == 200000) task_count = 0;
}

2、thread_task.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef __THREAD_TASK_H
#define __THREAD_TASK_H

#ifdef __cplusplus
extern "C" {
#endif

void ThreadStart(void);
void Task_Schedule(void);

#ifdef __cplusplus
}
#endif

#endif /* __THREAD_TASK_H */

2、修改board.c中的SysTick_Handler()函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
extern void Task_Schedule(void);

void SysTick_Handler(void)
{
/* 进入中断 */
rt_interrupt_enter();

/* 更新时基 */
rt_tick_increase();
/* 自定义调度函数 */
Task_Schedule();

/* 离开中断 */
rt_interrupt_leave();
}

三、动态创建线程

1、thread_task.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "thread_task.h"
#include "main.h"
#include <stdio.h>
#include "rtthread.h"

/******************************************** 线程 1 ******************************************************/
#define THREAD_1_PRIORITY 5 /* 进程优先级 */
#define THREAD_1_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_1_TIMESLICE 1 /* 进程执行时间片个数 */
static struct rt_thread *thread_1_handle; /* 进程句柄 */

/******************************************** 线程 2 ******************************************************/
#define THREAD_2_PRIORITY 5 /* 进程优先级 */
#define THREAD_2_STACK_SIZE 512 /* 进程栈空间大小 */
#define THREAD_2_TIMESLICE 1 /* 进程执行时间片个数 */
static struct rt_thread *thread_2_handle; /* 进程句柄 */



/**
* @brief 线程1入口函数
* @param 无
* @retval 无
*/
void thread_1_entry(void* param)
{
while(1)
{
rt_tick_t now_tick = rt_tick_get(); /* 获取当前时间 */

HAL_GPIO_TogglePin(GPIOC, LED1_Pin);

rt_thread_delay_until(&now_tick, 1000); /* 精准延时1000时间片 */
}
}

/**
* @brief 线程2入口函数
* @param 无
* @retval 无
*/
void thread_2_entry(void* param)
{
while(1)
{
rt_tick_t now_tick = rt_tick_get(); /* 获取当前时间 */

HAL_GPIO_TogglePin(GPIOC, LED2_Pin);

rt_thread_delay_until(&now_tick, 1000); /* 精准延时1000时间片 */
}

}

/**
* @brief 动态创建线程任务并启动
* @param 无
* @retval 无
*/
void ThreadStart(void)
{
/* 动态创建线程 */
thread_1_handle = rt_thread_create(
"thread_1", /* 线程句柄名称*/
thread_1_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
THREAD_1_STACK_SIZE, /* 线程栈大小 */
THREAD_1_PRIORITY, /* 线程优先级 */
THREAD_1_TIMESLICE /* 线程时间片大小 */
);


rt_thread_startup(thread_1_handle); /* 启动线程 */

thread_2_handle = rt_thread_create(
"thread_2", /* 线程句柄名称*/
thread_2_entry, /* 函数入口 */
RT_NULL, /* 入口函数参数 */
THREAD_2_STACK_SIZE, /* 线程栈大小 */
THREAD_2_PRIORITY, /* 线程优先级 */
THREAD_2_TIMESLICE /* 线程时间片大小 */
);

rt_thread_startup(thread_2_handle); /* 启动线程 */
}

2、thread_task.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef __THREAD_TASK_H
#define __THREAD_TASK_H

#ifdef __cplusplus
extern "C" {
#endif

void ThreadStart(void);
void Task_Schedule(void);

#ifdef __cplusplus
}
#endif

#endif /* __THREAD_TASK_H */