#ifndef __EVENT_DRIVE_H
#define __EVENT_DRIVE_H
#define INIT_DEVICE() resetAllTimer()
#define DIS_INTR() __asm volatile("cpsid i")
#define ENA_INTR() __asm volatile("cpsie i")
#define MAX_EVENT 4
#define MAX_TIMER 4
#define ISR_START 1
#define ISR_END (MAX_TIMER - 1)
#define SPI_TASK_ID 0
void execute(void);
void setNext(void (*p_func)(void));
unsigned int setTimeout(void (*p_func)(void), unsigned int tick);
void setTimer(unsigned int timerId, void (*p_func)(void), unsigned int tick);
void resetAllTimer(void);
void clearTimer(unsigned int id);
void ISR_setNext(void (*p_func)(void));
unsigned int ISR_setTimeout(void (*p_func)(void), unsigned int tick);
void ISR_setTimer(unsigned int timerId, void (*p_func)(void), unsigned int tick);
void timerAction(void);
#define crCREATE(p) static int crState = 0; void (* const crFunc)(void) = (p)
#define crSTART() switch (crState) { case 0:
#define crDELAY(n) do { setTimeout(crFunc, n); crState = (__LINE__); return; case (__LINE__):; } while (0)
#define crEXIT() do { crState = 0; return; } while (0)
#define crEND() }do { crState = 0; } while (0)
#endif /* __EVENT_DRIVE_H */
event_drive.c
#include "event_drive.h"
unsigned int eventInCnt = 0;
unsigned int eventOutCnt = 0;
void (*eventFunc[MAX_EVENT])(void);
void (*delayFunc[MAX_TIMER + 1])(void);
unsigned int delayCnt[MAX_TIMER + 1];
void execute(void)
{
while (eventInCnt != eventOutCnt)
{
eventFunc[eventOutCnt % MAX_EVENT]();
eventOutCnt++;
}
}
void setNext(void (*p_func)(void))
{
DIS_INTR();
eventFunc[eventInCnt % MAX_EVENT] = p_func;
eventInCnt++;
ENA_INTR();
}
unsigned int setTimeout(void (*p_func)(void), unsigned int tick)
{
register int i;
if (!tick)
tick = 1;
DIS_INTR();
i = ISR_START;
while (delayCnt[i])
{
if (i >= ISR_END)
break;
i++;
}
delayFunc[i] = p_func;
delayCnt[i] = tick;
ENA_INTR();
return i; // return timerId
}
void setTimer(unsigned int timerId, void (*p_func)(void), unsigned int tick)
{
if (!tick)
tick = 1;
if (timerId >= MAX_TIMER)
timerId = MAX_TIMER;
DIS_INTR();
delayFunc[timerId] = p_func;
delayCnt[timerId] = tick;
ENA_INTR();
}
void resetAllTimer(void)
{
int i;
for (i = 0; i < MAX_TIMER; i++)
{
delayCnt[i] = 0;
}
}
void clearTimer(unsigned int timerId)
{
if (timerId >= MAX_TIMER)
timerId = MAX_TIMER;
delayCnt[timerId] = 0;
}
void ISR_setNext(void (*p_func)(void))
{
eventFunc[eventInCnt % MAX_EVENT] = p_func;
eventInCnt++;
}
unsigned int ISR_setTimeout(void (*p_func)(void), unsigned int tick)
{
register int i;
if (!tick)
tick = 1;
i = ISR_START;
while (delayCnt[i])
{
if (i >= ISR_END)
break;
i++;
}
delayFunc[i] = p_func;
delayCnt[i] = tick;
return i;
}
void ISR_setTimer(unsigned int timerId, void (*p_func)(void), unsigned int tick)
{
if (!tick)
tick = 1;
if (timerId >= MAX_TIMER)
timerId = MAX_TIMER;
delayFunc[timerId] = p_func;
delayCnt[timerId] = tick;
}
void timerAction(void)
{
int i;
for (i = 0; i < MAX_TIMER; i++)
{
if (delayCnt[i])
{
if (!--delayCnt[i])
{
eventFunc[eventInCnt % MAX_EVENT] = delayFunc[i];
eventInCnt++;
}
}
}
}
測試程式
#include <stdio.h>
#include "event_drive.h"
void print_dot(void);
void print_0(void);
void testCoroutine(void);
void main()
{
INIT_DEVICE();
setTimeout(print_dot, 1);
setTimeout(print_0, 1);
setTimeout(testCoroutine, 1);
while (1)
{
execute();
}
}
void print_dot(void)
{
printf(".");
setTimeout(print_dot, 7);
}
void print_0(void)
{
printf("'");
setTimeout(print_0, 10);
}
void testCoroutine(void)
{
crCREATE(testCoroutine);
crSTART();
for (;;)
{
printf("1");
crDELAY(10);
printf("2");
crDELAY(10);
printf("3");
crDELAY(100);
}
crEND();
}
沒有留言:
張貼留言