privileged mode works

master
tcsullivan 6 years ago
parent 04548126b5
commit 231c796f50

@ -7,20 +7,18 @@
#define GPIO_SPEED 3 #define GPIO_SPEED 3
#define GPIO_OUT 4 #define GPIO_OUT 4
void gpio(uint32_t call, uint32_t port, uint32_t pin, uint32_t value) void gpio(uint32_t call, uint32_t pin, uint32_t value)
{ {
register uint32_t r0 asm("r0") = call; register uint32_t r0 asm("r0") = call;
register uint32_t r1 asm("r1") = port; register uint32_t r1 asm("r1") = pin;
register uint32_t r2 asm("r2") = pin; register uint32_t r2 asm("r2") = value;
register uint32_t r3 asm("r3") = value;
asm("\ asm("\
mov r0, %0; \ mov r0, %0; \
mov r1, %1; \ mov r1, %1; \
mov r2, %2; \ mov r2, %2; \
mov r3, %3; \
svc 1; \ svc 1; \
" :: "r" (r0), "r" (r1), "r" (r2), "r" (r3)); " :: "r" (r0), "r" (r1), "r" (r2));
} }
#endif // PRIV_GPIO_H_ #endif // PRIV_GPIO_H_

@ -20,23 +20,31 @@
#include <gpio.h> #include <gpio.h>
static const GPIO_TypeDef *gpio_ports[8] = {
GPIOA, GPIOB, GPIOC, GPIOD,
GPIOE, GPIOF, GPIOG, GPIOH
};
void gpio_svc(uint32_t *args) void gpio_svc(uint32_t *args)
{ {
GPIO_TypeDef *port = gpio_ports[args[1] / 16];
uint32_t pin = args[1] & 0xF;
switch (args[0]) { switch (args[0]) {
case 0: case 0:
gpio_mode((GPIO_TypeDef *)args[1], args[2], args[3]); gpio_mode(port, pin, args[2]);
break; break;
case 1: case 1:
gpio_type((GPIO_TypeDef *)args[1], args[2], args[3]); gpio_type(port, pin, args[2]);
break; break;
case 2: case 2:
gpio_pupd((GPIO_TypeDef *)args[1], args[2], args[3]); gpio_pupd(port, pin, args[2]);
break; break;
case 3: case 3:
gpio_speed((GPIO_TypeDef *)args[1], args[2], args[3]); gpio_speed(port, pin, args[2]);
break; break;
case 4: case 4:
gpio_dout((GPIO_TypeDef *)args[1], args[2], args[3]); gpio_dout(port, pin, args[2]);
break; break;
} }
} }

@ -54,12 +54,11 @@ int main(void)
void task2(void); void task2(void);
void kmain(void) void kmain(void)
{ {
gpio(GPIO_MODE, (uint32_t)GPIOA, 5, OUTPUT); gpio(GPIO_MODE, 5, OUTPUT);
//gpio_mode(GPIOA, 5, OUTPUT);
task_start(task2, 512); task_start(task2, 512);
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
gpio_dout(GPIOA, 5, !(i & 1)); gpio(GPIO_OUT, 5, !(i & 1));
delay(200); delay(200);
} }
} }
@ -76,7 +75,7 @@ void task3(void)
int state = 0; int state = 0;
delay(2500); delay(2500);
while (1) { while (1) {
gpio_dout(GPIOA, 5, state ^= 1); gpio(GPIO_OUT, 5, state ^= 1);
delay(500); delay(500);
} }
} }

@ -22,14 +22,19 @@
#include <stdint.h> #include <stdint.h>
#include <gpio.h> #include <gpio.h>
#include <clock.h> #include <clock.h>
#include <task.h>
extern void gpio_svc(uint32_t *); extern void gpio_svc(uint32_t *);
void svc_handler(uint32_t *args) void svc_handler(uint32_t *args)
{ {
uint32_t svc_number = ((char *)args[6])[-2]; /*uint32_t*/int svc_number = ((char *)args[6])[-2];
switch (svc_number) { switch (svc_number) {
case -1:
case 0:
_exit(args[0]);
break;
case 1: case 1:
gpio_svc(args); gpio_svc(args);
break; break;

@ -48,19 +48,25 @@ void _exit(int code)
free(current); free(current);
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
while (1);
} }
/** /**
* 'Prepares' task for running. * 'Prepares' task for running.
* Calls the task's main code, setting _exit() as the return point. * Calls the task's main code, setting _exit() as the return point.
*/ */
__attribute__ ((naked))
void task_doexit(void)
{
asm("eor r0, r0; svc 0");
while (1);
}
__attribute__ ((naked)) __attribute__ ((naked))
void task_crt0(void) void task_crt0(void)
{ {
asm("\ asm("\
mov r4, lr; \ mov r4, lr; \
ldr lr, =_exit; \ ldr lr, =task_doexit; \
bx r4; \ bx r4; \
"); ");
} }
@ -95,8 +101,11 @@ task_t *task_create(void (*code)(void), uint32_t stackSize)
void task_init(void (*init)(void)) void task_init(void (*init)(void))
{ {
current = (task_t *)malloc(sizeof(task_t)); current = (task_t *)malloc(sizeof(task_t));
current->stack = 0;
task_t *init_task = task_create(init, 4096); task_t *init_task = task_create(init, 4096);
prev = init_task;
current->next = init_task; current->next = init_task;
init_task->next = init_task; init_task->next = init_task;
@ -108,13 +117,12 @@ void task_init(void (*init)(void))
mov %0, r0; \ mov %0, r0; \
msr psp, r0; \ msr psp, r0; \
mrs r0, control; \ mrs r0, control; \
orr r0, r0, #2; \ orr r0, r0, #3; \
cpsie i; \ cpsie i; \
msr control, r0; \ msr control, r0; \
" : "=r" (current->sp)); " : "=r" (current->sp));
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; task_doexit();
while (1);
} }
void task_start(void (*task)(void), uint16_t stackSize) void task_start(void (*task)(void), uint16_t stackSize)

Loading…
Cancel
Save