規劃很久了,直到另一個功能出現才有動力去寫。寫出來程式不大。
系統只有二個檔案,測試一個,模擬一個。
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);
}
 
沒有留言:
張貼留言