From 5a3f22617b02ec366461be21765e636e6bdd0222 Mon Sep 17 00:00:00 2001 From: inmarket Date: Mon, 6 Oct 2014 17:05:16 +1000 Subject: Add support for FreeRTOS into make system --- boards/base/RaspberryPi/FreeRTOS/bcm2835_intc.h | 45 ++++++ boards/base/RaspberryPi/FreeRTOS/freertos_main.c | 62 ++++++++ boards/base/RaspberryPi/FreeRTOS/gpio.c | 134 +++++++++++++++++ boards/base/RaspberryPi/FreeRTOS/gpio.h | 48 ++++++ boards/base/RaspberryPi/FreeRTOS/interrupts.c | 166 +++++++++++++++++++++ boards/base/RaspberryPi/FreeRTOS/interrupts.h | 25 ++++ boards/base/RaspberryPi/FreeRTOS/mmio.h | 24 +++ boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld | 70 +++++++++ boards/base/RaspberryPi/FreeRTOS/startup.s | 102 +++++++++++++ boards/base/RaspberryPi/FreeRTOS/uart.c | 125 ++++++++++++++++ boards/base/RaspberryPi/FreeRTOS/uart.h | 25 ++++ .../example-FreeRTOS/Drivers/bcm2835_intc.h | 45 ------ .../RaspberryPi/example-FreeRTOS/Drivers/gpio.c | 134 ----------------- .../RaspberryPi/example-FreeRTOS/Drivers/gpio.h | 48 ------ .../example-FreeRTOS/Drivers/interrupts.c | 166 --------------------- .../example-FreeRTOS/Drivers/interrupts.h | 25 ---- .../RaspberryPi/example-FreeRTOS/Drivers/mmio.h | 24 --- .../RaspberryPi/example-FreeRTOS/Drivers/uart.c | 125 ---------------- .../RaspberryPi/example-FreeRTOS/Drivers/uart.h | 25 ---- boards/base/RaspberryPi/example-FreeRTOS/Makefile | 128 +++++++--------- boards/base/RaspberryPi/example-FreeRTOS/main.c | 82 ---------- .../RaspberryPi/example-FreeRTOS/raspberrypi.ld | 70 --------- boards/base/RaspberryPi/example-FreeRTOS/startup.s | 102 ------------- tools/gmake_scripts/cpu_armv6.mk | 18 +++ tools/gmake_scripts/cpu_raspberrypi.mk | 18 +++ tools/gmake_scripts/os_freertos.mk | 36 +++++ tools/gmake_scripts/readme.txt | 2 +- 27 files changed, 954 insertions(+), 920 deletions(-) create mode 100644 boards/base/RaspberryPi/FreeRTOS/bcm2835_intc.h create mode 100644 boards/base/RaspberryPi/FreeRTOS/freertos_main.c create mode 100644 boards/base/RaspberryPi/FreeRTOS/gpio.c create mode 100644 boards/base/RaspberryPi/FreeRTOS/gpio.h create mode 100644 boards/base/RaspberryPi/FreeRTOS/interrupts.c create mode 100644 boards/base/RaspberryPi/FreeRTOS/interrupts.h create mode 100644 boards/base/RaspberryPi/FreeRTOS/mmio.h create mode 100644 boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld create mode 100644 boards/base/RaspberryPi/FreeRTOS/startup.s create mode 100644 boards/base/RaspberryPi/FreeRTOS/uart.c create mode 100644 boards/base/RaspberryPi/FreeRTOS/uart.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/main.c delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld delete mode 100644 boards/base/RaspberryPi/example-FreeRTOS/startup.s create mode 100644 tools/gmake_scripts/cpu_armv6.mk create mode 100644 tools/gmake_scripts/cpu_raspberrypi.mk create mode 100644 tools/gmake_scripts/os_freertos.mk diff --git a/boards/base/RaspberryPi/FreeRTOS/bcm2835_intc.h b/boards/base/RaspberryPi/FreeRTOS/bcm2835_intc.h new file mode 100644 index 00000000..9f87b88e --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/bcm2835_intc.h @@ -0,0 +1,45 @@ +#ifndef _BCM2835_INTC_H_ +#define _BCM2835_INTC_H_ + +//#include "bcm2835.h" + +#define BCM2835_INTC_TOTAL_IRQ 64 + 8 + +#define BCM2835_BASE_INTC (0x2000B200) +#define BCM2835_INTC_IRQ_BASIC (BCM2835_BASE_INTC + 0x00) +#define BCM2835_IRQ_PENDING1 (BCM2835_BASE_INTC + 0x04) +#define BCM2835_IRQ_PENDING2 (BCM2835_BASE_INTC + 0x08) +#define BCM2835_IRQ_FIQ_CTRL (BCM2835_BASE_INTC + 0x0C) +#define BCM2835_IRQ_ENABLE1 (BCM2835_BASE_INTC + 0x10) +#define BCM2835_IRQ_ENABLE2 (BCM2835_BASE_INTC + 0x14) +#define BCM2835_IRQ_ENABLE_BASIC (BCM2835_BASE_INTC + 0x18) +#define BCM2835_IRQ_DISABLE1 (BCM2835_BASE_INTC + 0x1C) +#define BCM2835_IRQ_DISABLE2 (BCM2835_BASE_INTC + 0x20) +#define BCM2835_IRQ_DISABLE_BASIC (BCM2835_BASE_INTC + 0x24) + + + + +#define BCM2835_IRQ_ID_AUX 29 +#define BCM2835_IRQ_ID_SPI_SLAVE 43 +#define BCM2835_IRQ_ID_PWA0 45 +#define BCM2835_IRQ_ID_PWA1 46 +#define BCM2835_IRQ_ID_SMI 48 +#define BCM2835_IRQ_ID_GPIO_0 49 +#define BCM2835_IRQ_ID_GPIO_1 50 +#define BCM2835_IRQ_ID_GPIO_2 51 +#define BCM2835_IRQ_ID_GPIO_3 52 +#define BCM2835_IRQ_ID_I2C 53 +#define BCM2835_IRQ_ID_SPI 54 +#define BCM2835_IRQ_ID_PCM 55 +#define BCM2835_IRQ_ID_UART 57 + + +#define BCM2835_IRQ_ID_TIMER_0 64 +#define BCM2835_IRQ_ID_MAILBOX_0 65 +#define BCM2835_IRQ_ID_DOORBELL_0 66 +#define BCM2835_IRQ_ID_DOORBELL_1 67 +#define BCM2835_IRQ_ID_GPU0_HALTED 68 + + +#endif diff --git a/boards/base/RaspberryPi/FreeRTOS/freertos_main.c b/boards/base/RaspberryPi/FreeRTOS/freertos_main.c new file mode 100644 index 00000000..821a679b --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/freertos_main.c @@ -0,0 +1,62 @@ +#include +#include + +#include "Drivers/interrupts.h" + +extern int main(void); + +static void mainTask(void *pvParameters) { + (void) pvParameters; + main(); +} + +/** + * This is the systems main entry, some call it a boot thread. + **/ +int FreeRTOS_Main(void) { + + DisableInterrupts(); + InitInterruptController(); + + xTaskCreate(mainTask, + (portCHAR *)"Main Task", + 128, + NULL, + 0, + NULL); + + vTaskStartScheduler(); + + /* + * We should never get here, but just in case something goes wrong, + * we'll place the CPU into a safe loop. + */ + while(1) { + ; + } + + return 0; +} + +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time task stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is + called if a task stack overflow is detected. Note the system/interrupt + stack is not checked. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* This function will be called by each tick interrupt if + configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be + added here, but the tick hook is called from an interrupt context, so + code must not attempt to block, and only the interrupt safe FreeRTOS API + functions can be used (those that end in FromISR()). */ +} diff --git a/boards/base/RaspberryPi/FreeRTOS/gpio.c b/boards/base/RaspberryPi/FreeRTOS/gpio.c new file mode 100644 index 00000000..485de897 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/gpio.c @@ -0,0 +1,134 @@ +/** + * Quick and very Dirty GPIO API. + * + **/ + +#include "gpio.h" + +typedef struct { + unsigned long GPFSEL[6]; ///< Function selection registers. + unsigned long Reserved_1; + unsigned long GPSET[2]; + unsigned long Reserved_2; + unsigned long GPCLR[2]; + unsigned long Reserved_3; + unsigned long GPLEV[2]; + unsigned long Reserved_4; + unsigned long GPEDS[2]; + unsigned long Reserved_5; + unsigned long GPREN[2]; + unsigned long Reserved_6; + unsigned long GPFEN[2]; + unsigned long Reserved_7; + unsigned long GPHEN[2]; + unsigned long Reserved_8; + unsigned long GPLEN[2]; + unsigned long Reserved_9; + unsigned long GPAREN[2]; + unsigned long Reserved_A; + unsigned long GPAFEN[2]; + unsigned long Reserved_B; + unsigned long GPPUD[1]; + unsigned long GPPUDCLK[2]; + //Ignoring the reserved and test bytes +} BCM2835_GPIO_REGS; + +volatile BCM2835_GPIO_REGS * const pRegs = (BCM2835_GPIO_REGS *) (0x20200000); + + +void SetGpioFunction(unsigned int pinNum, unsigned int funcNum) { + + int offset = pinNum / 10; + + unsigned long val = pRegs->GPFSEL[offset]; // Read in the original register value. + + int item = pinNum % 10; + val &= ~(0x7 << (item * 3)); + val |= ((funcNum & 0x7) << (item * 3)); + pRegs->GPFSEL[offset] = val; +} + +void SetGpioDirection(unsigned int pinNum, enum GPIO_DIR dir) { + SetGpioFunction(pinNum,dir); +} + +void SetGpio(unsigned int pinNum, unsigned int pinVal) { + unsigned long offset=pinNum/32; + unsigned long mask=(1<<(pinNum%32)); + + if(pinVal) { + pRegs->GPSET[offset]|=mask; + } else { + pRegs->GPCLR[offset]|=mask; + } +} + +int ReadGpio(unsigned int pinNum) { + return ((pRegs->GPLEV[pinNum/32])>>(pinNum%32))&1; +} + +void EnableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type) +{ + unsigned long mask=(1<GPREN[offset]|=mask; + break; + case DETECT_FALLING: + pRegs->GPFEN[offset]|=mask; + break; + case DETECT_HIGH: + pRegs->GPHEN[offset]|=mask; + break; + case DETECT_LOW: + pRegs->GPLEN[offset]|=mask; + break; + case DETECT_RISING_ASYNC: + pRegs->GPAREN[offset]|=mask; + break; + case DETECT_FALLING_ASYNC: + pRegs->GPAFEN[offset]|=mask; + break; + case DETECT_NONE: + break; + } +} + +void DisableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type) +{ + unsigned long mask=~(1<<(pinNum%32)); + unsigned long offset=pinNum/32; + + switch(type) { + case DETECT_RISING: + pRegs->GPREN[offset]&=mask; + break; + case DETECT_FALLING: + pRegs->GPFEN[offset]&=mask; + break; + case DETECT_HIGH: + pRegs->GPHEN[offset]&=mask; + break; + case DETECT_LOW: + pRegs->GPLEN[offset]&=mask; + break; + case DETECT_RISING_ASYNC: + pRegs->GPAREN[offset]&=mask; + break; + case DETECT_FALLING_ASYNC: + pRegs->GPAFEN[offset]&=mask; + break; + case DETECT_NONE: + break; + } +} + +void ClearGpioInterrupt(unsigned int pinNum) +{ + unsigned long mask=(1<<(pinNum%32)); + unsigned long offset=pinNum/32; + + pRegs->GPEDS[offset]=mask; +} diff --git a/boards/base/RaspberryPi/FreeRTOS/gpio.h b/boards/base/RaspberryPi/FreeRTOS/gpio.h new file mode 100644 index 00000000..fa459707 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/gpio.h @@ -0,0 +1,48 @@ +#ifndef _GPIO_H_ +#define _GPIO_H_ + +/* GPIO event detect types */ +enum DETECT_TYPE { + DETECT_NONE, + DETECT_RISING, + DETECT_FALLING, + DETECT_HIGH, + DETECT_LOW, + DETECT_RISING_ASYNC, + DETECT_FALLING_ASYNC +}; + +/* GPIO pull up or down states */ +enum PULL_STATE { + PULL_DISABLE, + PULL_UP, + PULL_DOWN, + PULL_RESERVED +}; + +/* Pin data direction */ +enum GPIO_DIR { + GPIO_IN, + GPIO_OUT +}; + +/* GPIO pin setup */ +void SetGpioFunction (unsigned int pinNum, unsigned int funcNum); +/* A simple wrapper around SetGpioFunction */ +void SetGpioDirection (unsigned int pinNum, enum GPIO_DIR dir); + +/* Set GPIO output level */ +void SetGpio (unsigned int pinNum, unsigned int pinVal); + +/* Read GPIO pin level */ +int ReadGpio (unsigned int pinNum); + +/* GPIO pull up/down resistor control function (NOT YET IMPLEMENTED) */ +int PudGpio (unsigned int pinNum, enum PULL_STATE state); + +/* Interrupt related functions */ +void EnableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type); +void DisableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type); +void ClearGpioInterrupt (unsigned int pinNum); + +#endif diff --git a/boards/base/RaspberryPi/FreeRTOS/interrupts.c b/boards/base/RaspberryPi/FreeRTOS/interrupts.c new file mode 100644 index 00000000..9908b7c4 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/interrupts.c @@ -0,0 +1,166 @@ +/** + * Integrated Interrupt Controller for RaspberryPi. + * @author James Walmsley + **/ + +#include "interrupts.h" +#include "bcm2835_intc.h" + +static INTERRUPT_VECTOR g_VectorTable[BCM2835_INTC_TOTAL_IRQ]; + + +typedef struct { + unsigned long IRQBasic; // Pending 0 + unsigned long Pending1; + unsigned long Pending2; + unsigned long FIQCtrl; + unsigned long Enable1; + unsigned long Enable2; + unsigned long EnableBasic; + unsigned long Disable1; + unsigned long Disable2; + unsigned long DisableBasic; +} BCM2835_INTC_REGS; + +static volatile BCM2835_INTC_REGS * const pRegs = (BCM2835_INTC_REGS *) (BCM2835_BASE_INTC); + +/** + * Enables all IRQ's in the CPU's CPSR register. + **/ +static void irqEnable() { + __asm volatile("mrs r0,cpsr"); // Read in the cpsr register. + __asm volatile("bic r0,r0,#0x80"); // Clear bit 8, (0x80) -- Causes IRQs to be enabled. + __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register +} + +static void irqDisable() { + __asm volatile("mrs r0,cpsr"); // Read in the cpsr register. + __asm volatile("orr r0,r0,#0x80"); // Set bit 8, (0x80) -- Causes IRQs to be disabled. + __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register. + +} + +#define clz(a) \ + ({ unsigned long __value, __arg = (a); \ + asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \ + __value; }) + +/** + * This is the global IRQ handler on this platform! + * It is based on the assembler code found in the Broadcom datasheet. + * + **/ +void irqHandler() { + register unsigned long ulMaskedStatus; + register unsigned long irqNumber; + + ulMaskedStatus = pRegs->IRQBasic; + + /* Bits 7 through 0 in IRQBasic represent interrupts 64-71 */ + if (ulMaskedStatus & 0xFF) { + irqNumber=64 + 31; + } + + /* Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0) */ + else if(ulMaskedStatus & 0x100) { + ulMaskedStatus = pRegs->Pending1; + irqNumber = 0 + 31; + } + + /* Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32) */ + else if(ulMaskedStatus & 0x200) { + ulMaskedStatus = pRegs->Pending2; + irqNumber = 32 + 31; + } + + else { + // No interrupt avaialbe, so just return. + return; + } + + /* Keep only least significant bit, in case multiple interrupts have occured */ + ulMaskedStatus&=-ulMaskedStatus; + /* Some magic to determine number of interrupt to serve */ + irqNumber=irqNumber-clz(ulMaskedStatus); + /* Call interrupt handler */ + g_VectorTable[irqNumber].pfnHandler(irqNumber, g_VectorTable[irqNumber].pParam); +} + + +static void stubHandler(int nIRQ, void *pParam) { + /** + * Actually if we get here, we should probably disable the IRQ, + * otherwise we could lock up this system, as there is nothing to + * ackknowledge the interrupt. + **/ +} + +int InitInterruptController() { + int i; + for(i = 0; i < BCM2835_INTC_TOTAL_IRQ; i++) { + g_VectorTable[i].pfnHandler = stubHandler; + g_VectorTable[i].pParam = (void *) 0; + } + return 0; +} + + + +int RegisterInterrupt(int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam) { + if(nIRQ<0 || nIRQ>71) + return -1; + + irqDisable(); + { + g_VectorTable[nIRQ].pfnHandler = pfnHandler; + g_VectorTable[nIRQ].pParam = pParam; + } + irqEnable(); + return 0; +} + +int EnableInterrupt(int nIRQ) { + /* Datasheet says "All other bits are unaffected", and I'm counting on that. */ + unsigned int mask=1<<(nIRQ%32); + + if(nIRQ >=0 && nIRQ <=31) { + pRegs->Enable1 = mask; + } else + if(nIRQ >=32 && nIRQ <=63){ + pRegs->Enable2 = mask; + } else + if(nIRQ >= 64 && nIRQ <= 71) { // Basic IRQ enables + pRegs->EnableBasic = mask; + } else + return -1; + + return 0; +} + +int DisableInterrupt(int nIRQ) { + /* Datasheet says "All other bits are unaffected", and I'm counting on that. */ + unsigned int mask=1<<(nIRQ%32); + + if(nIRQ >=0 && nIRQ <=31) { + pRegs->Disable1 = mask; + } else + if(nIRQ >=32 && nIRQ <=63){ + pRegs->Disable2 = mask; + } else + if(nIRQ >= 64 && nIRQ <= 71) { + pRegs->DisableBasic = mask; + } else + return -1; + + return 0; +} + +int EnableInterrupts() { + irqEnable(); + return 0; +} + +int DisableInterrupts() { + irqDisable(); + return 0; +} diff --git a/boards/base/RaspberryPi/FreeRTOS/interrupts.h b/boards/base/RaspberryPi/FreeRTOS/interrupts.h new file mode 100644 index 00000000..d09353a4 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/interrupts.h @@ -0,0 +1,25 @@ +/** + * Tiny Interrupt Manager + * + * @author James Walmsley + * This code is licensed under the GNU GPLv3 license. + **/ + +#ifndef _INTERRUPTS_H_ +#define _INTERRUPTS_H_ + +typedef void (*FN_INTERRUPT_HANDLER)(int nIRQ, void *pParam); + +typedef struct { + FN_INTERRUPT_HANDLER pfnHandler; ///< Function that handles this IRQn + void *pParam; ///< A special parameter that the use can pass to the IRQ. +} INTERRUPT_VECTOR; + +int InitInterruptController (); +int RegisterInterrupt (int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam); +int EnableInterrupt (int nIRQ); +int DisableInterrupt (int nIRQ); +int EnableInterrupts (); +int DisableInterrupts (); + +#endif diff --git a/boards/base/RaspberryPi/FreeRTOS/mmio.h b/boards/base/RaspberryPi/FreeRTOS/mmio.h new file mode 100644 index 00000000..89bea700 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/mmio.h @@ -0,0 +1,24 @@ +/* mmio.h - access to MMIO registers */ + +#ifndef MMIO_H +#define MMIO_H + +#include + +// write to MMIO register +static inline void mmio_write(uint32_t reg, uint32_t data) { + uint32_t *ptr = (uint32_t*)reg; + asm volatile("str %[data], [%[reg]]" + : : [reg]"r"(ptr), [data]"r"(data)); +} + +// read from MMIO register +static inline uint32_t mmio_read(uint32_t reg) { + uint32_t *ptr = (uint32_t*)reg; + uint32_t data; + asm volatile("ldr %[data], [%[reg]]" + : [data]"=r"(data) : [reg]"r"(ptr)); + return data; +} + +#endif // #ifndef MMIO_H diff --git a/boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld b/boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld new file mode 100644 index 00000000..ece588b5 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld @@ -0,0 +1,70 @@ +/** + * BlueThunder Linker Script for the raspberry Pi! + * + * + * + **/ +MEMORY +{ + RESERVED (r) : ORIGIN = 0x00000000, LENGTH = 32K + INIT_RAM (rwx) : ORIGIN = 0x00008000, LENGTH = 32K + RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 128M +} + +ENTRY(_start) + +SECTIONS { + /* + * Our init section allows us to place the bootstrap code at address 0x8000 + * + * This is where the Graphics processor forces the ARM to start execution. + * However the interrupt vector code remains at 0x0000, and so we must copy the correct + * branch instructions to 0x0000 - 0x001C in order to get the processor to handle interrupts. + * + */ + .init : { + KEEP(*(.init)) + } > INIT_RAM = 0 + + .module_entries : { + __module_entries_start = .; + KEEP(*(.module_entries)) + KEEP(*(.module_entries.*)) + __module_entries_end = .; + __module_entries_size = SIZEOF(.module_entries); + } > INIT_RAM + + + /** + * This is the main code section, it is essentially of unlimited size. (128Mb). + * + **/ + .text : { + *(.text) + } > RAM + + /* + * Next we put the data. + */ + .data : { + *(.data) + } > RAM + + .bss : + { + __bss_start = .; + *(.bss) + *(.bss.*) + __bss_end = .; + } > RAM + + /** + * Place HEAP here??? + **/ + + /** + * Stack starts at the top of the RAM, and moves down! + **/ + _estack = ORIGIN(RAM) + LENGTH(RAM); +} + diff --git a/boards/base/RaspberryPi/FreeRTOS/startup.s b/boards/base/RaspberryPi/FreeRTOS/startup.s new file mode 100644 index 00000000..d865439f --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/startup.s @@ -0,0 +1,102 @@ +.extern system_init +.extern __bss_start +.extern __bss_end +.extern vFreeRTOS_ISR +.extern vPortYieldProcessor +.extern DisableInterrupts +.extern FreeRTOS_Main + .section .init + .globl _start +;; +_start: + ;@ All the following instruction should be read as: + ;@ Load the address at symbol into the program counter. + + ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi! + ;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset! + + ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb! + ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode. + ldr pc,prefetch_handler ;@ Prefetch/abort handler. + ldr pc,data_handler ;@ Data abort handler/ + ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler. + ldr pc,irq_handler ;@ IRQ handler + ldr pc,fiq_handler ;@ Fast interrupt handler. + + ;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses +reset_handler: .word reset +undefined_handler: .word undefined_instruction +swi_handler: .word vPortYieldProcessor +prefetch_handler: .word prefetch_abort +data_handler: .word data_abort +unused_handler: .word unused +irq_handler: .word vFreeRTOS_ISR +fiq_handler: .word fiq + +reset: + ;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000 + + mov r0,#0x8000 ;@ Store the source pointer + mov r1,#0x0000 ;@ Store the destination pointer. + + ;@ Here we copy the branching instructions + ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0 + stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1 + + ;@ So the branches get the correct address we also need to copy our vector table! + ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented. + stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data. + + + ;@ Set up the various STACK pointers for different CPU modes + ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD2 + msr cpsr_c,r0 + mov sp,#0x8000 + + ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD1 + msr cpsr_c,r0 + mov sp,#0x4000 + + ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) + mov r0,#0xD3 + msr cpsr_c,r0 + mov sp,#0x8000000 + + ldr r0, =__bss_start + ldr r1, =__bss_end + + mov r2, #0 + +zero_loop: + cmp r0,r1 + it lt + strlt r2,[r0], #4 + blt zero_loop + + bl DisableInterrupts + + + ;@ mov sp,#0x1000000 + b FreeRTOS_Main ;@ We're ready?? Lets start main execution! + .section .text + +undefined_instruction: + b undefined_instruction + +prefetch_abort: + b prefetch_abort + +data_abort: + b data_abort + +unused: + b unused + +fiq: + b fiq + +hang: + b hang + diff --git a/boards/base/RaspberryPi/FreeRTOS/uart.c b/boards/base/RaspberryPi/FreeRTOS/uart.c new file mode 100644 index 00000000..92f837e7 --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/uart.c @@ -0,0 +1,125 @@ +/* uart.c - UART initialization & communication */ +/* Reference material: + * http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf + * Chapter 13: UART + */ + +#include +#include +#include + +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), +}; + +/* + * delay function + * int32_t delay: number of cycles to delay + * + * This just loops times in a way that the compiler + * wont optimize away. + */ +static void delay(int32_t count) { + asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n" + : : [count]"r"(count) : "cc"); +} + +/* + * Initialize UART0. + */ +void uart_init() { + // Disable UART0. + mmio_write(UART0_CR, 0x00000000); + // Setup the GPIO pin 14 && 15. + + // Disable pull up/down for all GPIO pins & delay for 150 cycles. + mmio_write(GPPUD, 0x00000000); + delay(150); + + // Disable pull up/down for pin 14,15 & delay for 150 cycles. + mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15)); + delay(150); + + // Write 0 to GPPUDCLK0 to make it take effect. + mmio_write(GPPUDCLK0, 0x00000000); + + // Clear pending interrupts. + mmio_write(UART0_ICR, 0x7FF); + + // Set integer & fractional part of baud rate. + // Divider = UART_CLOCK/(16 * Baud) + // Fraction part register = (Fractional part * 64) + 0.5 + // UART_CLOCK = 3000000; Baud = 115200. + + // Divider = 3000000/(16 * 115200) = 1.627 = ~1. + // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40. + mmio_write(UART0_IBRD, 1); + mmio_write(UART0_FBRD, 40); + + // Enable FIFO & 8 bit data transmissio (1 stop bit, no parity). + mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6)); + + // Mask all interrupts. + mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | + (1 << 6) | (1 << 7) | (1 << 8) | + (1 << 9) | (1 << 10)); + + // Enable UART0, receive & transfer part of UART. + mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9)); +} + +/* + * Transmit a byte via UART0. + * uint8_t Byte: byte to send. + */ +void uart_putc(uint8_t byte) { + // wait for UART to become ready to transmit + while (1) { + if (!(mmio_read(UART0_FR) & (1 << 5))) { + break; + } + } + mmio_write(UART0_DR, byte); +} + +/* + * print a string to the UART one character at a time + * const char *str: 0-terminated string + */ +void uart_puts(const char *str) { + while (*str) { + uart_putc(*str++); + } +} diff --git a/boards/base/RaspberryPi/FreeRTOS/uart.h b/boards/base/RaspberryPi/FreeRTOS/uart.h new file mode 100644 index 00000000..fe7f64aa --- /dev/null +++ b/boards/base/RaspberryPi/FreeRTOS/uart.h @@ -0,0 +1,25 @@ +/* uart.h - UART initialization & communication */ + +#ifndef UART_H +#define UART_H + +#include + +/* + * Initialize UART0. + */ +void uart_init(); + +/* + * Transmit a byte via UART0. + * uint8_t Byte: byte to send. + */ +void uart_putc(uint8_t byte); + +/* + * print a string to the UART one character at a time + * const char *str: 0-terminated string + */ +void uart_puts(const char *str); + +#endif // #ifndef UART_H diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h deleted file mode 100644 index 9f87b88e..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/bcm2835_intc.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _BCM2835_INTC_H_ -#define _BCM2835_INTC_H_ - -//#include "bcm2835.h" - -#define BCM2835_INTC_TOTAL_IRQ 64 + 8 - -#define BCM2835_BASE_INTC (0x2000B200) -#define BCM2835_INTC_IRQ_BASIC (BCM2835_BASE_INTC + 0x00) -#define BCM2835_IRQ_PENDING1 (BCM2835_BASE_INTC + 0x04) -#define BCM2835_IRQ_PENDING2 (BCM2835_BASE_INTC + 0x08) -#define BCM2835_IRQ_FIQ_CTRL (BCM2835_BASE_INTC + 0x0C) -#define BCM2835_IRQ_ENABLE1 (BCM2835_BASE_INTC + 0x10) -#define BCM2835_IRQ_ENABLE2 (BCM2835_BASE_INTC + 0x14) -#define BCM2835_IRQ_ENABLE_BASIC (BCM2835_BASE_INTC + 0x18) -#define BCM2835_IRQ_DISABLE1 (BCM2835_BASE_INTC + 0x1C) -#define BCM2835_IRQ_DISABLE2 (BCM2835_BASE_INTC + 0x20) -#define BCM2835_IRQ_DISABLE_BASIC (BCM2835_BASE_INTC + 0x24) - - - - -#define BCM2835_IRQ_ID_AUX 29 -#define BCM2835_IRQ_ID_SPI_SLAVE 43 -#define BCM2835_IRQ_ID_PWA0 45 -#define BCM2835_IRQ_ID_PWA1 46 -#define BCM2835_IRQ_ID_SMI 48 -#define BCM2835_IRQ_ID_GPIO_0 49 -#define BCM2835_IRQ_ID_GPIO_1 50 -#define BCM2835_IRQ_ID_GPIO_2 51 -#define BCM2835_IRQ_ID_GPIO_3 52 -#define BCM2835_IRQ_ID_I2C 53 -#define BCM2835_IRQ_ID_SPI 54 -#define BCM2835_IRQ_ID_PCM 55 -#define BCM2835_IRQ_ID_UART 57 - - -#define BCM2835_IRQ_ID_TIMER_0 64 -#define BCM2835_IRQ_ID_MAILBOX_0 65 -#define BCM2835_IRQ_ID_DOORBELL_0 66 -#define BCM2835_IRQ_ID_DOORBELL_1 67 -#define BCM2835_IRQ_ID_GPU0_HALTED 68 - - -#endif diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c deleted file mode 100644 index 485de897..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - * Quick and very Dirty GPIO API. - * - **/ - -#include "gpio.h" - -typedef struct { - unsigned long GPFSEL[6]; ///< Function selection registers. - unsigned long Reserved_1; - unsigned long GPSET[2]; - unsigned long Reserved_2; - unsigned long GPCLR[2]; - unsigned long Reserved_3; - unsigned long GPLEV[2]; - unsigned long Reserved_4; - unsigned long GPEDS[2]; - unsigned long Reserved_5; - unsigned long GPREN[2]; - unsigned long Reserved_6; - unsigned long GPFEN[2]; - unsigned long Reserved_7; - unsigned long GPHEN[2]; - unsigned long Reserved_8; - unsigned long GPLEN[2]; - unsigned long Reserved_9; - unsigned long GPAREN[2]; - unsigned long Reserved_A; - unsigned long GPAFEN[2]; - unsigned long Reserved_B; - unsigned long GPPUD[1]; - unsigned long GPPUDCLK[2]; - //Ignoring the reserved and test bytes -} BCM2835_GPIO_REGS; - -volatile BCM2835_GPIO_REGS * const pRegs = (BCM2835_GPIO_REGS *) (0x20200000); - - -void SetGpioFunction(unsigned int pinNum, unsigned int funcNum) { - - int offset = pinNum / 10; - - unsigned long val = pRegs->GPFSEL[offset]; // Read in the original register value. - - int item = pinNum % 10; - val &= ~(0x7 << (item * 3)); - val |= ((funcNum & 0x7) << (item * 3)); - pRegs->GPFSEL[offset] = val; -} - -void SetGpioDirection(unsigned int pinNum, enum GPIO_DIR dir) { - SetGpioFunction(pinNum,dir); -} - -void SetGpio(unsigned int pinNum, unsigned int pinVal) { - unsigned long offset=pinNum/32; - unsigned long mask=(1<<(pinNum%32)); - - if(pinVal) { - pRegs->GPSET[offset]|=mask; - } else { - pRegs->GPCLR[offset]|=mask; - } -} - -int ReadGpio(unsigned int pinNum) { - return ((pRegs->GPLEV[pinNum/32])>>(pinNum%32))&1; -} - -void EnableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type) -{ - unsigned long mask=(1<GPREN[offset]|=mask; - break; - case DETECT_FALLING: - pRegs->GPFEN[offset]|=mask; - break; - case DETECT_HIGH: - pRegs->GPHEN[offset]|=mask; - break; - case DETECT_LOW: - pRegs->GPLEN[offset]|=mask; - break; - case DETECT_RISING_ASYNC: - pRegs->GPAREN[offset]|=mask; - break; - case DETECT_FALLING_ASYNC: - pRegs->GPAFEN[offset]|=mask; - break; - case DETECT_NONE: - break; - } -} - -void DisableGpioDetect(unsigned int pinNum, enum DETECT_TYPE type) -{ - unsigned long mask=~(1<<(pinNum%32)); - unsigned long offset=pinNum/32; - - switch(type) { - case DETECT_RISING: - pRegs->GPREN[offset]&=mask; - break; - case DETECT_FALLING: - pRegs->GPFEN[offset]&=mask; - break; - case DETECT_HIGH: - pRegs->GPHEN[offset]&=mask; - break; - case DETECT_LOW: - pRegs->GPLEN[offset]&=mask; - break; - case DETECT_RISING_ASYNC: - pRegs->GPAREN[offset]&=mask; - break; - case DETECT_FALLING_ASYNC: - pRegs->GPAFEN[offset]&=mask; - break; - case DETECT_NONE: - break; - } -} - -void ClearGpioInterrupt(unsigned int pinNum) -{ - unsigned long mask=(1<<(pinNum%32)); - unsigned long offset=pinNum/32; - - pRegs->GPEDS[offset]=mask; -} diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h deleted file mode 100644 index fa459707..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/gpio.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _GPIO_H_ -#define _GPIO_H_ - -/* GPIO event detect types */ -enum DETECT_TYPE { - DETECT_NONE, - DETECT_RISING, - DETECT_FALLING, - DETECT_HIGH, - DETECT_LOW, - DETECT_RISING_ASYNC, - DETECT_FALLING_ASYNC -}; - -/* GPIO pull up or down states */ -enum PULL_STATE { - PULL_DISABLE, - PULL_UP, - PULL_DOWN, - PULL_RESERVED -}; - -/* Pin data direction */ -enum GPIO_DIR { - GPIO_IN, - GPIO_OUT -}; - -/* GPIO pin setup */ -void SetGpioFunction (unsigned int pinNum, unsigned int funcNum); -/* A simple wrapper around SetGpioFunction */ -void SetGpioDirection (unsigned int pinNum, enum GPIO_DIR dir); - -/* Set GPIO output level */ -void SetGpio (unsigned int pinNum, unsigned int pinVal); - -/* Read GPIO pin level */ -int ReadGpio (unsigned int pinNum); - -/* GPIO pull up/down resistor control function (NOT YET IMPLEMENTED) */ -int PudGpio (unsigned int pinNum, enum PULL_STATE state); - -/* Interrupt related functions */ -void EnableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type); -void DisableGpioDetect (unsigned int pinNum, enum DETECT_TYPE type); -void ClearGpioInterrupt (unsigned int pinNum); - -#endif diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c deleted file mode 100644 index 9908b7c4..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.c +++ /dev/null @@ -1,166 +0,0 @@ -/** - * Integrated Interrupt Controller for RaspberryPi. - * @author James Walmsley - **/ - -#include "interrupts.h" -#include "bcm2835_intc.h" - -static INTERRUPT_VECTOR g_VectorTable[BCM2835_INTC_TOTAL_IRQ]; - - -typedef struct { - unsigned long IRQBasic; // Pending 0 - unsigned long Pending1; - unsigned long Pending2; - unsigned long FIQCtrl; - unsigned long Enable1; - unsigned long Enable2; - unsigned long EnableBasic; - unsigned long Disable1; - unsigned long Disable2; - unsigned long DisableBasic; -} BCM2835_INTC_REGS; - -static volatile BCM2835_INTC_REGS * const pRegs = (BCM2835_INTC_REGS *) (BCM2835_BASE_INTC); - -/** - * Enables all IRQ's in the CPU's CPSR register. - **/ -static void irqEnable() { - __asm volatile("mrs r0,cpsr"); // Read in the cpsr register. - __asm volatile("bic r0,r0,#0x80"); // Clear bit 8, (0x80) -- Causes IRQs to be enabled. - __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register -} - -static void irqDisable() { - __asm volatile("mrs r0,cpsr"); // Read in the cpsr register. - __asm volatile("orr r0,r0,#0x80"); // Set bit 8, (0x80) -- Causes IRQs to be disabled. - __asm volatile("msr cpsr_c, r0"); // Write it back to the CPSR register. - -} - -#define clz(a) \ - ({ unsigned long __value, __arg = (a); \ - asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \ - __value; }) - -/** - * This is the global IRQ handler on this platform! - * It is based on the assembler code found in the Broadcom datasheet. - * - **/ -void irqHandler() { - register unsigned long ulMaskedStatus; - register unsigned long irqNumber; - - ulMaskedStatus = pRegs->IRQBasic; - - /* Bits 7 through 0 in IRQBasic represent interrupts 64-71 */ - if (ulMaskedStatus & 0xFF) { - irqNumber=64 + 31; - } - - /* Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0) */ - else if(ulMaskedStatus & 0x100) { - ulMaskedStatus = pRegs->Pending1; - irqNumber = 0 + 31; - } - - /* Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32) */ - else if(ulMaskedStatus & 0x200) { - ulMaskedStatus = pRegs->Pending2; - irqNumber = 32 + 31; - } - - else { - // No interrupt avaialbe, so just return. - return; - } - - /* Keep only least significant bit, in case multiple interrupts have occured */ - ulMaskedStatus&=-ulMaskedStatus; - /* Some magic to determine number of interrupt to serve */ - irqNumber=irqNumber-clz(ulMaskedStatus); - /* Call interrupt handler */ - g_VectorTable[irqNumber].pfnHandler(irqNumber, g_VectorTable[irqNumber].pParam); -} - - -static void stubHandler(int nIRQ, void *pParam) { - /** - * Actually if we get here, we should probably disable the IRQ, - * otherwise we could lock up this system, as there is nothing to - * ackknowledge the interrupt. - **/ -} - -int InitInterruptController() { - int i; - for(i = 0; i < BCM2835_INTC_TOTAL_IRQ; i++) { - g_VectorTable[i].pfnHandler = stubHandler; - g_VectorTable[i].pParam = (void *) 0; - } - return 0; -} - - - -int RegisterInterrupt(int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam) { - if(nIRQ<0 || nIRQ>71) - return -1; - - irqDisable(); - { - g_VectorTable[nIRQ].pfnHandler = pfnHandler; - g_VectorTable[nIRQ].pParam = pParam; - } - irqEnable(); - return 0; -} - -int EnableInterrupt(int nIRQ) { - /* Datasheet says "All other bits are unaffected", and I'm counting on that. */ - unsigned int mask=1<<(nIRQ%32); - - if(nIRQ >=0 && nIRQ <=31) { - pRegs->Enable1 = mask; - } else - if(nIRQ >=32 && nIRQ <=63){ - pRegs->Enable2 = mask; - } else - if(nIRQ >= 64 && nIRQ <= 71) { // Basic IRQ enables - pRegs->EnableBasic = mask; - } else - return -1; - - return 0; -} - -int DisableInterrupt(int nIRQ) { - /* Datasheet says "All other bits are unaffected", and I'm counting on that. */ - unsigned int mask=1<<(nIRQ%32); - - if(nIRQ >=0 && nIRQ <=31) { - pRegs->Disable1 = mask; - } else - if(nIRQ >=32 && nIRQ <=63){ - pRegs->Disable2 = mask; - } else - if(nIRQ >= 64 && nIRQ <= 71) { - pRegs->DisableBasic = mask; - } else - return -1; - - return 0; -} - -int EnableInterrupts() { - irqEnable(); - return 0; -} - -int DisableInterrupts() { - irqDisable(); - return 0; -} diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h deleted file mode 100644 index d09353a4..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/interrupts.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Tiny Interrupt Manager - * - * @author James Walmsley - * This code is licensed under the GNU GPLv3 license. - **/ - -#ifndef _INTERRUPTS_H_ -#define _INTERRUPTS_H_ - -typedef void (*FN_INTERRUPT_HANDLER)(int nIRQ, void *pParam); - -typedef struct { - FN_INTERRUPT_HANDLER pfnHandler; ///< Function that handles this IRQn - void *pParam; ///< A special parameter that the use can pass to the IRQ. -} INTERRUPT_VECTOR; - -int InitInterruptController (); -int RegisterInterrupt (int nIRQ, FN_INTERRUPT_HANDLER pfnHandler, void *pParam); -int EnableInterrupt (int nIRQ); -int DisableInterrupt (int nIRQ); -int EnableInterrupts (); -int DisableInterrupts (); - -#endif diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h deleted file mode 100644 index 89bea700..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/mmio.h +++ /dev/null @@ -1,24 +0,0 @@ -/* mmio.h - access to MMIO registers */ - -#ifndef MMIO_H -#define MMIO_H - -#include - -// write to MMIO register -static inline void mmio_write(uint32_t reg, uint32_t data) { - uint32_t *ptr = (uint32_t*)reg; - asm volatile("str %[data], [%[reg]]" - : : [reg]"r"(ptr), [data]"r"(data)); -} - -// read from MMIO register -static inline uint32_t mmio_read(uint32_t reg) { - uint32_t *ptr = (uint32_t*)reg; - uint32_t data; - asm volatile("ldr %[data], [%[reg]]" - : [data]"=r"(data) : [reg]"r"(ptr)); - return data; -} - -#endif // #ifndef MMIO_H diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c deleted file mode 100644 index 92f837e7..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.c +++ /dev/null @@ -1,125 +0,0 @@ -/* uart.c - UART initialization & communication */ -/* Reference material: - * http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf - * Chapter 13: UART - */ - -#include -#include -#include - -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), -}; - -/* - * delay function - * int32_t delay: number of cycles to delay - * - * This just loops times in a way that the compiler - * wont optimize away. - */ -static void delay(int32_t count) { - asm volatile("__delay_%=: subs %[count], %[count], #1; bne __delay_%=\n" - : : [count]"r"(count) : "cc"); -} - -/* - * Initialize UART0. - */ -void uart_init() { - // Disable UART0. - mmio_write(UART0_CR, 0x00000000); - // Setup the GPIO pin 14 && 15. - - // Disable pull up/down for all GPIO pins & delay for 150 cycles. - mmio_write(GPPUD, 0x00000000); - delay(150); - - // Disable pull up/down for pin 14,15 & delay for 150 cycles. - mmio_write(GPPUDCLK0, (1 << 14) | (1 << 15)); - delay(150); - - // Write 0 to GPPUDCLK0 to make it take effect. - mmio_write(GPPUDCLK0, 0x00000000); - - // Clear pending interrupts. - mmio_write(UART0_ICR, 0x7FF); - - // Set integer & fractional part of baud rate. - // Divider = UART_CLOCK/(16 * Baud) - // Fraction part register = (Fractional part * 64) + 0.5 - // UART_CLOCK = 3000000; Baud = 115200. - - // Divider = 3000000/(16 * 115200) = 1.627 = ~1. - // Fractional part register = (.627 * 64) + 0.5 = 40.6 = ~40. - mmio_write(UART0_IBRD, 1); - mmio_write(UART0_FBRD, 40); - - // Enable FIFO & 8 bit data transmissio (1 stop bit, no parity). - mmio_write(UART0_LCRH, (1 << 4) | (1 << 5) | (1 << 6)); - - // Mask all interrupts. - mmio_write(UART0_IMSC, (1 << 1) | (1 << 4) | (1 << 5) | - (1 << 6) | (1 << 7) | (1 << 8) | - (1 << 9) | (1 << 10)); - - // Enable UART0, receive & transfer part of UART. - mmio_write(UART0_CR, (1 << 0) | (1 << 8) | (1 << 9)); -} - -/* - * Transmit a byte via UART0. - * uint8_t Byte: byte to send. - */ -void uart_putc(uint8_t byte) { - // wait for UART to become ready to transmit - while (1) { - if (!(mmio_read(UART0_FR) & (1 << 5))) { - break; - } - } - mmio_write(UART0_DR, byte); -} - -/* - * print a string to the UART one character at a time - * const char *str: 0-terminated string - */ -void uart_puts(const char *str) { - while (*str) { - uart_putc(*str++); - } -} diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h b/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h deleted file mode 100644 index fe7f64aa..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/Drivers/uart.h +++ /dev/null @@ -1,25 +0,0 @@ -/* uart.h - UART initialization & communication */ - -#ifndef UART_H -#define UART_H - -#include - -/* - * Initialize UART0. - */ -void uart_init(); - -/* - * Transmit a byte via UART0. - * uint8_t Byte: byte to send. - */ -void uart_putc(uint8_t byte); - -/* - * print a string to the UART one character at a time - * const char *str: 0-terminated string - */ -void uart_puts(const char *str); - -#endif // #ifndef UART_H diff --git a/boards/base/RaspberryPi/example-FreeRTOS/Makefile b/boards/base/RaspberryPi/example-FreeRTOS/Makefile index c1751204..a8d64ad0 100644 --- a/boards/base/RaspberryPi/example-FreeRTOS/Makefile +++ b/boards/base/RaspberryPi/example-FreeRTOS/Makefile @@ -1,73 +1,55 @@ -# build environment -PREFIX ?= /your compiler path/gcc-arm-none-eabi-4_8-2014q1 -ARCH ?= $(PREFIX)/bin/arm-none-eabi - -CC = ${ARCH}-gcc -CPP = ${ARCH}-g++ -AS = ${ARCH}-as -LD = ${ARCH}-ld -AR = ${ARCH}-ar -OBJCOPY = ${ARCH}-objcopy - -PLATFORM = raspi -LINKER_SCRIPT = raspberrypi.ld - -CFLAGS = -march=armv6z -g -Wall -Wextra -ASFLAGS = -g - -CFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s -ASFLAGS_FOR_TARGET = #-mcpu=arm1176jzf-s -LDFLAGS = #--error-unresolved-symbols - -GFXLIB := ../uGFX -include $(GFXLIB)/gfx.mk -include $(GFXLIB)/drivers/gdisp/framebuffer/driver.mk - -OSLIB := ../FreeRTOS -MODULES := $(OSLIB)/Source/portable/GCC/RaspberryPi -MODULES += $(OSLIB)/Source/portable/MemMang -MODULES += $(OSLIB)/Source -MODULES += Drivers - -SRC_DIR := $(MODULES) -INC_DIR := $(addsuffix /include,$(SRC_DIR)) -BUILD_DIR := $(addsuffix /build,$(SRC_DIR)) - -INCLUDEDIRS := $(OSLIB)/Source/portable/GCC/RaspberryPi -INCLUDEDIRS += $(OSLIB)/Source/include -INCLUDEDIRS += Drivers -INCLUDEDIRS += $(GFXINC) - -INCLUDES := $(addprefix -I,$(INCLUDEDIRS)) - -ASRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.s)) -AOBJ := $(ASRC:.s=.o) -CSRC := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) -CSRC += $(GFXSRC) -COBJ := $(CSRC:.c=.o) - -vpath %.c $(SRC_DIR) -vpath %.cpp $(SRC_DIR) -vpath %.s $(SRC_DIR) - -%.o: %.c - $(CC) $(CFLAGS_FOR_TARGET) $(INCLUDES) $(CFLAGS) -c -o $*.o $< - -%.o: %.s - $(AS) $(ASFLAGS_FOR_TARGET) $(INCLUDES) $(ASFLAGS) -o $*.o $< - -OBJ = $(AOBJ) $(COBJ) - -bin/kernel.img: bin/kernel.elf - ${OBJCOPY} -O binary $< $@ - -bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/lib/gcc/arm-none-eabi/4.8.3" -lgcc -bin/kernel.elf: LDFLAGS += -L "$(PREFIX)/arm-none-eabi/lib" -lc -bin/kernel.elf: $(OBJ) - ${LD} $(OBJ) -Map bin/kernel.map -o $@ -T $(LINKER_SCRIPT) ${LDFLAGS} - -clean: - rm -f bin/*.elf bin/*.img bin/*.map $(OBJ) - - - +# Possible Targets: all clean Debug cleanDebug Release cleanRelease + +############################################################################################## +# Settings +# + +# General settings + # See $(GFXLIB)/tools/gmake_scripts/readme.txt for the list of variables + OPT_OS = freertos + OPT_THUMB = yes + OPT_LINK_OPTIMIZE = yes + # For the raspberry pi we can either use the generic armv6 cpu or the highly optimized raspberrypi settings + OPT_CPU = raspberrypi + +# uGFX settings + # See $(GFXLIB)/tools/gmake_scripts/library_ugfx.mk for the list of variables + GFXLIB = ../uGFX + GFXBOARD = RaspberryPi + GFXDEMO = modules/gdisp/basics + +# FreeRTOS settings +ifeq ($(OPT_OS),freertos) + # See $(GFXLIB)/tools/gmake_scripts/os_freertos.mk for the list of variables + FREERTOS = ../FreeRTOS + FREERTOS_BOARD = RaspberryPi + FREERTOS_MODULES = $(GFXLIB)/boards/base/RaspberryPi/FreeRTOS + FREERTOS_LDSCRIPT = $(GFXLIB)/boards/base/RaspberryPi/FreeRTOS/raspberrypi.ld +endif + +############################################################################################## +# Set these for your project +# + +ARCH = arm-none-eabi- +SRCFLAGS = -ggdb -O0 +CFLAGS = +CXXFLAGS = -fno-rtti +ASFLAGS = +LDFLAGS = + +SRC = +OBJS = +DEFS = +LIBS = +INCPATH = +LIBPATH = + +############################################################################################## +# These should be at the end +# + +include $(GFXLIB)/tools/gmake_scripts/library_ugfx.mk +include $(GFXLIB)/tools/gmake_scripts/os_$(OPT_OS).mk +include $(GFXLIB)/tools/gmake_scripts/compiler_gcc.mk +# *** EOF *** diff --git a/boards/base/RaspberryPi/example-FreeRTOS/main.c b/boards/base/RaspberryPi/example-FreeRTOS/main.c deleted file mode 100644 index 3a64a7bb..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/main.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include - -#include "Drivers/interrupts.h" - -#include "gfx.h" - -static void displayTask(void *pvParameters) { - coord_t width, height; - // Get the screen size - width = gdispGetWidth(); - height = gdispGetHeight(); - - // Code Here - gdispDrawBox(10, 10, width/2, height/2, Yellow); - gdispFillArea(width/2, height/2, width/2-10, height/2-10, Blue); - gdispDrawLine(5, 30, width-50, height-40, Red); - - while(1) - { - vTaskDelay(1000); - } - - return; -} - -/** - * This is the systems main entry, some call it a boot thread. - * - * -- Absolutely nothing wrong with this being called main(), just it doesn't have - * -- the same prototype as you'd see in a linux program. - **/ -int main(void) { - - DisableInterrupts(); - InitInterruptController(); - - // Initialize and clear the display - gfxInit(); - - xTaskCreate(displayTask, - (portCHAR *)"Display Task", - 128, - NULL, - 0, - NULL); - - vTaskStartScheduler(); - - /* - * We should never get here, but just in case something goes wrong, - * we'll place the CPU into a safe loop. - */ - while(1) { - ; - } - - return 0; -} - -void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) -{ - ( void ) pcTaskName; - ( void ) pxTask; - - /* Run time task stack overflow checking is performed if - configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is - called if a task stack overflow is detected. Note the system/interrupt - stack is not checked. */ - taskDISABLE_INTERRUPTS(); - for( ;; ); -} -/*-----------------------------------------------------------*/ - -void vApplicationTickHook( void ) -{ - /* This function will be called by each tick interrupt if - configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be - added here, but the tick hook is called from an interrupt context, so - code must not attempt to block, and only the interrupt safe FreeRTOS API - functions can be used (those that end in FromISR()). */ -} diff --git a/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld b/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld deleted file mode 100644 index ece588b5..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/raspberrypi.ld +++ /dev/null @@ -1,70 +0,0 @@ -/** - * BlueThunder Linker Script for the raspberry Pi! - * - * - * - **/ -MEMORY -{ - RESERVED (r) : ORIGIN = 0x00000000, LENGTH = 32K - INIT_RAM (rwx) : ORIGIN = 0x00008000, LENGTH = 32K - RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 128M -} - -ENTRY(_start) - -SECTIONS { - /* - * Our init section allows us to place the bootstrap code at address 0x8000 - * - * This is where the Graphics processor forces the ARM to start execution. - * However the interrupt vector code remains at 0x0000, and so we must copy the correct - * branch instructions to 0x0000 - 0x001C in order to get the processor to handle interrupts. - * - */ - .init : { - KEEP(*(.init)) - } > INIT_RAM = 0 - - .module_entries : { - __module_entries_start = .; - KEEP(*(.module_entries)) - KEEP(*(.module_entries.*)) - __module_entries_end = .; - __module_entries_size = SIZEOF(.module_entries); - } > INIT_RAM - - - /** - * This is the main code section, it is essentially of unlimited size. (128Mb). - * - **/ - .text : { - *(.text) - } > RAM - - /* - * Next we put the data. - */ - .data : { - *(.data) - } > RAM - - .bss : - { - __bss_start = .; - *(.bss) - *(.bss.*) - __bss_end = .; - } > RAM - - /** - * Place HEAP here??? - **/ - - /** - * Stack starts at the top of the RAM, and moves down! - **/ - _estack = ORIGIN(RAM) + LENGTH(RAM); -} - diff --git a/boards/base/RaspberryPi/example-FreeRTOS/startup.s b/boards/base/RaspberryPi/example-FreeRTOS/startup.s deleted file mode 100644 index 286f396c..00000000 --- a/boards/base/RaspberryPi/example-FreeRTOS/startup.s +++ /dev/null @@ -1,102 +0,0 @@ -.extern system_init -.extern __bss_start -.extern __bss_end -.extern vFreeRTOS_ISR -.extern vPortYieldProcessor -.extern DisableInterrupts -.extern main - .section .init - .globl _start -;; -_start: - ;@ All the following instruction should be read as: - ;@ Load the address at symbol into the program counter. - - ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi! - ;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset! - - ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb! - ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode. - ldr pc,prefetch_handler ;@ Prefetch/abort handler. - ldr pc,data_handler ;@ Data abort handler/ - ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler. - ldr pc,irq_handler ;@ IRQ handler - ldr pc,fiq_handler ;@ Fast interrupt handler. - - ;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses -reset_handler: .word reset -undefined_handler: .word undefined_instruction -swi_handler: .word vPortYieldProcessor -prefetch_handler: .word prefetch_abort -data_handler: .word data_abort -unused_handler: .word unused -irq_handler: .word vFreeRTOS_ISR -fiq_handler: .word fiq - -reset: - ;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000 - - mov r0,#0x8000 ;@ Store the source pointer - mov r1,#0x0000 ;@ Store the destination pointer. - - ;@ Here we copy the branching instructions - ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0 - stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1 - - ;@ So the branches get the correct address we also need to copy our vector table! - ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented. - stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data. - - - ;@ Set up the various STACK pointers for different CPU modes - ;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) - mov r0,#0xD2 - msr cpsr_c,r0 - mov sp,#0x8000 - - ;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) - mov r0,#0xD1 - msr cpsr_c,r0 - mov sp,#0x4000 - - ;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS) - mov r0,#0xD3 - msr cpsr_c,r0 - mov sp,#0x8000000 - - ldr r0, =__bss_start - ldr r1, =__bss_end - - mov r2, #0 - -zero_loop: - cmp r0,r1 - it lt - strlt r2,[r0], #4 - blt zero_loop - - bl DisableInterrupts - - - ;@ mov sp,#0x1000000 - b main ;@ We're ready?? Lets start main execution! - .section .text - -undefined_instruction: - b undefined_instruction - -prefetch_abort: - b prefetch_abort - -data_abort: - b data_abort - -unused: - b unused - -fiq: - b fiq - -hang: - b hang - diff --git a/tools/gmake_scripts/cpu_armv6.mk b/tools/gmake_scripts/cpu_armv6.mk new file mode 100644 index 00000000..0fa5867e --- /dev/null +++ b/tools/gmake_scripts/cpu_armv6.mk @@ -0,0 +1,18 @@ +# +# This file is subject to the terms of the GFX License. If a copy of +# the license was not distributed with this file, you can obtain one at: +# +# http://ugfx.org/license.html +# + +# +# See readme.txt for the make API +# + +# Requirements: +# +# NONE +# + +SRCFLAGS += -march=armv6 -mfpu=vfp -mfloat-abi=hard +LDFLAGS += -march=armv6 -mfpu=vfp -mfloat-abi=hard diff --git a/tools/gmake_scripts/cpu_raspberrypi.mk b/tools/gmake_scripts/cpu_raspberrypi.mk new file mode 100644 index 00000000..b31c35e9 --- /dev/null +++ b/tools/gmake_scripts/cpu_raspberrypi.mk @@ -0,0 +1,18 @@ +# +# This file is subject to the terms of the GFX License. If a copy of +# the license was not distributed with this file, you can obtain one at: +# +# http://ugfx.org/license.html +# + +# +# See readme.txt for the make API +# + +# Requirements: +# +# NONE +# + +SRCFLAGS += -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard +LDFLAGS += -march=armv6zk -mcpu=arm1176jzf-s -mtune=arm1176jzf-s -mfpu=vfp -mfloat-abi=hard diff --git a/tools/gmake_scripts/os_freertos.mk b/tools/gmake_scripts/os_freertos.mk new file mode 100644 index 00000000..5cbd5be0 --- /dev/null +++ b/tools/gmake_scripts/os_freertos.mk @@ -0,0 +1,36 @@ +# +# This file is subject to the terms of the GFX License. If a copy of +# the license was not distributed with this file, you can obtain one at: +# +# http://ugfx.org/license.html +# + +# See readme.txt for the make API + +# Requirements: +# +# FREERTOS: The location of the FreeRTOS code eg FREERTOS=../FreeRTOS +# FREERTOS_BOARD The board name eg FREERTOS_BOARD=RaspberryPi +# + +# Optional: +# +# FREERTOS_MODULES A list of directories containing FreeRTOS source (eg drivers, startup etc) - default is "" +# FREERTOS_LDSCRIPT The loader script - default is "" +# + +PATHLIST += FREERTOS + +FREERTOS_MODULES += $(FREERTOS)/Source/portable/GCC/$(FREERTOS_BOARD) +FREERTOS_MODULES += $(FREERTOS)/Source/portable/MemMang +FREERTOS_MODULES += $(FREERTOS)/Source + +INCPATH += $(FREERTOS)/Source/portable/GCC/$(FREERTOS_BOARD) \ + $(FREERTOS)/Source/include + +SRC += $(foreach sdir,$(FREERTOS_MODULES),$(wildcard $(sdir)/*.s)) +SRC += $(foreach sdir,$(FREERTOS_MODULES),$(wildcard $(sdir)/*.c)) + +ifeq ($(LDSCRIPT),) + LDSCRIPT= $(FREERTOS_LDSCRIPT) +endif diff --git a/tools/gmake_scripts/readme.txt b/tools/gmake_scripts/readme.txt index eec7dd95..67206ed9 100644 --- a/tools/gmake_scripts/readme.txt +++ b/tools/gmake_scripts/readme.txt @@ -16,7 +16,7 @@ OPT_COPY_EXE=no|yes - Copy the final program to the local project directory - OPT_NONSTANDARD_FLAGS=no - Turn off adding the standard compiler language flags - default no OPT_LINK_OPTIMIZE=no - Remove unused code/data during link - default no OPT_OS=win32|win32.chibios|linux|osx|chibios|freertos|ecos|raw32|rawrtos - Mandatory: The operating system -OPT_CPU=x86|x64|stm32m4|at91sam7 - Add some cpu dependant flags +OPT_CPU=x86|x64|stm32m4|at91sam7|armv6|raspberrypi - Add some cpu dependant flags BUILDDIR - Build Directory - default is ".build" or "bin/Debug" or "bin/Release" depending on the target PROJECT - Project Name - default is the name of the project directory -- cgit v1.2.3