This commit is contained in:
Wolfgang Hottgenroth 2024-06-12 23:15:34 +02:00
commit 1b6f444f4a
6 changed files with 205 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.o
firmware.txt
firmware.elf
firmware.map

35
Makefile Normal file
View File

@ -0,0 +1,35 @@
TOOLCHAIN_PREFIX=/opt/msp430-gcc
CC=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-gcc
OBJDUMP=$(TOOLCHAIN_PREFIX)/bin/msp430-elf-objdump
ARTIFACT=firmware
MCU=msp430g2553
DEBUGFLAGS=
DEBUGFLAGS+= -g3 -ggdb -gdwarf-2
COMMONFLAGS=-Wall -mmcu=$(MCU) -I $(TOOLCHAIN_PREFIX)/include -O0 -g0 $(DEBUGFLAGS)
CFLAGS=$(COMMONFLAGS) -std=gnu99
ASFLAGS=$(COMMONFLAGS) -D__ASSEMBLER__
LDFLAGS=-mmcu=$(MCU) -L $(TOOLCHAIN_PREFIX)/include
$(ARTIFACT).elf: main.o scheduler.o
$(CC) -o $@ $(LDFLAGS) $^
$(OBJDUMP) -D $(ARTIFACT).elf > $(ARTIFACT).txt
.c.o:
$(CC) $(CFLAGS) -c $<
.S.o:
$(CC) $(ASFLAGS) -c $<
.PHONY: all
all: $(ARTIFACT).elf
.PHONY: clean
clean:
-rm -f *.o $(ARTIFACT).elf $(ARTIFACT).txt
.PHONY: upload
upload: $(ARTIFACT).elf
mspdebug rf2500 "prog $(ARTIFACT).elf"

2
firmware.gdb Normal file
View File

@ -0,0 +1,2 @@
target remote localhost:2000
file firmware.elf

29
main.c Normal file
View File

@ -0,0 +1,29 @@
#include <msp430g2553.h>
#include <stdint.h>
#include <stdlib.h>
#include "scheduler.h"
int main() {
WDTCTL = WDTPW | WDTHOLD;
__disable_interrupt();
// highest possible system clock
DCOCTL = DCO0 | DCO1 | DCO2;
BCSCTL1 = XT2OFF | RSEL0 | RSEL1 | RSEL2 | RSEL3;
BCSCTL2 = 0;
BCSCTL3 = 0;
schInit();
__enable_interrupt();
while (1) {
schExec();
}
}

107
scheduler.c Normal file
View File

@ -0,0 +1,107 @@
#include <stdlib.h>
#include <msp430g2553.h>
#include "scheduler.h"
tTask tasks[MAX_NUM_OF_TASKS];
uint32_t seconds;
void schInit() {
TACCR0 = 19600;
TACCTL0 = CCIE;
TACTL = MC_1 | ID_0 | TASSEL_2 | TACLR;
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
tasks[i].delay = 0;
tasks[i].period = 0;
tasks[i].run = 0;
tasks[i].exec = NULL;
tasks[i].handle = NULL;
}
seconds = 0;
// LED
P2DIR |= BIT6;
P2OUT &= ~BIT6;
P2SEL &= ~BIT6;
P2SEL2 &= ~BIT6;
}
void __attribute__ ((interrupt (TIMER0_A0_VECTOR))) schUpdate() {
static uint16_t milliSeconds = 0;
if (milliSeconds >= 1000) {
seconds += 1;
milliSeconds = 0;
P2OUT ^= BIT6;
}
milliSeconds += 1;
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
if (tasks[i].exec != NULL) {
if (tasks[i].delay == 0) {
tasks[i].delay = tasks[i].period;
tasks[i].run++;
} else {
tasks[i].delay--;
}
}
}
}
uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period) {
uint16_t taskId = 0xffff;
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
if (tasks[i].exec == NULL) {
tasks[i].delay = delay;
tasks[i].period = period;
if (delay == 0 && period == 0) {
tasks[i].run = 1;
} else {
tasks[i].run = 0;
}
tasks[i].exec = exec;
tasks[i].handle = handle;
taskId = i;
break;
}
}
return taskId;
}
void schDel(uint16_t taskId) {
tasks[taskId].exec = NULL;
}
void schExec() {
for (uint16_t i = 0; i < MAX_NUM_OF_TASKS; i++) {
// synchronize access to tasks[].run
__disable_interrupt();
if (tasks[i].exec != NULL && tasks[i].run > 0) {
tasks[i].run--;
// synchronize access to tasks[].run
// reenable interrupts before actually executing task
__enable_interrupt();
tasks[i].exec(tasks[i].handle);
if (tasks[i].period == 0) {
tasks[i].exec = NULL;
}
} else {
// synchronize access to tasks[].run
// reenable interrupts in case task is not yet executable
__enable_interrupt();
}
}
}
uint32_t getSeconds() {
uint32_t s;
__disable_interrupt();
s = seconds;
__enable_interrupt();
return s;
}

27
scheduler.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef PONTCOOPSCHEDULER_H_
#define PONTCOOPSCHEDULER_H_
#include <stdint.h>
#define MAX_NUM_OF_TASKS 4
typedef struct {
uint16_t delay;
uint16_t period;
uint8_t run;
void (*exec)(void *handle);
void *handle;
} tTask;
void schInit();
uint16_t schAdd(void (*exec)(void *), void *handle, uint32_t delay, uint32_t period);
void schDel(uint16_t taskId);
void schExec();
#endif /* PONTCOOPSCHEDULER_H_ */