RT-Thread之創建線程
一、靜態線程創建
1、thread_task.c文件
#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文件
#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文件
#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文件
#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()函數
extern void Task_Schedule(void);
void SysTick_Handler(void)
{
/* 進入中斷 */
rt_interrupt_enter();
/* 更新時基 */
rt_tick_increase();
/* 自定義調度函數 */
Task_Schedule();
/* 離開中斷 */
rt_interrupt_leave();
}
三、動態創建線程
1、thread_task.c文件
#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文件
#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 */
歡迎關注個人微信公眾號:比特向陽;
您也可以通過郵箱 lsk0358@163.com與我進行交流;

浙公網安備 33010602011771號