540 lines
12 KiB
C
540 lines
12 KiB
C
/**********************************************************
|
||
** porting.c *
|
||
** 2022-11-15 *
|
||
** V1.0 *
|
||
**********************************************************/
|
||
|
||
#include "porting.h"
|
||
|
||
|
||
|
||
/**
|
||
* @brief: ³õʼ»¯Ò»¸öFIFO
|
||
*
|
||
*
|
||
*/
|
||
void sfifo_init(st_fifo_t *stfifo, void *array, unsigned short stsize, unsigned short deepth)
|
||
{
|
||
stfifo->deepth = deepth;
|
||
stfifo->occupy = 0;
|
||
stfifo->array = array;
|
||
stfifo->stsize = stsize;
|
||
stfifo->limit = (void*)((unsigned int)array + stsize*deepth);
|
||
stfifo->wp = stfifo->array;
|
||
stfifo->rp = stfifo->array;
|
||
}
|
||
|
||
void sfifo_reset(st_fifo_t *stfifo)
|
||
{
|
||
stfifo->occupy = 0;
|
||
stfifo->rp = stfifo->array;
|
||
stfifo->wp = stfifo->array;
|
||
}
|
||
|
||
|
||
bool sfifo_write(st_fifo_t *stfifo, const void *stunit)
|
||
{
|
||
if (stfifo->occupy >= stfifo->deepth || stfifo->array == NULL) return false;
|
||
|
||
memcpy((unsigned char*)stfifo->wp,(unsigned char*)stunit,stfifo->stsize);
|
||
stfifo->wp = (void*)((unsigned int)stfifo->wp + stfifo->stsize);
|
||
if (stfifo->wp >= stfifo->limit) stfifo->wp = stfifo->array;
|
||
|
||
stfifo->occupy++;
|
||
|
||
return true;
|
||
}
|
||
|
||
bool sfifo_empty(st_fifo_t *stfifo)
|
||
{
|
||
if (stfifo->occupy == 0 || stfifo->array == NULL) return true;
|
||
else return false;
|
||
}
|
||
|
||
bool sfifo_full(st_fifo_t *stfifo)
|
||
{
|
||
if (stfifo->occupy >= stfifo->deepth) return true;
|
||
else return false;
|
||
}
|
||
|
||
|
||
unsigned int sfifo_read(st_fifo_t *stfifo,void *stunit)
|
||
{
|
||
|
||
if (stfifo->occupy == 0 || stfifo->array == NULL) return 0x0;
|
||
|
||
memcpy((unsigned char*)stunit,(unsigned char*)stfifo->rp,stfifo->stsize);
|
||
stfifo->rp = (void*)((unsigned int)stfifo->rp + stfifo->stsize);
|
||
if (stfifo->rp >= stfifo->limit) stfifo->rp = stfifo->array;
|
||
|
||
|
||
stfifo->occupy--;
|
||
|
||
return stfifo->stsize;
|
||
}
|
||
|
||
unsigned int sfifo_occupy_get(st_fifo_t *stfifo)
|
||
{
|
||
return stfifo->occupy;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/******************************************************************
|
||
QUEUE
|
||
******************************************************************/
|
||
bool CreateQueue(QUEUE *que)
|
||
{
|
||
if (que == 0) return FALSE;
|
||
que->head = 0;
|
||
que->tail = 0;
|
||
que->item = 0;
|
||
return TRUE;
|
||
}
|
||
|
||
unsigned short QueueItem(QUEUE *que)
|
||
{
|
||
if (que == 0) return 0;
|
||
else return (que->item);
|
||
}
|
||
|
||
QUEUEMEM *QueueHead(QUEUE *que)
|
||
{
|
||
if (que == 0 || que->item == 0) return 0;
|
||
else return ((QUEUEMEM *)que->head);// + sizeof(NODE));
|
||
}
|
||
|
||
QUEUEMEM *QueueTail(QUEUE *que)
|
||
{
|
||
if (que == 0 || que->item == 0) return 0;
|
||
else return ((QUEUEMEM *)que->tail);// + sizeof(NODE));
|
||
}
|
||
|
||
QUEUEMEM *QueueNext(QUEUEMEM *element)
|
||
{
|
||
QUEUENODE *curnode;
|
||
|
||
if (element == 0) return 0;
|
||
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
|
||
if ((curnode = curnode->next) == 0) return 0;
|
||
else return ((QUEUEMEM *)curnode);// + sizeof(NODE));
|
||
}
|
||
|
||
QUEUEMEM *DelQueueElement(QUEUE *que, QUEUEMEM *element)
|
||
{
|
||
QUEUENODE *curnode, *prenode, *nextnode;
|
||
|
||
if (que == 0 || element == 0) return 0;
|
||
if (que->item == 0) return 0;
|
||
|
||
que->item--;
|
||
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
|
||
|
||
if (curnode == que->head) {
|
||
que->head = curnode->next;
|
||
if (que->item == 0) {
|
||
que->tail = 0;
|
||
return 0;
|
||
} else {
|
||
return (QUEUEMEM *)(que->head);// + sizeof(NODE);
|
||
}
|
||
}
|
||
|
||
nextnode = curnode->next;
|
||
prenode = que->head;
|
||
while (prenode != 0) {
|
||
if (prenode->next == curnode) {
|
||
break;
|
||
} else {
|
||
prenode = prenode->next;
|
||
}
|
||
}
|
||
if (prenode == 0) return 0;
|
||
|
||
prenode->next = nextnode;
|
||
if (curnode == que->tail) {
|
||
que->tail = prenode;
|
||
return 0;
|
||
} else {
|
||
return ((QUEUEMEM *)nextnode);// + sizeof(NODE));
|
||
}
|
||
}
|
||
|
||
// Return: Queue head
|
||
QUEUEMEM *DelQueueHead(QUEUE *que)
|
||
{
|
||
QUEUEMEM *element;
|
||
|
||
if (que == 0 || que->item == 0) return 0;
|
||
|
||
element = (QUEUEMEM *)que->head;//+ sizeof(NODE);
|
||
DelQueueElement(que, element);
|
||
return element;
|
||
}
|
||
|
||
// Return: Queue tail
|
||
QUEUEMEM *DelQueueTail(QUEUE *que)
|
||
{
|
||
QUEUEMEM *element;
|
||
|
||
if (que == 0 || que->item == 0) return 0;
|
||
|
||
element = (QUEUEMEM *)que->tail;// + sizeof(NODE);
|
||
DelQueueElement(que, element);
|
||
return element;
|
||
}
|
||
|
||
bool AppendQueue(QUEUE *que, QUEUEMEM *element)
|
||
{
|
||
QUEUENODE *curnode;
|
||
|
||
if (que == 0 || element == 0) return FALSE;
|
||
|
||
curnode = (QUEUENODE *)(element);// - sizeof(NODE));
|
||
if (que->item == 0) {
|
||
que->head = curnode;
|
||
} else {
|
||
que->tail->next = curnode;
|
||
}
|
||
curnode->next = 0;
|
||
que->tail = curnode;
|
||
que->item++;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
//intsert element before curelement
|
||
bool InsertBeforeQueue(QUEUE *que, QUEUEMEM *element,QUEUEMEM *curelement)
|
||
{
|
||
QUEUENODE *curnode, *prenode, *node;
|
||
|
||
if (que == 0 || element == 0 || curelement == 0) return FALSE;
|
||
node = (QUEUENODE*)element;
|
||
curnode = (QUEUENODE*)curelement;
|
||
|
||
if (que->head == curnode) {
|
||
que->head = node;
|
||
node->next = curnode;
|
||
} else {
|
||
prenode = que->head;
|
||
while (prenode != 0) {
|
||
if (prenode->next == curnode) {
|
||
break;
|
||
} else {
|
||
prenode = prenode->next;
|
||
}
|
||
}
|
||
if (prenode == 0) return false;
|
||
prenode->next = node;
|
||
node->next = curnode;
|
||
}
|
||
que->item++;
|
||
return true;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
/*********************************************ÐźÅÏà¹ØµÄ²Ù×÷*******************************************************/
|
||
typedef struct {
|
||
unsigned int signal_id;
|
||
unsigned int para1;
|
||
unsigned int para2;
|
||
} signal_cell_t;
|
||
|
||
typedef struct {
|
||
unsigned int signal;
|
||
signal_callback cb;
|
||
}signal_callback_t;
|
||
|
||
typedef struct {
|
||
signal_callback_t signal_map[20]; /* ´æ´¢my_kill ×¢²áµÄÐźźͻص÷ */
|
||
signal_cell_t signal[40];
|
||
st_fifo_t queue;
|
||
} signal_queue_t;
|
||
|
||
|
||
static signal_queue_t can_signal_queue = {0};
|
||
|
||
|
||
|
||
/*
|
||
* \brief: ·¢ËÍÒ»¸öÏûÏ¢¸ø½ø³ÌPID
|
||
* \para:
|
||
* signal: my_signal_e ÀàÐ͵ÄÐźÅÖµ
|
||
* para1,para2: ²ÎÊý£¬my_kill Óë¶ÔÓ¦ÏûÏ¢»Øµ÷Ö®¼ä´«µÝ²ÎÊýÓÃ
|
||
*
|
||
* ÕâÀï³ýÁ˽«ÏûÏ¢´æ·Åµ½¶ÓÁÐÍ⣬»¹»á¼ì²éµ±Ç°¶ÓÁÐÖеÄÏûÏ¢
|
||
* ¸öÊý£¬µ±³¬¹ýÒ»¶¨ÖµÊ±¸øÓ뾯¸æÌáʾ
|
||
*/
|
||
int can_kill(unsigned int signal, unsigned int para1, unsigned int para2)
|
||
{
|
||
signal_cell_t signal_cell;
|
||
|
||
|
||
signal_cell.signal_id = signal;
|
||
signal_cell.para1 = para1;
|
||
signal_cell.para2 = para2;
|
||
|
||
return sfifo_write(&can_signal_queue.queue, (void *)&signal_cell);
|
||
}
|
||
|
||
|
||
/*
|
||
* \brief: ÉêÃ÷²¶»ñ½ø³ÌPID µÄÏûÏ¢signal
|
||
* \para:
|
||
* signal: Òª²¶»ñµÄÏûÏ¢
|
||
* cb: ²¶»ñº¯Êý
|
||
* \return:
|
||
* 0-³É¹¦ <0 ʧ°Ü
|
||
*
|
||
*¼ì²éÒª²¶»ñµÄÏûÏ¢ÊÇ·ñÒÑÔÚpSQueue->mass Öб»ÉêÃ÷£¬ÒÑÉêÃ÷Ôò·µ»Øʧ°Ü
|
||
*½«ÆäÌí¼Óµ½pSQueue->signal_map ÖÐ
|
||
*/
|
||
int can_signal(unsigned int signal, signal_callback cb)
|
||
{
|
||
unsigned int i;
|
||
|
||
if (signal == E_CAN_SIGNAL_NULL) return -1;
|
||
|
||
|
||
/*Èç¹ûÒѾÉêÃ÷ÔòÓÃеĻص÷º¯ÊýÌ滻֮ǰµÄ»Øµ÷º¯Êý*/
|
||
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
|
||
{
|
||
if (can_signal_queue.signal_map[i].signal == signal)
|
||
{
|
||
can_signal_queue.signal_map[i].cb = cb;
|
||
if (can_signal_queue.signal_map[i].cb == NULL)
|
||
{
|
||
/* ɾ³ý»Øµ÷ */
|
||
can_signal_queue.signal_map[i].signal = E_CAN_SIGNAL_NULL;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*Èç¹ûûÓÐÉêÃ÷ÔòÌí¼Ó*/
|
||
if (cb == NULL)
|
||
{
|
||
/* Ìí¼ÓÐÂÐźţ¬ÔòÆä´¦Àíº¯Êý±ØÐ벻ΪNULL */
|
||
return -1;
|
||
}
|
||
|
||
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
|
||
{
|
||
if (can_signal_queue.signal_map[i].signal == E_CAN_SIGNAL_NULL || can_signal_queue.signal_map[i].cb == NULL)
|
||
{
|
||
can_signal_queue.signal_map[i].signal = signal;
|
||
can_signal_queue.signal_map[i].cb = cb;
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
|
||
/* ÐźŹ¦Äܵijõʼ»¯ */
|
||
int can_signal_queue_init(void)
|
||
{
|
||
memset(&can_signal_queue, 0x00, sizeof(can_signal_queue));
|
||
sfifo_init(&can_signal_queue.queue, &can_signal_queue.signal[0], sizeof(can_signal_queue.signal[0]), NELEMENTS(can_signal_queue.signal));
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief: ´¦ÀíCANµÄÐźŵ÷¶È
|
||
*/
|
||
int can_signal_schedule(void)
|
||
{
|
||
signal_callback cb;
|
||
signal_cell_t signal_cell;
|
||
unsigned int i;
|
||
|
||
while(sfifo_empty(&can_signal_queue.queue) == false)
|
||
{
|
||
sfifo_read(&can_signal_queue.queue, (void *)&signal_cell);
|
||
|
||
for (i=0; i<NELEMENTS(can_signal_queue.signal_map); i++)
|
||
{
|
||
if (can_signal_queue.signal_map[i].signal == signal_cell.signal_id)
|
||
{
|
||
cb = can_signal_queue.signal_map[i].cb;
|
||
if (cb != NULL) cb(signal_cell.signal_id, signal_cell.para1, signal_cell.para2);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
/******************************************¶¨Ê±Æ÷********************************************************************/
|
||
typedef struct tmr_st {
|
||
unsigned int holdtime; //¶¨Ê±Ê±¼ä£¬Îª0±íʾֹͣ£»
|
||
unsigned int optime;
|
||
can_tmr_func tmrfunc; //¶¨Ê±Ö´ÐÐÈÎÎñµÄÖ¸Õë
|
||
} timer_cell_t;;
|
||
|
||
static timer_cell_t can_timer[20];
|
||
|
||
|
||
TIMER can_timer_create(can_tmr_func cb)
|
||
{
|
||
unsigned short i;
|
||
|
||
if (cb == NULL)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
for (i = 0; i < NELEMENTS(can_timer); i++)
|
||
{
|
||
if (can_timer[i].tmrfunc == NULL)
|
||
{
|
||
can_timer[i].tmrfunc = cb;
|
||
can_timer[i].holdtime = 0;
|
||
return (TIMER)&can_timer[i];
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
void can_timer_remove(TIMER tmr)
|
||
{
|
||
timer_cell_t *pCur = (timer_cell_t *)tmr;
|
||
|
||
if ((NULL == pCur))
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
pCur->holdtime = 0;
|
||
pCur->optime = 0;
|
||
pCur->tmrfunc = NULL;
|
||
return;
|
||
}
|
||
|
||
void can_timer_start(TIMER tmr,unsigned int ms)
|
||
{
|
||
timer_cell_t *pCur = (timer_cell_t *)tmr;
|
||
|
||
if (pCur == NULL) return;
|
||
|
||
pCur->holdtime = ms;
|
||
|
||
TickOut(&(pCur->optime), 0);
|
||
}
|
||
|
||
|
||
void can_timer_stop(TIMER tmr)
|
||
{
|
||
timer_cell_t *pCur = (timer_cell_t *)tmr;
|
||
|
||
if (pCur == NULL) return;
|
||
|
||
pCur->holdtime = 0;
|
||
}
|
||
|
||
bool can_timer_switch(TIMER tmr)
|
||
{
|
||
timer_cell_t *pCur = (timer_cell_t *)tmr;
|
||
|
||
if (pCur == NULL) return false;
|
||
|
||
if (pCur->holdtime > 0) {
|
||
return true;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ¶¨Ê±Æ÷¹¦Äܵijõʼ»¯ */
|
||
int can_timer_init(void)
|
||
{
|
||
memset(can_timer, 0x00, sizeof(can_timer));
|
||
return 0;
|
||
}
|
||
|
||
|
||
/* ¶¨Ê±Æ÷¹¦Äܵijõʼ»¯ */
|
||
int can_timer_schedule(void)
|
||
{
|
||
unsigned int tick, i, holdtime, last_tick = 0;
|
||
can_tmr_func cb;
|
||
|
||
TickOut(&tick, 0);
|
||
|
||
if (tick == last_tick || tick == (last_tick+1))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
last_tick = tick;
|
||
|
||
for (i = 0; i < NELEMENTS(can_timer); i++)
|
||
{
|
||
cb = can_timer[i].tmrfunc;
|
||
holdtime = can_timer[i].holdtime;
|
||
|
||
if (holdtime > 0 && cb != NULL)
|
||
{
|
||
|
||
if (TickOut(&can_timer[i].optime,holdtime) == TRUE)
|
||
{
|
||
if (can_timer[i].tmrfunc != NULL)
|
||
{
|
||
can_timer[i].optime += ((tick - can_timer[i].optime)/holdtime*holdtime);
|
||
}
|
||
|
||
if (cb != NULL)
|
||
{
|
||
cb((TIMER)&can_timer[i]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief: ³õʼ»¯can ÐÒéµÄ»ù´¡¹¦ÄÜ
|
||
*/
|
||
void can_porting_init(void)
|
||
{
|
||
can_timer_init();
|
||
can_signal_queue_init();
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief: ³õʼ»¯can ÐÒéµÄ»ù´¡¹¦Äܵĵ÷¶È
|
||
*/
|
||
void can_porting_schedule(void)
|
||
{
|
||
can_signal_schedule();
|
||
can_timer_schedule();
|
||
}
|
||
|
||
|