/********************************************************** ** 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; iholdtime = 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; } } /* 定时器功能的初始化 */ int can_timer_init(void) { memset(can_timer, 0x00, sizeof(can_timer)); return 0; } /* 定时器功能的初始化 */ 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(); }