149 lines
4.8 KiB
C
149 lines
4.8 KiB
C
/*
|
||
* timeSliceOffset.c
|
||
*
|
||
* Created on: 2024年6月22日
|
||
* Author: psx
|
||
*/
|
||
|
||
#include "TimeSliceOffset.h"
|
||
|
||
|
||
static STR_TimeSliceOffset* pTimeSliceList = NULL; /**< 时间片链表入口(仅入口,最终直接指向设备实体,所需无需申请空间。链表是单向线性链表) */
|
||
|
||
|
||
/**
|
||
* @brief 注册
|
||
* @param[in] pTSlice 时间片对象指针
|
||
* @param[in] taskFunc 任务函数的函数指针
|
||
* @param[in] reloadVal 时间片重载值*tick基准即为任务执行间隔
|
||
* @param[in] offset 偏移量,这是错位的精髓
|
||
* @return 配置是否成功
|
||
* - 0 注册成功
|
||
* - 1 配置完成,但对象已存在,无需加入链表
|
||
* - -1 pTSlice为空指针,无效对象
|
||
* @par 注意事项:
|
||
* - reloadVal设置为零即非定时任务,则offset偏移量无效
|
||
* @par 示例:
|
||
* @code
|
||
*
|
||
* TimeSliceOffset_Register(&m_timeSlice_1, Task_1, 0, 0); //0,即非定时任务(每次轮询都会执行)
|
||
* TimeSliceOffset_Register(&m_timeSlice_2, Task_2, 10, 0); //10*1ms,即10ms运行一次
|
||
* TimeSliceOffset_Register(&m_timeSlice_3, Task_3, 10, 5); //10*1ms,即10ms运行一次,与Task_2错开5ms,这样就不会集中到同一个10ms的时间点上
|
||
*
|
||
* @endcode
|
||
*/
|
||
int TimeSliceOffset_Register(STR_TimeSliceOffset* pTSlice, \
|
||
void (*taskFunc)(void), \
|
||
unsigned short reloadVal, \
|
||
unsigned short offset)
|
||
{
|
||
if(NULL == pTSlice)return -1; /* 返回错误:无效对象 */
|
||
|
||
pTSlice->reloadVal = reloadVal;
|
||
pTSlice->count = reloadVal + offset; /* 添加偏移量,使得同一数值的时间片错开 */
|
||
pTSlice->taskFunc = taskFunc;
|
||
if(0 == reloadVal) /* 非定时任务 */
|
||
{
|
||
pTSlice->runFlag = 1; /* 非定时任务可运行标志默认为一 */
|
||
}
|
||
else /* 定时任务 */
|
||
{
|
||
pTSlice->runFlag = 0; /* 定时任务可运行标志默认为零 */
|
||
}
|
||
|
||
/*遍历链表,防止添加重复*/
|
||
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
|
||
{
|
||
if(pTemp == pTSlice)
|
||
{
|
||
return 1; /* 返回成功:配置完成,但对象已存在,无需加入链表 */
|
||
}
|
||
}
|
||
/*加入链表*/
|
||
pTSlice->pNext = pTimeSliceList;
|
||
pTimeSliceList = pTSlice; /* 把对象加入到链表头部 */
|
||
|
||
return 0; /* 返回成功:注册成功 */
|
||
}
|
||
|
||
/**
|
||
* @brief 取消注册
|
||
* @return 取消配置是否成功
|
||
* - 0 取消配置成功
|
||
* - 1 取消配置成功,但对象不存在,无需从链表中删除
|
||
* - -1 pTSlice为空指针,无效对象
|
||
* @endcode
|
||
*/
|
||
int TimeSliceOffset_Unregister(STR_TimeSliceOffset* pTSlice)
|
||
{
|
||
if (NULL == pTSlice) return -1; /* 返回错误:无效对象 */
|
||
|
||
/* 遍历链表 */
|
||
for (STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext) {
|
||
if (pTemp->pNext == pTSlice) {
|
||
pTemp->pNext = pTemp->pNext->pNext;
|
||
return 0; /* 返回成功:取消注册 */
|
||
} else if (pTemp == pTSlice) {
|
||
pTimeSliceList = pTemp->pNext;
|
||
// pTimeSliceList->pNext = pTemp->pNext->pNext;
|
||
return 0; /* 返回成功:取消注册 */
|
||
}
|
||
}
|
||
return 1; /* 返回成功:对象不存在于链表中 */
|
||
}
|
||
|
||
/**
|
||
* @brief 启动时间片错位轮询(代替main的while循环)
|
||
* @param null
|
||
* @return null
|
||
* @par 注意事项:
|
||
* - null
|
||
*/
|
||
void TimeSliceOffset_Start(void)
|
||
{
|
||
while(1) /* 代替main的while循环 */
|
||
{
|
||
/*遍历时间片链表*/
|
||
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
|
||
{
|
||
if(pTemp->runFlag) /* 可运行则调用任务函数 */
|
||
{
|
||
if(pTemp->reloadVal) /* 重载值不为0,即定时任务 */
|
||
{
|
||
pTemp->runFlag = 0; /* 可运行标志清零,开启新一轮倒计时 */
|
||
}
|
||
pTemp->taskFunc();
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief 时间片生成(放到systick或定时器中断处理函数内)
|
||
* @param null
|
||
* @return null
|
||
* @par 注意事项:
|
||
* - null
|
||
*/
|
||
void TimeSliceOffset_Produce(void)
|
||
{
|
||
/*遍历时间片链表*/
|
||
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
|
||
{
|
||
if(pTemp->reloadVal) /* 重载值不为0,即定时任务 */
|
||
{
|
||
--pTemp->count; /* 计数器递减 */
|
||
if(0 == pTemp->count) /* 计数器递减到零 */
|
||
{
|
||
pTemp->runFlag = 1; /* 允许执行 */
|
||
pTemp->count = pTemp->reloadVal; /* 计数器重载 */
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|