folder restructure

master
Clyne Sullivan 6 years ago
parent 231c796f50
commit c66410f631

@ -25,37 +25,26 @@ AS = as
MCUFLAGS = -mthumb -mcpu=cortex-m4 #-mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS)
CFLAGS = $(MCUFLAGS) -ggdb \
-Iinclude -Iinclude/cmsis \
-I.. \
-fno-builtin -fsigned-char -ffreestanding \
-Wall -Werror -Wextra -pedantic \
-Wno-overlength-strings -Wno-discarded-qualifiers
LFLAGS = -T link.ld
CFILES = $(wildcard src/*.c)
AFILES = $(wildcard src/*.s)
OUT = main.elf
OUTDIR = out
OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
export
OUT = out/main.elf
all: $(OUT)
$(OUT): $(OFILES)
all:
@$(MAKE) -C src/kernel
@$(MAKE) -C src/user
@echo " LINK " $(OUT)
@$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT)
@$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -o $(OUT) $$(find src/ -name "*.o")
$(OUTDIR)/%.o: src/%.c
@echo " CC " $<
@$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
$(OUTDIR)/%.asm.o: src/%.s
@echo " AS " $<
@$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
clean:
@echo " CLEAN"
@rm -rf out/*
@$(MAKE) -C src/kernel clean
@$(MAKE) -C src/user clean
@rm -f $(OUT)

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

@ -0,0 +1,22 @@
CFILES = $(wildcard *.c)
AFILES = $(wildcard *.s)
OFILES = $(patsubst %.c, %.o, $(CFILES)) \
$(patsubst %.s, %.asm.o, $(AFILES))
CFLAGS += -I.. -I../arch/cmsis
all: $(OFILES)
%.o: %.c
@echo " CC " $<
@$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
%.asm.o: %.s
@echo " AS " $<
@$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
clean:
@echo " CLEAN"
@rm -f $(OFILES)

@ -18,12 +18,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <clock.h>
#include <stm32l476xx.h>
#include "clock.h"
#include <arch/stm/stm32l476xx.h>
// ticks since init
volatile uint32_t ticks = 0;
volatile uint8_t tim2_finished = 1;
void clock_svc(uint32_t *args)
{
udelay(args[0]);
}
void clock_init(void)
{
// turn on HSI (16MHz)
@ -53,6 +60,15 @@ void clock_init(void)
// SysTick init. 80MHz / 80000 = 1kHz, ms precision
SysTick->LOAD = 80000;
SysTick->CTRL |= 0x07; // no div, interrupt, enable
// Prepare TIM2 for microsecond timing
NVIC_EnableIRQ(TIM2_IRQn);
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
TIM2->DIER |= TIM_DIER_UIE;
TIM2->PSC = 40 - 1;
TIM2->ARR = 100;
TIM2->CR1 |= TIM_CR1_OPM | TIM_CR1_CEN;
}
void delay(uint32_t count)
@ -61,12 +77,27 @@ void delay(uint32_t count)
while (ticks < target);
}
void udelay(uint32_t count)
{
tim2_finished = 0;
TIM2->ARR = count;
TIM2->CR1 |= TIM_CR1_CEN;
while (tim2_finished == 0);
}
void SysTick_Handler(void)
{
// just keep counting
ticks++;
// task switch every four ticks (4ms)
if (!(ticks & 3))
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
}
void TIM2_IRQHandler(void)
{
TIM2->SR &= ~(TIM_SR_UIF);
tim2_finished |= 1;
}

@ -1,6 +1,6 @@
/**
* @file clock.h
* Basic clock utilities
* Clock utilities
*
* Copyright (C) 2018 Clyne Sullivan
*
@ -30,8 +30,14 @@ extern void clock_init(void);
/**
* Sleeps for given amount of milliseconds.
* @param ms number of milliseconds to sleep for
* @param ms Number of milliseconds to sleep for
*/
void delay(uint32_t ms);
/**
* Sleeps for the given amount of microseconds.
* @param count Number of microseconds to sleep for
*/
void udelay(uint32_t count);
#endif // CLOCK_H_

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <gpio.h>
#include "gpio.h"
static const GPIO_TypeDef *gpio_ports[8] = {
GPIOA, GPIOB, GPIOC, GPIOD,

@ -1,6 +1,6 @@
/**
* @file gpio.h
* Abstracts gpio access, makes things easier
* GPIO Abstraction and access
*
* Copyright (C) 2018 Clyne Sullivan
*
@ -21,17 +21,17 @@
#ifndef GPIO_H_
#define GPIO_H_
#include <stm32l476xx.h>
#include <arch/stm/stm32l476xx.h>
/**
* Helps simplify gpio calls.
* @param p port, e.g. GPIOA
* @param b pin, e.g. 4
* @param p Port, e.g. A
* @param b Pin, e.g. 4
*/
#define GPIO_PORT(p, b) GPIO##p, b
/**
* Defines possible modes for a gpio pin
* Defines possible modes for a gpio pin.
*/
enum GPIO_MODE
{
@ -72,59 +72,59 @@ enum GPIO_PUPD
};
/**
* Initializes the gpio.
* Prepares for GPIO usage.
*/
void gpio_init(void);
/**
* Enables or disables pullup/pulldown for the given pin.
* @param port the port, e.g. GPIOA
* @param pin the pin
* @param pupd pullup/pulldown enable
* @param port The port, e.g. GPIOA
* @param pin The pin
* @param pupd Pullup/pulldown enable
* @see GPIO_PUPD
*/
void gpio_pupd(GPIO_TypeDef *port, uint32_t pin, uint32_t pupd);
/**
* Sets whether to use push-pull or open drain for the given pin.
* @param port the port
* @param pin the pin
* @param type what to use
* @param port The port
* @param pin The pin
* @param type What type to use
* @see GPIO_TYPE
*/
void gpio_type(GPIO_TypeDef *port, uint32_t pin, uint32_t type);
/**
* Sets the pin's speed.
* @param port the port
* @param pin the pin
* @param speed the speed to use
* @param port The port
* @param pin The pin
* @param speed The speed to use
* @see GPIO_SPEED
*/
void gpio_speed(GPIO_TypeDef *port, uint32_t pin, uint32_t speed);
/**
* Sets the pin's i/o mode.
* @param port the port
* @param pin the pin
* @param mode the mode to use
* @param port The port
* @param pin The pin
* @param mode The mode to use
* @see GPIO_MODE
*/
void gpio_mode(GPIO_TypeDef *port, uint32_t pin, uint32_t mode);
/**
* Sets the state of a digital output pin.
* @param port the port
* @param pin the pin
* @param val non-zero for high, zero for low
* @param port The port
* @param pin The pin
* @param val Non-zero for high, zero for low
*/
void gpio_dout(GPIO_TypeDef *port, uint32_t pin, uint32_t val);
/**
* Reads a digital input pin.
* @param port the port
* @param pin the pin
* @return non-zero for high, zero for low
* @param port The port
* @param pin The pin
* @return Non-zero for high, zero for low
*/
uint32_t gpio_din(GPIO_TypeDef *port, uint32_t pin);

@ -18,10 +18,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <heap.h>
#include "heap.h"
#define HEAP_ALIGN 4
typedef struct {
uint32_t size;
void *next;
} __attribute__ ((packed)) alloc_t;
static alloc_t *free_blocks;
static void *heap_end;

@ -23,43 +23,38 @@
#include <stdint.h>
typedef struct {
uint32_t size;
void *next;
} __attribute__ ((packed)) alloc_t;
/**
* Initializes memory management of the given heap.
* No overflow stuff is done, so...
* @param buf the heap to use for allocations
* No overflow stuff is done, so... be careful.
* @param buf The heap to use for allocations
*/
void heap_init(void *buf);
/**
* Returns the amount of free memory, in bytes.
* @return amount of free memory in bytes
* Returns the amount of free, allocatable memory, in bytes.
* @return Amount of free memory in bytes
*/
uint32_t heap_free(void);
/**
* Allocates a chunk of memory.
* @param size how many bytes to claim
* @return pointer to the allocated buffer
* @param size How many bytes to claim
* @return Pointer to the allocated buffer
*/
void *malloc(uint32_t size);
/**
* Allocates and zeros a chunk of memory.
* @param count how many of whatever to allocate
* @param size byte count of each whatever
* @return pointer to the allocated buffer
* @param count How many of whatever to allocate
* @param size Byte count of each whatever
* @return Pointer to the allocated buffer
*/
void *calloc(uint32_t count, uint32_t size);
/**
* Frees the buffer allocated through malloc/calloc.
* Please don't double-free.
* @param the buffer to release
* @param The buffer to release
*/
void free(void *buf);

@ -1,6 +1,6 @@
/**
* @file main.c
* Entry point for operating system
* @file init.c
* Kernel initialization procedure
*
* Copyright (C) 2018 Clyne Sullivan
*
@ -18,16 +18,15 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <clock.h>
#include <gpio.h>
#include <priv_gpio.h>
#include <heap.h>
#include <stm32l476xx.h>
#include <task.h>
#include "clock.h"
#include "gpio.h"
#include "heap.h"
#include "task.h"
#include <arch/stm/stm32l476xx.h>
extern uint8_t __bss_end__;
void kmain(void);
extern void user_main(void);
int main(void)
{
@ -47,35 +46,7 @@ int main(void)
// enable FPU
//SCB->CPACR |= (0xF << 20);
task_init(kmain);
task_init(user_main);
while (1);
}
void task2(void);
void kmain(void)
{
gpio(GPIO_MODE, 5, OUTPUT);
task_start(task2, 512);
for (int i = 0; i < 8; i++) {
gpio(GPIO_OUT, 5, !(i & 1));
delay(200);
}
}
void task3(void);
void task2(void)
{
delay(400);
task_start(task3, 1024);
}
void task3(void)
{
int state = 0;
delay(2500);
while (1) {
gpio(GPIO_OUT, 5, state ^= 1);
delay(500);
}
}

@ -20,11 +20,12 @@
*/
#include <stdint.h>
#include <gpio.h>
#include <clock.h>
#include <task.h>
#include "gpio.h"
#include "clock.h"
#include "task.h"
extern void gpio_svc(uint32_t *);
extern void clock_svc(uint32_t *);
void svc_handler(uint32_t *args)
{
@ -38,6 +39,8 @@ void svc_handler(uint32_t *args)
case 1:
gpio_svc(args);
break;
case 2:
clock_svc(args);
default:
break;
}

@ -18,9 +18,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <task.h>
#include <heap.h>
#include <stm32l476xx.h>
#include "task.h"
#include "heap.h"
#include <arch/stm/stm32l476xx.h>
task_t *current, *prev;
static uint8_t task_disable = 0;
@ -167,6 +167,7 @@ void PendSV_Handler(void)
asm("bx lr");
// TODO why, and what does this do
// TODO get back to c, implement task sleeping
asm("\
mrs r0, psp; \
isb; \

@ -54,8 +54,10 @@ void task_start(void (*task)(void), uint16_t stackSize);
*/
void task_hold(uint8_t hold);
/**
* Frees the task's resources and removes it from the running task list.
* @param code An unused exit code
*/
void _exit(int code);
//int fork(void);
#endif // TASK_H_

@ -0,0 +1,22 @@
CFILES = $(wildcard *.c)
AFILES = $(wildcard *.s)
OFILES = $(patsubst %.c, %.o, $(CFILES)) \
$(patsubst %.s, %.asm.o, $(AFILES))
CFLAGS += -I.. -I../arch/cmsis
all: $(OFILES)
%.o: %.c
@echo " CC " $<
@$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
%.asm.o: %.s
@echo " AS " $<
@$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
clean:
@echo " CLEAN"
@rm -f $(OFILES)

@ -0,0 +1,58 @@
/**
* @file priv_gpio.h
* GPIO access for unpriviledged processes
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef PRIV_GPIO_H_
#define PRIV_GPIO_H_
// For value flags
#include <kernel/gpio.h>
/**
* Possible GPIO calls.
*/
enum GPIO_CALLS {
GPIO_MODE = 0, /**< Change GPIO mode */
GPIO_TYPE, /**< Change GPIO type (PuPd/ODrain) */
GPIO_PUPD, /**< Set/clear pullup/pulldown */
GPIO_SPEED, /**< Set GPIO speed */
GPIO_OUT, /**< Set GPIO output state */
};
/**
* Provides unpriviledged GPIO access.
* @param call The type of GPIO call to make
* @param pin The pin to modify (0-15 = A, 16-31 = B, ...)
* @param value The value to pass to the call
*/
void gpio(uint32_t call, uint32_t pin, uint32_t value)
{
register uint32_t r0 asm("r0") = call;
register uint32_t r1 asm("r1") = pin;
register uint32_t r2 asm("r2") = value;
asm("\
mov r0, %0; \
mov r1, %1; \
mov r2, %2; \
svc 1; \
" :: "r" (r0), "r" (r1), "r" (r2));
}
#endif // PRIV_GPIO_H_

@ -0,0 +1,35 @@
#include <kernel/clock.h>
#include "priv_gpio.h"
#include <kernel/task.h>
void task1(void);
void task2(void);
void user_main(void)
{
gpio(GPIO_MODE, 5, OUTPUT);
task_start(task1, 512);
for (int i = 0; i < 8; i++) {
gpio(GPIO_OUT, 5, !(i & 1));
delay(200);
}
}
void task1(void)
{
delay(400);
task_start(task2, 1024);
}
void task2(void)
{
int state = 0;
delay(2500);
while (1) {
gpio(GPIO_OUT, 5, state ^= 1);
delay(500);
}
}
Loading…
Cancel
Save