diff --git a/Demo/Drivers/uart.c b/Demo/Drivers/uart.c new file mode 100644 index 0000000..281ca7e --- /dev/null +++ b/Demo/Drivers/uart.c @@ -0,0 +1,68 @@ +#include + +static inline void mmio_write(uint32_t reg, uint32_t data) +{ + *(volatile uint32_t *)reg = data; +} + +static inline uint32_t mmio_read(uint32_t reg) +{ + return *(volatile uint32_t *)reg; +} + +enum +{ + // The GPIO registers base address. + GPIO_BASE = 0x20200000, + + // The offsets for reach register. + + // Controls actuation of pull up/down to ALL GPIO pins. + GPPUD = (GPIO_BASE + 0x94), + + // Controls actuation of pull up/down for specific GPIO pin. + GPPUDCLK0 = (GPIO_BASE + 0x98), + + // The base address for UART. + UART0_BASE = 0x20201000, + + // The offsets for reach register for the UART. + UART0_DR = (UART0_BASE + 0x00), + UART0_RSRECR = (UART0_BASE + 0x04), + UART0_FR = (UART0_BASE + 0x18), + UART0_ILPR = (UART0_BASE + 0x20), + UART0_IBRD = (UART0_BASE + 0x24), + UART0_FBRD = (UART0_BASE + 0x28), + UART0_LCRH = (UART0_BASE + 0x2C), + UART0_CR = (UART0_BASE + 0x30), + UART0_IFLS = (UART0_BASE + 0x34), + UART0_IMSC = (UART0_BASE + 0x38), + UART0_RIS = (UART0_BASE + 0x3C), + UART0_MIS = (UART0_BASE + 0x40), + UART0_ICR = (UART0_BASE + 0x44), + UART0_DMACR = (UART0_BASE + 0x48), + UART0_ITCR = (UART0_BASE + 0x80), + UART0_ITIP = (UART0_BASE + 0x84), + UART0_ITOP = (UART0_BASE + 0x88), + UART0_TDR = (UART0_BASE + 0x8C), +}; + +void uartPutC(unsigned char byte) +{ + // Wait for UART to become ready to transmit. + while ( mmio_read(UART0_FR) & (1 << 5) ) { } + mmio_write(UART0_DR, byte); +} + +void uartPutS(const char *s) { + while (*s) { + uartPutC(*s++); + } +} + +void uartPutI(const unsigned int i){ + + if(i/10 > 0) + uartPutI(i/10); + uartPutC('0' + (i%10)); +} diff --git a/Demo/Drivers/uart.h b/Demo/Drivers/uart.h new file mode 100644 index 0000000..a678c0b --- /dev/null +++ b/Demo/Drivers/uart.h @@ -0,0 +1,8 @@ +#ifndef _UART_H_ +#define _UART_H_ + +void uartPutC(unsigned char byte); +void uartPutS(const char *s); +void uartPutI(const unsigned int i); + +#endif diff --git a/Demo/main.c b/Demo/main.c index b2fdfb6..5bea598 100644 --- a/Demo/main.c +++ b/Demo/main.c @@ -4,25 +4,73 @@ #include "Drivers/interrupts.h" #include "Drivers/gpio.h" -void task1(void *pParam) { - - int i = 0; - while(1) { - i++; - SetGpio(16, 1); - vTaskDelay(200); - } +/* void task1(void *pParam) { */ + +/* int i = 0; */ +/* while(1) { */ +/* i++; */ +/* SetGpio(16, 1); */ +/* vTaskDelay(200); */ +/* } */ +/* } */ + +/* void task2(void *pParam) { */ + +/* int i = 0; */ +/* while(1) { */ +/* i++; */ +/* vTaskDelay(100); */ +/* SetGpio(16, 0); */ +/* vTaskDelay(100); */ +/* } */ +/* } */ + +static inline void __my_delay(void){ + int i; + + for(i=0;i<10000/*00*/;i++) + asm volatile("nop"); +} + +#define __dsb() __asm__ __volatile__ ("mcr p15,0,%[t],c7,c10,4\n" :: [t] "r" (0) : "memory"); + +#define __isb(x) __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory") +void taskSingle(void* param) +{ + int i; + + for(i=0;i<10;i++) + { + SetGpio(16, 0); + uartPutS("\t--- task single ---\n"); + __my_delay(); + /* __dsb(); */ + /* __isb(); */ + taskYIELD(); + } + + vTaskDelete(NULL); } -void task2(void *pParam) { +void taskDuo(void* param){ + int i; + for(i=0;i<10;i++) { + SetGpio(16, 1); + uartPutS("+++ task duo +++\n"); + __my_delay(); + /* __dsb(); */ + /* __isb(); */ + taskYIELD(); + } - int i = 0; - while(1) { - i++; - vTaskDelay(100); - SetGpio(16, 0); - vTaskDelay(100); - } + vTaskDelete(NULL); +} +void taskEnd(void* param){ + uartPutS("before udf\n"); + + asm volatile("udf"); + + uartPutS("after udf\n"); } @@ -32,23 +80,53 @@ void task2(void *pParam) { * -- Absolutely nothing wrong with this being called main(), just it doesn't have * -- the same prototype as you'd see in a linux program. **/ -void main(void) { +/* void print_cpu_mode(unsigned int psr) */ +/* { */ +/* uartPutS("CPU Mode: "); */ +/* switch (psr & 0x1F) */ +/* { */ +/* case 0b10000: uartPutS("User"); break; */ +/* case 0b10001: uartPutS("FIQ"); break; */ +/* case 0b10010: uartPutS("IRQ"); break; */ +/* case 0b10011: uartPutS("Supervisor"); break; */ +/* case 0b10111: uartPutS("Abort"); break; */ +/* case 0b11011: uartPutS("Undefined"); break; */ +/* case 0b11111: uartPutS("System"); break; */ +/* case 0b10110: uartPutS("Monitor"); break; */ +/* default: uartPutS("Shut the fuck up"); */ +/* } */ +/* uartPutC('\n'); */ +/* } */ + +/* unsigned int read_cpsr(void) */ +/* { */ +/* unsigned int psr = -1; */ + +/* asm volatile("mrs %0, cpsr" : : "r"(psr)); */ - DisableInterrupts(); - InitInterruptController(); +/* return psr; */ +/* } */ - SetGpioFunction(16, 1); // RDY led +void main(void) { + + /* print_cpu_mode(read_cpsr()); */ - xTaskCreate(task1, "LED_0", 128, NULL, 0, NULL); - xTaskCreate(task2, "LED_1", 128, NULL, 0, NULL); + DisableInterrupts(); + InitInterruptController(); - vTaskStartScheduler(); + /* SetGpioFunction(16, 1); // RDY led */ + + xTaskCreate(taskDuo, "Duo Task", 128, NULL, 1, NULL); + xTaskCreate(taskSingle, "Single Task", 128, NULL, 1, NULL); + //xTaskCreate(taskEnd, "End Task", 128, NULL, 0, NULL); + uartPutS("Hop hop go working\n\n"); + vTaskStartScheduler(); - /* - * We should never get here, but just in case something goes wrong, - * we'll place the CPU into a safe loop. - */ - while(1) { - ; - } + /* + * We should never get here, but just in case something goes wrong, + * we'll place the CPU into a safe loop. + */ + while(1) { + ; + } } diff --git a/Makefile b/Makefile index f4b3e80..4171294 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,19 @@ LINKER_SCRIPT=raspberrypi.ld -include .dbuild/dbuild.mk +QEMU_PATH = /home/fser/code/qemu-raspi/arm-softmmu/ +QEMU = $(QEMU_PATH)/qemu-system-arm + + + +.PHONY: emu +emu: all + $(QEMU) -kernel kernel.elf -cpu arm1176 -m 512 -M raspi -nographic + +.PHONY: debug-emu +debug-emu: all + $(QEMU) -s -S -kernel kernel.elf -cpu arm1176 -m 512 -M raspi -nographic + all: kernel.list kernel.img kernel.syms @$(SIZE) kernel.elf @@ -29,7 +42,7 @@ kernel.syms: kernel.elf #kernel.elf: LDFLAGS += -L "/opt/Xilinx/14.2/ISE_DS/EDK/gnu/arm/lin64/lib/gcc/arm-xilinx-eabi/4.6.1/" -lgcc #kernel.elf: LDFLAGS += -L "/opt/Xilinx/14.2/ISE_DS/EDK/gnu/arm/lin64/arm-xilinx-eabi/lib/" -lc -kernel.elf: LDFLAGS += -L "/usr/lib/gcc/arm-none-eabi/4.7.4" -lgcc -kernel.elf: LDFLAGS += -L "/usr/arm-none-eabi/lib" -lc +kernel.elf: LDFLAGS += -L "/usr/lib/gcc/arm-none-eabi/4.9.3/" -lgcc +kernel.elf: LDFLAGS += -L "/usr/arm-none-eabi/lib/" -lc kernel.elf: $(OBJECTS) $(Q)$(LD) $(OBJECTS) -Map kernel.map -o $@ -T $(LINKER_SCRIPT) $(LDFLAGS) diff --git a/objects.mk b/objects.mk index 24d7c5c..f9d3c20 100644 --- a/objects.mk +++ b/objects.mk @@ -11,7 +11,7 @@ OBJECTS += $(BUILD_DIR)FreeRTOS/Source/croutine.o OBJECTS += $(BUILD_DIR)FreeRTOS/Source/list.o OBJECTS += $(BUILD_DIR)FreeRTOS/Source/queue.o OBJECTS += $(BUILD_DIR)FreeRTOS/Source/tasks.o - +OBJECTS += $(BUILD_DIR)Demo/Drivers/uart.o # # Interrupt Manager & GPIO Drivers #