規劃很久了,直到另一個功能出現才有動力去寫。寫出來程式不大。
系統只有二個檔案,測試一個,模擬一個。
event_drive.h 如下
extern void OS_ENTER_CRITICAL(void);
extern void OS_EXIT_CRITICAL(void);
extern void SimInit(void);
#define INIT_DEVICE() SimInit()
#define DIS_INTR() OS_ENTER_CRITICAL()
#define ENA_INTR() OS_EXIT_CRITICAL()
#define MAX_EVENT 8
#define MAX_TIMER 32
extern void execute(void);
extern void setTimeout(void (*p_func)(void), unsigned int tick);
extern void ISR_setTimeout(void (*p_func)(void), unsigned int tick);
extern void timerAction(void);
使用者可以設定同時執行的事件數目及要管理的延時事件數
event_drive.c 如下
#include "event_drive.h"
unsigned int eventInCnt = 0;
unsigned int eventOutCnt = 0;
void (*eventFunc[MAX_EVENT])(void);
void (*delayFunc[MAX_TIMER])(void);
unsigned int delayCnt[MAX_TIMER];
void execute(void)
{
// FIFO function array
if (eventInCnt != eventOutCnt)
{
eventFunc[eventOutCnt % MAX_EVENT]();
eventOutCnt++;
}
}
void setTimeout(void (*p_func)(void), unsigned int tick)
{
int i;
if (!tick)
tick = 1;
DIS_INTR();
for (i = 0; i < MAX_TIMER; i++)
{
if (delayCnt[i] == 0)
break;
}
delayFunc[i] = p_func;
delayCnt[i] = tick;
ENA_INTR();
}
void ISR_setTimeout(void (*p_func)(void), unsigned int tick)
{
int i;
if (!tick)
tick = 1;
for (i = 0; i < MAX_TIMER; i++)
{
if (delayCnt[i] == 0)
break;
}
delayFunc[i] = p_func;
delayCnt[i] = tick;
}
void timerAction(void)
{
int i;
for (i = 0; i < MAX_TIMER; i++)
{
if (delayCnt[i])
{
delayCnt[i]--;
if (!delayCnt[i])
{
eventFunc[eventInCnt % MAX_EVENT] = delayFunc[i];
eventInCnt++;
}
}
}
}
只有4個函式:
execute()是執行的地方,放在main()中的while(1)內就可以了。
timerAction()放在時間中斷內,用來管理延遲執行的函式何時要回復執行。
setTimeout()是使用者註冊一個延遲執行的函式。
ISR_setTimeout()是使用者用於中斷內的函式。
Sim.c windows下的模擬界面
#include <windows.h>
#include <winbase.h>
#include "event_drive.h"
HANDLE OSSemaphore;
DWORD WINAPI OSTickW32(LPVOID lpParameter);
HANDLE OSTick32Handle;
void SimInit(void)
{
DWORD dwID;
OSSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
OSTick32Handle = CreateThread(NULL, 0, OSTickW32, 0, 0, &dwID);
SetPriorityClass(OSTick32Handle, THREAD_PRIORITY_HIGHEST);
SetThreadPriority(OSTick32Handle, THREAD_PRIORITY_HIGHEST);
}
DWORD WINAPI OSTickW32(LPVOID lpParameter)
{
while (1)
{
timerAction();
Sleep(1);
}
return 0;
}
void OS_SLEEP(unsigned int count)
{
Sleep(count);
}
void OS_INIT_CRITICAL(void)
{
return;
}
void OS_ENTER_CRITICAL(void)
{
WaitForSingleObject(OSSemaphore, INFINITE);
}
void OS_EXIT_CRITICAL(void)
{
ReleaseSemaphore(OSSemaphore, 1, NULL);
}
測試用程式
#include <stdio.h>
#include "event_drive.h"
void print_dot(void);
void print_0(void);
void main()
{
INIT_DEVICE();
setTimeout(print_dot, 1);
setTimeout(print_0, 1);
while (1)
{
execute();
}
}
void print_dot(void)
{
printf(".");
setTimeout(print_dot, 7);
}
void print_0(void)
{
printf("0");
setTimeout(print_0, 10);
}