mppt/Drivers/TimeSliceOffset/timeSliceOffset.c

150 lines
4.8 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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();
}
}
// __WFI();
}
}
/**
* @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; /* 计数器重载 */
}
}
}
}