WFI and timer change

Before implementing context switch, I wanted to improve interrupt handling and better timer.
I was using busy loop to check messages from interrupt. First, I used WFI ARM instruction to wait (sleep) until interrupted.

startup.s:
.global _wfi
_wfi:
  wfi
  bx lr

hoge.c:
while (true) {
  _disable_IRQ();
  _wfi();
  if (StatusFifo8(&fifoTimer) == 0) {
    _enable_IRQ();
  } else {
    unsigned char data = GetFifo8(&fifoTimer);
    _enable_IRQ();
...

And I used FIFO8 used in Haribote OS (32bit tiny OS for x86).

Then quickly wrote dirty timer handling which supports up to MAX_TIMER (currently 512). It’s not using a list but an array and not efficient -> TODO.

#define MAX_TIMER 512
typedef struct _TIMER {
  unsigned int timeout;
  unsigned char data;
} TIMER;

typedef struct _TIMERCTL {
  unsigned int counter, next;
  unsigned int length;  // number of used timers
  FIFO8 *fifo;
  TIMER timer[MAX_TIMER];
} TIMERCTL;

extern TIMERCTL timerctl;

void InitTimer(FIFO8 *fifo);
TIMER *SetTimer(TIMER *timer, unsigned int timeout, unsigned char data);

One more improvement. I bought a USB power cable with a switch! I don’t need to plug-in/out to reboot my code anymore 🙂

Today’s code -> https://github.com/sokoide/rpi-baremetal -> 007_wfi.

USB power cable with switch.
usbcable

3 timers whose intervals are 100ms, 500ms and 1s each.
timer2

Leave a Reply

Your email address will not be published. Required fields are marked *