提示:针对不同的模块,调用时间间隔不同,合理利用系统资源。
关于裸机调度的时间片
main.c
typedef struct
{
uint8_t run; // 调度标志,1:调度,0:挂起
uint16_t timCount; // 时间片计数值
uint16_t timRload; // 时间片重载值
void (*pTaskFuncCb)(void); // 函数指针变量,用来保存业务功能模块函数地址
} TaskComps_t;
static TaskComps_t g_taskComps[] =
{
{0, 5, 5, HmiTask},
{0, 10, 10, WifiNetworkTask},
{0, 100, 100, SensorTask},
// {0, 1000, 1000, BatteryDrvTest},
{0, 1000, 1000, BatteryTask},
/* 添加业务功能模块 */
};
#define TASK_NUM_MAX (sizeof(g_taskComps) / sizeof(g_taskComps[0]))
static void TaskHandler(void)
{
for (uint8_t i = 0; i < TASK_NUM_MAX; i++)
{
if (g_taskComps[i].run) // 判断时间片标志
{
g_taskComps[i].run = 0; // 标志清零
g_taskComps[i].pTaskFuncCb(); // 执行调度业务功能模块
}
}
}
/**
***********************************************************
* @brief 在定时器中断服务函数中被间接调用,设置时间片标记,
需要定时器1ms产生1次中断
* @param
* @return
***********************************************************
*/
static void TaskScheduleCb(void)
{
for (uint8_t i = 0; i < TASK_NUM_MAX; i++)
{
if (g_taskComps[i].timCount)
{
g_taskComps[i].timCount--;
if (g_taskComps[i].timCount == 0)
{
g_taskComps[i].run = 1;
g_taskComps[i].timCount = g_taskComps[i].timRload;
}
}
}
}
static void DrvInit(void)
{
DelayInit();
LedDrvInit();
KeyDrvInit();
RtcDrvInit();
SystickInit();
WifiModuleDrvInit();
LcdDrvInit();
TempHumiDrvInit();
Pm25DrvInit();
BatteryDrvInit();
}
static void AppInit(void)
{
TaskScheduleCbReg(TaskScheduleCb);
}
int main(void)
{
DrvInit();
AppInit();
DelayNms(1000);
HmiTest();
// RtcTime_t rtcTime = {2024, 4, 15, 16, 25, 30};
// SetRtcTime(&rtcTime);
while (1)
{
TaskHandler();
}
}
systick.c
#include <stdint.h>
#include <stdlib.h>
#include "gd32f30x.h"
static volatile uint64_t g_sysRunTime = 0;
static void (*g_pTaskScheduleFunc)(void); // 函数指针变量,保存任务调度的函数地址
/**
***********************************************************
* @brief 注册任务调度回调函数
* @param pFunc, 传入回调函数地址
* @return
***********************************************************
*/
void TaskScheduleCbReg(void (*pFunc)(void))
{
g_pTaskScheduleFunc = pFunc;
}
/**
***********************************************************
* @brief systick初始化
* @param
* @return
***********************************************************
*/
void SystickInit(void)
{
/*1ms 产生一次定时中断*/
if (SysTick_Config(rcu_clock_freq_get(CK_AHB) / 1000))
{
while (1);
}
}
/**
***********************************************************
* @brief 定时中断服务函数,1ms产生一次中断
* @param
* @return
***********************************************************
*/
void SysTick_Handler(void)
{
g_sysRunTime++;
if (g_pTaskScheduleFunc == NULL)
{
return;
}
g_pTaskScheduleFunc();
}
/**
***********************************************************
* @brief 获取系统运行时间
* @param
* @return 以1ms为单位
***********************************************************
*/
uint64_t GetSysRunTime(void)
{
return g_sysRunTime;
}