基于STM32的虚拟多线程,可以很好的用于裸机程序中,用于模拟小型操作系统的多线程概念。本实例参考了参考TI_BLE协议栈_ZStack协议栈。
#include "Hal_Led/Hal_Led.h"
#include "Hal_delay/delay.h"
#include "Hal_Key/Hal_Key.h"
#include "ringbuffer.h"
#define APP_LED2_BLINK_EVENT 0x0001
#define HAL_LED1_BLINK_EVENT 0x0001
#define TASK_NO_TASK_RUNNING 0xFF
unsigned short Hal_ProcessEvent( unsigned char task_id, unsigned short events );
unsigned short App_ProcessEvent( unsigned char task_id, unsigned short events );
typedef unsigned short uint16;
typedef unsigned char uint8;
#define TASK_CNT 2 //定义线程的个数
//定义函数指针
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short events );
//线程函数表
const pTaskEventHandlerFn tasksArr[] =
{
Hal_ProcessEvent,
App_ProcessEvent
};
const unsigned char tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
//uint16 *tasksEvents;
uint16 tasksEvents[TASK_CNT] = {0}; //每个线程有16位位域空间用于设置事件
static uint8 activeTaskID = 0xFF; //当前任务ID,指示作用
#define SUCCESS 0x00
#define FAILURE 0x01
#define INVALID_TASK 0x02
uint8 osal_set_event( uint8 task_id, uint16 event_flag )
{
if ( task_id < tasksCnt )
{
tasksEvents[task_id] |= event_flag; // Stuff the event bit(s)
return ( SUCCESS );
}
else
{
return ( INVALID_TASK );
}
}
/**
* @brief 程序入口
* @param none
* @return none
*/
int main(void)
{
unsigned short taskID = 0;
uint8 idx = 0;
SystemInit(); //系统时钟初始化
delayInit(72); //滴答定时器初始化
Led_Init(); //LED初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
osal_set_event(0, HAL_LED1_BLINK_EVENT);
osal_set_event(1, APP_LED2_BLINK_EVENT);
while(1)
{
do
{
if(tasksEvents[idx]) //轮训获知哪个线程有事件需要进行处理
{
break;
}
}
while (++idx < tasksCnt);
if (idx < tasksCnt)
{
uint16 events;
events = tasksEvents[idx];
tasksEvents[idx] = 0; // 清除事件数组中的事件
activeTaskID = idx;
events = (tasksArr[idx])( idx, events ); //调用线程函数
activeTaskID = TASK_NO_TASK_RUNNING;
tasksEvents[idx] |= events; // 添加未处理的事件到本线程的事件组中
}
delayMs(1000);
}
}
/**
* @brief 应用层处理
* @param none
* @r
*/
unsigned short Hal_ProcessEvent( unsigned char task_id, unsigned short events )
{
if ( events & HAL_LED1_BLINK_EVENT )
{
Led_Reverse(1);
return events ^ HAL_LED1_BLINK_EVENT; //清除事件
}
}
/**
* @brief 硬件控制线程
* @param none
* @r
*/
unsigned short App_ProcessEvent( unsigned char task_id, unsigned short events )
{
if ( events & APP_LED2_BLINK_EVENT )
{
Led_Reverse(2);
return events ^ APP_LED2_BLINK_EVENT; //清除事件