diff --git a/Makefile b/Makefile index 8024a4c..0ae82bd 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ CFLAGS+= -fno-common -ffunction-sections -fdata-sections CFLAGS+= -g -gdwarf-2 CFLAGS+= -Wall + LDFLAGS+= ${CFLAGS} LDFLAGS+= --static #LDFLAGS+= -nostartfiles @@ -32,7 +33,8 @@ OBJS+= main.o OBJS+= syscall.o OBJS+= usartu.o OBJS+= scheduler.o - +OBJS+= semoper.o +OBJS+= semaphore.o main.elf: $(OBJS) $(TARGET)-gcc $(^F) $(LDFLAGS) -o $@ @@ -42,7 +44,7 @@ main.elf: $(OBJS) $(TARGET)-gcc $(CFLAGS) -c -o $@ $< %.o: %.S - $(TARGET)-as $(ASFLAGS) -o $@ $< + $(TARGET)-gcc $(CFLAGS) -c -o $@ $< %.bin: %.elf $(TARGET)-objcopy -O binary $< $@ diff --git a/main.c b/main.c index 7df08d3..55b5668 100644 --- a/main.c +++ b/main.c @@ -18,6 +18,7 @@ #include "scheduler.h" #include "usartu.h" +#include "semoper.h" void delay(uint32_t n) { @@ -81,8 +82,11 @@ void task3(void) { } void task4(void) { + static volatile int32_t t4; + while (true) { - printf("task 4 %d\r\n", g_uptime); + sem_post32(&t4, (int32_t)1); + printf("task 4 %d %lu\r\n", g_uptime, t4); delay(3300); }; } diff --git a/semaphore.c b/semaphore.c index f6b885a..a8e0032 100644 --- a/semaphore.c +++ b/semaphore.c @@ -3,21 +3,19 @@ */ #include "semaphore.h" +#include "semoper.h" -typedef struct { - int value; -} sem_t; - -int sem_init(sem_t* sem, int value) { +void sem_init(sem_t* sem, int32_t value) { sem->value = value; } -int sem_wait(sem_t* sem) { - while(sem->value > 0); - sem->value--; +int32_t sem_wait(sem_t* sem) { + //while(sem->value > 0); + //sem->value--; + return sem_wait32(&(sem->value), (int32_t)1); } - -int sem_post(sem_t* sem) { - sem->value++; +int32_t sem_post(sem_t* sem) { + //sem->value++; + return sem_post32(&(sem->value), (int32_t)1); } diff --git a/semaphore.h b/semaphore.h index 0cf2b8e..c8d005c 100644 --- a/semaphore.h +++ b/semaphore.h @@ -3,10 +3,12 @@ */ +#include + typedef struct { - int value; + int32_t value; } sem_t; -int sem_init(sem_t* sem, int value); -int sem_wait(sem_t* sem); -int sem_post(sem_t* sem); +void sem_init(sem_t* sem, int32_t value); +int32_t sem_wait(sem_t* sem); +int32_t sem_post(sem_t* sem); diff --git a/semoper.S b/semoper.S new file mode 100644 index 0000000..561f1f2 --- /dev/null +++ b/semoper.S @@ -0,0 +1,31 @@ +.thumb +.syntax unified + +.text + +.globl sem_post32 +.type sem_post32, %function + +sem_post32: +1: + ldrex r2, [r0] + add r2, r2, r1 + strex r3, r2, [r0] + teq r3, #0 + bne 1b + mov r0, r2 + bx lr + + +.globl sem_wait32 +.type sem_wait32, %function + +sem_wait32: +1: + ldrex r2, [r0] + sub r2, r2, r1 + strex r3, r2, [r0] + teq r3, #0 + bne 1b + mov r0, r2 + bx lr diff --git a/semoper.h b/semoper.h new file mode 100644 index 0000000..23d2d10 --- /dev/null +++ b/semoper.h @@ -0,0 +1,13 @@ +/* + * Copyright 2022 Oleg Borodin + */ + +#ifndef SEMOPER_H_QWERTY +#define SEMOPER_H_QWERTY + +#include + +int32_t sem_post32(volatile int32_t *addr, int32_t value); +int32_t sem_wait32(volatile int32_t *addr, int32_t value); + +#endif