449 lines
9.7 KiB
C
Raw Normal View History

2025-05-21 11:31:07 +08:00
/******************************************************************************
Copyright @2024 - 2044 Shenzhen dcenzix Technology Ltd.
******************************************************************************
@file cola_os.c
@brief cola系统
@author xiexiongwu
@version V1.0
@date 2024525
******************************************************************************/
/*----------------------------------------------*
* *
*----------------------------------------------*/
#include <stdio.h>
#include "cola_os.h"
#include "s32_core_cm0.h"
#if 0
//in keil arm gcc
#define disable_irq() __disable_irq()
#define enable_irq() __enable_irq()
#define OS_CPU_SR uint32_t
#define enter_critical() \
do { cpu_sr = __get_PRIMASK(); __disable_irq();} while (0)
#define exit_critical() \
do { __set_PRIMASK(cpu_sr);} while (0)
#else
/* 替换后的中断控制宏 */
#define disable_irq() DISABLE_INTERRUPTS()
#define enable_irq() ENABLE_INTERRUPTS()
/* 定义临界区保护类型 */
#define OS_CPU_SR uint32_t
/* 临界区保护宏适配GCC */
#define enter_critical() \
do \
{ \
__asm volatile ("mrs %0, primask" : "=r" (cpu_sr)); \
disable_irq(); \
} while (0)
#define exit_critical() \
do \
{ \
__asm volatile ("msr primask, %0" : : "r" (cpu_sr)); \
} while (0)
#endif
/*----------------------------------------------*
* *
*----------------------------------------------*/
#define LIST_HEAD_INIT(name) { 0 }
#define TASK_LIST_HEAD(name) \
struct task_s name = LIST_HEAD_INIT(name)
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != NULL; pos = pos->next)
#define list_for_null(pos, head) \
for (pos = head; pos->next != NULL; pos = pos->next)
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next; pos != NULL; \
n = pos->next,pos = n)
#define list_for_each_del(pos, n, head) \
for (n = (head),pos = (head)->next; pos != NULL; \
n = pos,pos = pos->next)
#define time_after_eq(a,b) (((int)((a) - (b)) >= 0))
/*----------------------------------------------*
* *
*----------------------------------------------*/
/*----------------------------------------------*
* *
*----------------------------------------------*/
/** \var task_list
* \brief
*/
static TASK_LIST_HEAD(task_list);
/** \var jiffies
* \brief
*/
volatile unsigned int jiffies = 0;
/** \var jiffies
* \brief
*/
/*----------------------------------------------*
* *
*----------------------------------------------*/
/*
*/
/**
*@brief
*
*@param [in]void
*@return void
*
*/
void cola_task_loop(void)
{
uint32_t events = 0;
task_t *cur, *n = NULL ;
OS_CPU_SR cpu_sr;
list_for_each_safe(cur, n, &task_list)
{
//检查定时任务是否超时
if ((EN_COLA_TASK_TIMER == cur->taskType) && (cur->start) && (time_after_eq(jiffies, cur->timerTick)))
{
enter_critical();
cur->run = true;
cur->timerTick = jiffies + cur->period;
exit_critical();
}
if (cur->run)
{
if ((EN_COLA_TIMER_ONE_SHOT == cur->timerType) && (EN_COLA_TASK_TIMER == cur->taskType))
{
cur->start = false;
}
if (NULL != cur->func)
{
events = cur->event;
if (events)
{
enter_critical();
cur->event = 0;
exit_critical();
}
cur->func(cur->usr, events);
}
if (EN_COLA_TASK_TIMER == cur->taskType)
{
enter_critical();
cur->run = false;
exit_critical();
}
}
}
}
/**
*@brief
*
*@param [in]task_t *task
*@return bool true:;false:
*
*/
static bool cola_task_is_exists(task_t *task)
{
task_t *cur ;
list_for_each(cur, &task_list)
{
if (cur->taskNum == task->taskNum)
{
return true;
}
}
return false;
}
/**
*@brief
*
*@param [in]task_t *task
*@param [in]cbFunc func
*@param [in]void *arg
*@return bool true:;false:
*
*/
bool cola_task_create(task_t *task, cbFunc func, void *arg)
{
task_t *cur ;
OS_CPU_SR cpu_sr;
enter_critical();
if ((NULL == task) || (cola_task_is_exists(task)))
{
exit_critical();
return false;
}
task->taskType = EN_COLA_TASK_TASK;
task->start = true;
task->run = true;
task->func = func;
task->event = 0;
task->usr = arg;
list_for_null(cur, &task_list)
{
}
task->taskNum = cur->taskNum + 1;
cur->next = task;
task->next = NULL;
exit_critical();
return true;
}
/**
*@brief
*
*@param [in]task_t *task
*@return bool true:;false:
*
*/
bool cola_task_delete(task_t *task)
{
task_t *cur, *n;
OS_CPU_SR cpu_sr;
enter_critical();
list_for_each_del(cur, n, &task_list)
{
if (cur->taskNum == task->taskNum)
{
n->next = cur->next;
exit_critical();
return true;
}
}
exit_critical();
return false;
}
/**
*@brief
*
*@param [in]task_t *task
*@param [in]cbFunc func
*@param [in]void *arg
*@return bool true:;false:
*
*/
bool cola_timer_create(task_t *timer, cbFunc func, void *arg)
{
task_t *cur ;
OS_CPU_SR cpu_sr;
enter_critical();
if ((NULL == timer) || (cola_task_is_exists(timer)))
{
exit_critical();
return false;
}
timer->taskType = EN_COLA_TASK_TIMER;
timer->run = false;
timer->period = 0;
timer->timerType = EN_COLA_TIMER_ONE_SHOT;
timer->start = false;
timer->timerTick = 0;
timer->func = func;
timer->event = 0;
timer->usr = arg;
list_for_null(cur, &task_list)
{
}
timer->taskNum = cur->taskNum + 1;
cur->next = timer;
timer->next = NULL;
exit_critical();
return true;
}
/**
*@brief
*
*@param [in]task_t *timer
*@param [in]cbFunc func
*@param [in]void *arg
*@return bool true:;false:
*
*/
bool cola_timer_start(task_t *timer, EN_COLA_TIMER_TYPE time_type, uint32_t time_ms)
{
task_t *cur ;
OS_CPU_SR cpu_sr;
enter_critical();
list_for_each(cur, &task_list)
{
if (cur->taskNum == timer->taskNum)
{
timer->period = time_ms;
timer->timerType = time_type;
timer->start = true;
timer->timerTick = jiffies + time_ms;
timer->taskType = EN_COLA_TASK_TIMER;
exit_critical();
return true;
}
}
exit_critical();
return false;
}
/**
*@brief
*
*@param [in]task_t *timer
*@return bool true:;false:
*
*/
bool cola_timer_stop(task_t *timer)
{
task_t *cur;
OS_CPU_SR cpu_sr;
enter_critical();
list_for_each(cur, &task_list)
{
if (cur->taskNum == timer->taskNum)
{
timer->start = false;
exit_critical();
return true;
}
}
exit_critical();
return false;
}
/**
*@brief
*
*@param [in]task_t *timer
*@return bool true:;false:
*
*/
bool cola_timer_delete(task_t *timer)
{
return cola_task_delete(timer);
}
/**
*@brief (uint ms)
*
*@param void
*@return void
*
*/
void cola_timer_ticker(void)
{
jiffies++;
}
/**
*@brief tick count(uint ms)
*
*@param void
*@return tick count
*
*/
unsigned int cola_get_ticker(void)
{
return jiffies;
}
/**
*@brief
*
*@param [in]task_t *task
*@param [in]EN_COLA_EVENT_TYPE event
*@return bool true:;false:
*
*/
bool cola_set_event(task_t *task, uint32_t event)
{
task_t *cur;
OS_CPU_SR cpu_sr;
enter_critical();
list_for_each(cur, &task_list)
{
if (cur->taskNum == task->taskNum)
{
cur->event |= event;
exit_critical();
return true;
}
}
exit_critical();
return false;
}
/**
*@brief
*
*@param [in]task_t *task
*@param [in]EN_COLA_EVENT_TYPE event
*@return bool true:;false:
*
*/
bool cola_clear_event(task_t *task, uint32_t event)
{
task_t *cur;
OS_CPU_SR cpu_sr;
enter_critical();
list_for_each(cur, &task_list)
{
if (cur->taskNum == task->taskNum)
{
cur->event &= ~(event);
exit_critical();
return true;
}
}
exit_critical();
return false;
}
/**
*@brief
*
*@param [in]uint32_t ms
*@return void
*
*/
void cola_delay_ms(uint32_t ms)
{
unsigned int start = jiffies;
while ((jiffies - start) <= ms);
}