2019年9月29日 星期日

Bison使用

windows下使用
C:>win_flex  input_file.l
C:>win_bison -d input_file.y
在VS2019下會有些問題
  1. 少 unistd.h
    1. 巨集中定義 YY_NO_UNISTD_H
  2. 停用4996警告,C語言一般都有這個問題

2019年9月15日 星期日

事件驅動多工合併Coroutine

event_drive.h 
#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();
}