基于 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;  // 清除事件