added semaphore to tasks for sample/testing
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
.SECONDARY:
|
.SECONDARY:
|
||||||
|
|
||||||
CFLAGS+= -I. -Os -DSTM32F4 -std=c99
|
CFLAGS+= -I. -O1 -DSTM32F4 -std=c99
|
||||||
#CFLAGS+= -mthumb
|
#CFLAGS+= -mthumb
|
||||||
#CFLAGS+= -march=armv7e-m
|
#CFLAGS+= -march=armv7e-m
|
||||||
CFLAGS+= -mfloat-abi=hard
|
CFLAGS+= -mfloat-abi=hard
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include "scheduler.h"
|
#include "scheduler.h"
|
||||||
#include "usartu.h"
|
#include "usartu.h"
|
||||||
#include "semoper.h"
|
#include "semoper.h"
|
||||||
|
#include "semaphore.h"
|
||||||
|
|
||||||
|
|
||||||
void delay(uint32_t n) {
|
void delay(uint32_t n) {
|
||||||
@@ -59,35 +60,43 @@ static void systick_setup(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int g_uptime;
|
int g_uptime;
|
||||||
|
sem_t g_sem;
|
||||||
|
|
||||||
void task1(void) {
|
void task1(void) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
sem_wait(&g_sem);
|
||||||
printf("task 1 %d\r\n", g_uptime);
|
printf("task 1 %d\r\n", g_uptime);
|
||||||
|
sem_post(&g_sem);
|
||||||
delay(3000);
|
delay(3000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void task2(void) {
|
void task2(void) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
sem_wait(&g_sem);
|
||||||
printf("task 2 %d\r\n", g_uptime);
|
printf("task 2 %d\r\n", g_uptime);
|
||||||
delay(3100);
|
sem_post(&g_sem);
|
||||||
|
delay(3000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void task3(void) {
|
void task3(void) {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
sem_wait(&g_sem);
|
||||||
printf("task 3 %d\r\n", g_uptime);
|
printf("task 3 %d\r\n", g_uptime);
|
||||||
delay(3200);
|
sem_post(&g_sem);
|
||||||
|
delay(3000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void task4(void) {
|
void task4(void) {
|
||||||
static volatile int32_t t4;
|
static volatile int32_t t4;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
atom_inc32(&t4, (int32_t)1);
|
atom_inc32(&t4, (int32_t)1);
|
||||||
|
sem_wait(&g_sem);
|
||||||
printf("task 4 %d %lu\r\n", g_uptime, t4);
|
printf("task 4 %d %lu\r\n", g_uptime, t4);
|
||||||
delay(3300);
|
sem_post(&g_sem);
|
||||||
|
delay(3000);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +108,7 @@ void sys_tick_handler(void) {
|
|||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
g_uptime = 0;
|
g_uptime = 0;
|
||||||
|
sem_init(&g_sem, 1);
|
||||||
static scheduler_t g_scheduler;
|
static scheduler_t g_scheduler;
|
||||||
|
|
||||||
clock_setup();
|
clock_setup();
|
||||||
|
|||||||
+22
-17
@@ -83,42 +83,47 @@ static void scheduler_switch(scheduler_t *scheduler) {
|
|||||||
void __attribute__((naked)) pend_sv_handler(void) {
|
void __attribute__((naked)) pend_sv_handler(void) {
|
||||||
|
|
||||||
const uint32_t RETURN_ON_PSP = RETURN_ON_PSP_THREAD;
|
const uint32_t RETURN_ON_PSP = RETURN_ON_PSP_THREAD;
|
||||||
|
|
||||||
__asm__("cpsid if":::"memory");
|
|
||||||
uint32_t lr;
|
uint32_t lr;
|
||||||
__asm__("mov %0, lr\n":"=r"(lr));
|
|
||||||
|
__asm__(
|
||||||
|
"cpsid if \n"
|
||||||
|
"mov %0, lr \n"
|
||||||
|
:"=r"(lr)
|
||||||
|
);
|
||||||
|
|
||||||
if (lr & EXC_RETURN_MODE_THREAD) {
|
if (lr & EXC_RETURN_MODE_THREAD) {
|
||||||
uint32_t psp;
|
uint32_t psp;
|
||||||
__asm__(
|
__asm__(
|
||||||
"mrs %0, psp\n"
|
"mrs %0, psp \n"
|
||||||
"stmdb %0!, {r4-r11}\n"
|
"stmdb %0!, {r4-r11} \n"
|
||||||
"msr psp, %0\n" : "=r"(psp)
|
"msr psp, %0 \n"
|
||||||
|
: "=r"(psp)
|
||||||
);
|
);
|
||||||
m_scheduler->tasks[m_scheduler->current_task].sp = psp;
|
m_scheduler->tasks[m_scheduler->current_task].sp = psp;
|
||||||
} else {
|
} else {
|
||||||
__asm__(
|
__asm__(
|
||||||
"stmdb sp!, {r4-r11}\n");
|
"stmdb sp!, {r4-r11} \n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduler_switch(m_scheduler);
|
scheduler_switch(m_scheduler);
|
||||||
|
|
||||||
uint32_t psp = (uint32_t)m_scheduler->tasks[m_scheduler->current_task].sp;
|
uint32_t psp = (uint32_t)m_scheduler->tasks[m_scheduler->current_task].sp;
|
||||||
__asm__(
|
__asm__ (
|
||||||
"ldmfd %0!, {r4-r11}\n"
|
"ldmfd %0!, {r4-r11} \n"
|
||||||
"msr psp, %0\n"::"r"(psp)
|
"msr psp, %0 \n"
|
||||||
|
"cpsie if \n"
|
||||||
|
"bx %1 \n"
|
||||||
|
:: "r"(psp), "r"(RETURN_ON_PSP)
|
||||||
);
|
);
|
||||||
|
|
||||||
__asm__("cpsie if" ::: "memory");
|
|
||||||
__asm__("bx %0\n"::"r"(RETURN_ON_PSP));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler_yield(void) {
|
void scheduler_yield(void) {
|
||||||
SCB_ICSR |= SCB_ICSR_PENDSVSET;
|
SCB_ICSR |= SCB_ICSR_PENDSVSET;
|
||||||
__asm__(
|
__asm__(
|
||||||
"nop\n"
|
"nop \n"
|
||||||
"nop\n"
|
"nop \n"
|
||||||
"nop\n"
|
"nop \n"
|
||||||
"nop\n"
|
"nop \n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -10,13 +10,15 @@ void sem_init(sem_t* sem, int32_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t sem_wait(sem_t* sem) {
|
int32_t sem_wait(sem_t* sem) {
|
||||||
//while(sem->value > 0);
|
//while(sem->value <= 0);
|
||||||
//sem->value--;
|
//sem->value--;
|
||||||
while (atom_dec32(&(sem->value), (int32_t)0) > 0);
|
//return sem->value;
|
||||||
|
while (atom_dec32(&(sem->value), (int32_t)0) <= 0);
|
||||||
return atom_dec32(&(sem->value), (int32_t)1);
|
return atom_dec32(&(sem->value), (int32_t)1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sem_post(sem_t* sem) {
|
int32_t sem_post(sem_t* sem) {
|
||||||
//sem->value++;
|
//sem->value++;
|
||||||
|
//return sem->value;
|
||||||
return atom_inc32(&(sem->value), (int32_t)1);
|
return atom_inc32(&(sem->value), (int32_t)1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,7 @@
|
|||||||
.type atom_inc32, %function
|
.type atom_inc32, %function
|
||||||
|
|
||||||
atom_inc32:
|
atom_inc32:
|
||||||
1:
|
1: ldrex r2, [r0]
|
||||||
ldrex r2, [r0]
|
|
||||||
add r2, r2, r1
|
add r2, r2, r1
|
||||||
strex r3, r2, [r0]
|
strex r3, r2, [r0]
|
||||||
teq r3, #0
|
teq r3, #0
|
||||||
@@ -21,8 +20,7 @@ atom_inc32:
|
|||||||
.type atom_dec32, %function
|
.type atom_dec32, %function
|
||||||
|
|
||||||
atom_dec32:
|
atom_dec32:
|
||||||
1:
|
1: ldrex r2, [r0]
|
||||||
ldrex r2, [r0]
|
|
||||||
sub r2, r2, r1
|
sub r2, r2, r1
|
||||||
strex r3, r2, [r0]
|
strex r3, r2, [r0]
|
||||||
teq r3, #0
|
teq r3, #0
|
||||||
|
|||||||
Reference in New Issue
Block a user