From baedda497d16c5096971eee83a0c467fe663fe6d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sat, 2 Jan 2016 21:13:31 +0100 Subject: o Moving around a lot of files. --- CMakeLists.txt | 146 ++------------- apps/CMakeLists.txt | 5 + apps/os1/CMakeLists.txt | 23 +++ apps/os1/os1.cpp | 285 ++++++++++++++++++++++++++++++ apps/os1/os1_cm3.s | 56 ++++++ apps/os2/CMakeLists.txt | 23 +++ apps/os2/os2.cpp | 341 ++++++++++++++++++++++++++++++++++++ apps/os2/os2_cm3.s | 56 ++++++ apps/serial1/CMakeLists.txt | 23 +++ apps/serial1/serial1.cpp | 128 ++++++++++++++ apps/serial2/CMakeLists.txt | 23 +++ apps/serial2/serial2.cpp | 150 ++++++++++++++++ apps/test1/CMakeLists.txt | 24 +++ apps/test1/test1.cpp | 101 +++++++++++ debug.cpp | 44 ----- host/CMakeLists.txt | 2 +- include/debug.h | 44 ----- include/init_high.h | 120 ------------- include/playground.h | 12 -- include/stm32f10x_conf.h | 38 ---- init_high.cpp | 315 --------------------------------- init_low.s | 42 ----- os1.cpp | 285 ------------------------------ os1_cm3.s | 56 ------ os2.cpp | 341 ------------------------------------ os2_cm3.s | 56 ------ playground/include/debug.h | 44 +++++ playground/include/init_high.h | 120 +++++++++++++ playground/include/playground.h | 12 ++ playground/include/stm32f10x_conf.h | 38 ++++ playground/src/debug.cpp | 44 +++++ playground/src/init_high.cpp | 315 +++++++++++++++++++++++++++++++++ playground/src/init_low.s | 42 +++++ serial1.cpp | 128 -------------- serial2.cpp | 150 ---------------- test1.cpp | 101 ----------- 36 files changed, 1865 insertions(+), 1868 deletions(-) create mode 100644 apps/os1/CMakeLists.txt create mode 100644 apps/os1/os1.cpp create mode 100644 apps/os1/os1_cm3.s create mode 100644 apps/os2/CMakeLists.txt create mode 100644 apps/os2/os2.cpp create mode 100644 apps/os2/os2_cm3.s create mode 100644 apps/serial1/CMakeLists.txt create mode 100644 apps/serial1/serial1.cpp create mode 100644 apps/serial2/CMakeLists.txt create mode 100644 apps/serial2/serial2.cpp create mode 100644 apps/test1/CMakeLists.txt create mode 100644 apps/test1/test1.cpp delete mode 100644 debug.cpp delete mode 100644 include/debug.h delete mode 100644 include/init_high.h delete mode 100644 include/playground.h delete mode 100644 include/stm32f10x_conf.h delete mode 100644 init_high.cpp delete mode 100644 init_low.s delete mode 100644 os1.cpp delete mode 100644 os1_cm3.s delete mode 100644 os2.cpp delete mode 100644 os2_cm3.s create mode 100644 playground/include/debug.h create mode 100644 playground/include/init_high.h create mode 100644 playground/include/playground.h create mode 100644 playground/include/stm32f10x_conf.h create mode 100644 playground/src/debug.cpp create mode 100644 playground/src/init_high.cpp create mode 100644 playground/src/init_low.s delete mode 100644 serial1.cpp delete mode 100644 serial2.cpp delete mode 100644 test1.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 48a5736..2ce54f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,150 +37,26 @@ target_include_directories(tinyprintf PUBLIC tinyprintf) set(STM32F10X_STDPERIPH_LIB ${CMAKE_SOURCE_DIR}/tmp/STM32F10x_StdPeriph_Lib_V3.5.0) set(STM32F10X_STDPERIPH_DEFINES STM32F10X_MD USE_STDPERIPH_DRIVER) - -######################################################################################################### -# test1 - -add_executable(test1.elf test1.cpp init_low.s init_high.cpp include/init_high.h include/stm32f10x_conf.h - # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php - tinyprintf/tinyprintf.c tinyprintf/tinyprintf.h - debug.cpp include/debug.h - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c - ) - -target_include_directories(test1.elf PUBLIC - include - tinyprintf - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) -target_compile_definitions(test1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) - -target_compile_options(test1.elf PUBLIC "-O0") -set_target_properties(test1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") -add_extra_commands(test1.elf) - -######################################################################################################### -# serial1 - -add_executable(serial1.elf serial1.cpp init_low.s init_high.cpp include/init_high.h include/stm32f10x_conf.h - debug.cpp include/debug.h - # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php - tinyprintf/tinyprintf.c tinyprintf/tinyprintf.h - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c - ) - -target_include_directories(serial1.elf PUBLIC - include - tinyprintf - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) -target_compile_definitions(serial1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) - -set_target_properties(serial1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") -add_extra_commands(serial1.elf) - -######################################################################################################### -# serial2 - -add_executable(serial2.elf serial2.cpp init_low.s init_high.cpp include/init_high.h include/stm32f10x_conf.h - include/playground.h - debug.cpp include/debug.h - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c - ) -target_link_libraries(serial2.elf tinyprintf) - -target_include_directories(serial2.elf PUBLIC - include - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) -target_compile_definitions(serial2.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) - -set_target_properties(serial2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") -add_extra_commands(serial2.elf) - -######################################################################################################### -# os1 - -add_executable(os1.elf os1.cpp os1_cm3.s init_low.s init_high.cpp include/init_high.h include/stm32f10x_conf.h - include/playground.h - debug.cpp include/debug.h - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c - ) -target_link_libraries(os1.elf tinyprintf) - -target_include_directories(os1.elf PUBLIC - include - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) -target_compile_definitions(os1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) - -set_target_properties(os1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") -add_extra_commands(os1.elf) - -######################################################################################################### -# os2 - -add_executable(os2.elf os2.cpp os2_cm3.s init_low.s init_high.cpp include/init_high.h include/stm32f10x_conf.h - include/playground.h - debug.cpp include/debug.h - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c - ) -target_link_libraries(os2.elf tinyprintf) - -target_include_directories(os2.elf PUBLIC - include - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport - ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x - ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) -target_compile_definitions(os2.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) - -set_target_properties(os2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") -add_extra_commands(os2.elf) - -add_subdirectory(apps) - -## +set(PLAYGROUND_DIR ${CMAKE_SOURCE_DIR}/playground) +set(TINYPRINTF_DIR ${CMAKE_SOURCE_DIR}/tinyprintf) add_library(playground OBJECT - init_low.s init_high.cpp - include/init_high.h + playground/src/init_low.s playground/src/init_high.cpp + playground/include/init_high.h - include/stm32f10x_conf.h + playground/include/stm32f10x_conf.h - include/playground.h + playground/include/playground.h - debug.cpp - include/debug.h) + playground/src/debug.cpp + playground/include/debug.h) target_include_directories(playground PUBLIC - include + playground/include tinyprintf ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc ) target_compile_definitions(playground PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +add_subdirectory(apps) diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 57fb795..a38f85d 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -1 +1,6 @@ add_subdirectory(dma1) +add_subdirectory(os1) +add_subdirectory(os2) +add_subdirectory(serial1) +add_subdirectory(serial2) +add_subdirectory(test1) diff --git a/apps/os1/CMakeLists.txt b/apps/os1/CMakeLists.txt new file mode 100644 index 0000000..b6849b7 --- /dev/null +++ b/apps/os1/CMakeLists.txt @@ -0,0 +1,23 @@ +add_executable(os1.elf os1.cpp os1_cm3.s + ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h + ${PLAYGROUND_DIR}/include/playground.h + ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h + ${PLAYGROUND_DIR}/include/stm32f10x_conf.h + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) +target_link_libraries(os1.elf tinyprintf) + +target_include_directories(os1.elf PUBLIC + ${PLAYGROUND_DIR}/include + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(os1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +set_target_properties(os1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(os1.elf) diff --git a/apps/os1/os1.cpp b/apps/os1/os1.cpp new file mode 100644 index 0000000..9c87a3d --- /dev/null +++ b/apps/os1/os1.cpp @@ -0,0 +1,285 @@ +#include +#include +#include +#include + +#include "debug.h" +#include "tinyprintf.h" +#include "playground.h" + +extern "C" +__attribute__((naked, used)) +void HardFault_Handler_C(uint32_t *hardfault_args) { + dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); + dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); + dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); + dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); + dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); + dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); + dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); + dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); + dbg_printf("\n"); + + halt(); +} + +enum class exc_return_t : uint32_t { + RETURN_TO_HANDLER_MODE_USE_MSP = 0xFFFFFFF1, + RETURN_TO_THREAD_MODE_USE_MSP = 0xFFFFFFF9, + RETURN_TO_THREAD_MODE_USE_PSP = 0xFFFFFFFD, +}; + +// This is used from assembly so order is important +struct task_t { + uint8_t *stack; + exc_return_t exc_return; + int flags; + + void init(uint8_t *stack) { + this->stack = stack; + flags = 0x01; + set_ready(); + } + + void deinit() { + flags = 0; + } + + bool is_ready() { + return (flags & 0x02) > 0; + } + + void set_ready() { + flags |= 0x02; + } +} __attribute__((packed)); + +const int max_task_count = 3; +const int stack_size = 100; + +task_t tasks[max_task_count]; +uint8_t stacks[max_task_count][stack_size]; +uint8_t task_count = 0; +int current_task; + +const unsigned int SYSTICK_FREQUENCY_HZ = 10; + +struct hardware_frame_t { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +struct software_frame_t { + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; +}; + +extern "C" +void SysTick_Handler() { + static bool on = true; + + if (on) { + GPIO_SetBits(GPIOB, GPIO_Pin_7); + } + else { + GPIO_ResetBits(GPIOB, GPIO_Pin_7); + } + + on = !on; + + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; +} + +void thread_end() { +} + +volatile bool idle_task_run; + +void idle_task(const void *const) { + // trigger PendSV to run + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; + + // wait for the PendSV handler to kick in. After the handler has completed it will do a context switch and + // this point shouldn't be reached. + + idle_task_run = true; + while (idle_task_run) { + GPIOB->BSRR = GPIO_Pin_6; + GPIOB->BRR = GPIO_Pin_6; + } +} + +static +void os_create_thread(void (task)(void const *const), bool create_sw); + +void os_init() { + NVIC_SetPriority(SysTick_IRQn, 0xff); + NVIC_SetPriority(PendSV_IRQn, 0xff); + + SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY_HZ); + + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + init.GPIO_Pin = GPIO_Pin_6; + GPIO_Init(GPIOB, &init); + init.GPIO_Pin = GPIO_Pin_7; + GPIO_Init(GPIOB, &init); + + for (int i = 0; i < max_task_count; i++) { + tasks[i].flags = 0; + } + + os_create_thread(idle_task, false); + current_task = 0; +} + +void os_create_thread(void (task)(void const *const)) { + os_create_thread(task, true); +} + +static +void os_create_thread(void (task)(void const *const), bool create_sw) { + uint8_t *s = stacks[task_count] + stack_size; + + s -= sizeof(hardware_frame_t); + hardware_frame_t *hw = reinterpret_cast(s); + + hw->r0 = 0x00000000; + hw->r1 = 0x01010101; + hw->r2 = 0x02020202; + hw->r3 = 0x03030303; + hw->r12 = 0x0c0c0c0c; + hw->lr = reinterpret_cast(thread_end); + + hw->pc = reinterpret_cast(task); + hw->psr = 0x01000000; + + if (create_sw) { + s -= sizeof(software_frame_t); + software_frame_t *sw = reinterpret_cast(s); + + sw->r4 = 0x04040404; + sw->r5 = 0x05050505; + sw->r6 = 0x06060606; + sw->r7 = 0x07070707; + sw->r8 = 0x08080808; + sw->r9 = 0x09090909; + sw->r10 = 0x0a0a0a0a; + sw->r11 = 0x0b0b0b0b; + } + + task_t *t = &tasks[task_count]; + t->init(s); + t->exc_return = exc_return_t::RETURN_TO_THREAD_MODE_USE_PSP; + + task_count++; +} + +static +int find_first_ready_task() { + task_t *t; + int idx = current_task + 1; + do { + if (idx == max_task_count) { + idx = 1; + } else if (idx == current_task) { + return 0; + } + + t = &tasks[idx]; + } while (!t->is_ready()); + + return idx; +} + +__attribute__((used)) +task_t *select_next_task(uint8_t *current_stack) { + + task_t *t = &tasks[current_task]; + int new_task = find_first_ready_task(); + + if (new_task != current_task) { + t->stack = current_stack; + t = &tasks[new_task]; + current_task = new_task; + } + + return t; +} + +volatile bool run; + +extern "C" void do_first_context_switch(uint8_t *user_stack, void (task)(const void *const arg)); + +void os_start() { + run = true; + + task_t &t = tasks[0]; + + do_first_context_switch(t.stack, idle_task); + + while (run) { + } +} + + +volatile bool run1 = true; + +void job1(void const *const) { + while (run1) { + GPIO_SetBits(GPIOB, GPIO_Pin_8); + GPIO_ResetBits(GPIOB, GPIO_Pin_8); + } +} + +volatile bool run2 = true; + +void job2(void const *const) { + while (run2) { + GPIO_SetBits(GPIOB, GPIO_Pin_5); + GPIO_ResetBits(GPIOB, GPIO_Pin_5); + } +} + +int main(void) { + SystemInit(); + + init_printf(nullptr, dbg_putc); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO + | RCC_APB2Periph_USART1 + | RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_GPIOC, + ENABLE); + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + // Make Port B's pin #5 the debug output pin + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8; + GPIO_Init(GPIOB, &init); + + os_init(); + os_create_thread(job1); + os_create_thread(job2); + os_start(); + + return 0; +} diff --git a/apps/os1/os1_cm3.s b/apps/os1/os1_cm3.s new file mode 100644 index 0000000..a9083dc --- /dev/null +++ b/apps/os1/os1_cm3.s @@ -0,0 +1,56 @@ +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +/* + +User threads use the process stack (PSP register), kernel and exception code use the main stack (MSP register). + +*/ + +.thumb_func +.global do_first_context_switch +// void do_first_context_switch(uint8_t *user_stack, void (task)(const void *arg)); +do_first_context_switch: + /* Set PSP to the user task's stack */ + msr psp, r0 + + // Set CONTROL.SPSEL=1 so that we run with two stacks + mov r0, #2 + msr control, r0 + isb + + // Restore the data from hardware_frame_t. + pop {r0 - r3, r12, lr} + // Pop PC and PSR. PSR is ignored, but we branch to the new PC + pop {r4, r5} + bx r4 + +/* +When this function is executed {r0-r3,r12,lr,pc} has been pushed to the stack pointed to by PSP. We push the rest of the +registers to the PSP. The current stack pointer is the MSP. + */ +.thumb_func +.global PendSV_Handler +PendSV_Handler: + // Save the rest of the context to the current process' stack + mrs r0, psp + stmdb r0!, {r4 - r11} + + // Call select_next_task_sp. after return, r0 points to a task_t + bl _Z16select_next_taskPh // task_t *select_next_task(uint8_t *current_stack) + + // load task_t.stack and task_t.lr into r1 and lr + ldm r0, {r1, lr} + + ldmia r1!, {r4 - r11} + msr psp, r1 + + // Return, let the CPU restore the hardware part of the context + bx lr +.pool +.size PendSV_Handler,.-PendSV_Handler + +.end diff --git a/apps/os2/CMakeLists.txt b/apps/os2/CMakeLists.txt new file mode 100644 index 0000000..6db926d --- /dev/null +++ b/apps/os2/CMakeLists.txt @@ -0,0 +1,23 @@ +add_executable(os2.elf os2.cpp os2_cm3.s + ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h + ${PLAYGROUND_DIR}/include/playground.h + ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h + ${PLAYGROUND_DIR}/include/stm32f10x_conf.h + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) +target_link_libraries(os2.elf tinyprintf) + +target_include_directories(os2.elf PUBLIC + ${PLAYGROUND_DIR}/include + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(os2.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +set_target_properties(os2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(os2.elf) diff --git a/apps/os2/os2.cpp b/apps/os2/os2.cpp new file mode 100644 index 0000000..c104ac2 --- /dev/null +++ b/apps/os2/os2.cpp @@ -0,0 +1,341 @@ +#include +#include +#include +#include + +#include "debug.h" +#include "tinyprintf.h" +#include "playground.h" + +namespace trygvis { +namespace os2 { + +namespace os { +extern "C" +__attribute__((naked, used)) +void HardFault_Handler_C(uint32_t *hardfault_args) { + dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); + dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); + dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); + dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); + dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); + dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); + dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); + dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); + dbg_printf("\n"); + + halt(); +} + +enum class exc_return_t : uint32_t { + RETURN_TO_HANDLER_MODE_USE_MSP = 0xFFFFFFF1, + RETURN_TO_THREAD_MODE_USE_MSP = 0xFFFFFFF9, + RETURN_TO_THREAD_MODE_USE_PSP = 0xFFFFFFFD, +}; + +// This is used from assembly so order is important +struct task_t { + uint8_t *stack; + exc_return_t exc_return; + int flags; + + void init(uint8_t *stack) { + this->stack = stack; + flags = 0x01; + set_ready(); + } + + void deinit() { + flags = 0; + } + + bool is_ready() { + return (flags & 0x02) > 0; + } + + void set_ready() { + flags |= 0x02; + } +} __attribute__((packed)); + +const int max_task_count = 3; +const int stack_size = 100; + +task_t tasks[max_task_count]; +uint8_t stacks[max_task_count][stack_size]; +uint8_t task_count = 0; +int current_task; + +const unsigned int SYSTICK_FREQUENCY_HZ = 10; + +struct hardware_frame_t { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +struct software_frame_t { + uint32_t r4; + uint32_t r5; + uint32_t r6; + uint32_t r7; + uint32_t r8; + uint32_t r9; + uint32_t r10; + uint32_t r11; +}; + +extern "C" +void SysTick_Handler() { + static bool on = true; + + if (on) { + GPIO_SetBits(GPIOB, GPIO_Pin_7); + } + else { + GPIO_ResetBits(GPIOB, GPIO_Pin_7); + } + + on = !on; + + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; +} + +void thread_end() { +} + +volatile bool idle_task_run; + +void idle_task(const void *const) { + // trigger PendSV to run + SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; + + // wait for the PendSV handler to kick in. After the handler has completed it will do a context switch and + // this point shouldn't be reached. + + idle_task_run = true; + while (idle_task_run) { + GPIOB->BSRR = GPIO_Pin_6; + GPIOB->BRR = GPIO_Pin_6; + } +} + +static +void os_create_thread(void (task)(void const *const), bool create_sw); + +void os_init() { + NVIC_SetPriority(SysTick_IRQn, 0xff); + NVIC_SetPriority(PendSV_IRQn, 0xff); + + SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY_HZ); + + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + init.GPIO_Pin = GPIO_Pin_6; + GPIO_Init(GPIOB, &init); + init.GPIO_Pin = GPIO_Pin_7; + GPIO_Init(GPIOB, &init); + + for (int i = 0; i < max_task_count; i++) { + tasks[i].flags = 0; + } + + os_create_thread(idle_task, false); + current_task = 0; +} + +void os_create_thread(void (task)(void const *const)) { + os_create_thread(task, true); +} + +static +void os_create_thread(void (task)(void const *const), bool create_sw) { + uint8_t *s = stacks[task_count] + stack_size; + + s -= sizeof(hardware_frame_t); + hardware_frame_t *hw = reinterpret_cast(s); + + hw->r0 = 0x00000000; + hw->r1 = 0x01010101; + hw->r2 = 0x02020202; + hw->r3 = 0x03030303; + hw->r12 = 0x0c0c0c0c; + hw->lr = reinterpret_cast(thread_end); + + hw->pc = reinterpret_cast(task); + hw->psr = 0x01000000; + + if (create_sw) { + s -= sizeof(software_frame_t); + software_frame_t *sw = reinterpret_cast(s); + + sw->r4 = 0x04040404; + sw->r5 = 0x05050505; + sw->r6 = 0x06060606; + sw->r7 = 0x07070707; + sw->r8 = 0x08080808; + sw->r9 = 0x09090909; + sw->r10 = 0x0a0a0a0a; + sw->r11 = 0x0b0b0b0b; + } + + task_t *t = &tasks[task_count]; + t->init(s); + t->exc_return = exc_return_t::RETURN_TO_THREAD_MODE_USE_PSP; + + task_count++; +} + +static +int find_first_ready_task() { + task_t *t; + int idx = current_task + 1; + do { + if (idx == max_task_count) { + idx = 1; + } else if (idx == current_task) { + return 0; + } + + t = &tasks[idx]; + } while (!t->is_ready()); + + return idx; +} + +__attribute__((used)) +task_t *select_next_task(uint8_t *current_stack) { + + task_t *t = &tasks[current_task]; + int new_task = find_first_ready_task(); + + if (new_task != current_task) { + t->stack = current_stack; + t = &tasks[new_task]; + current_task = new_task; + } + + return t; +} + +volatile bool run; + +extern "C" void do_first_context_switch(uint8_t *user_stack, void (task)(const void *const arg)); + +void os_start() { + run = true; + + task_t &t = tasks[0]; + + do_first_context_switch(t.stack, idle_task); + + while (run) { + } +} + +class CriticalSection { +public: + CriticalSection() : primask(__get_PRIMASK()) { + __disable_irq(); + } + + ~CriticalSection() { + __set_PRIMASK(primask); + } + +private: + uint32_t primask; +}; + +//class Mutex { +//public: +// Mutex() : task(-1) { +// } +// +// void lock() { +// do { +// { +// CriticalSection cs; +// if (task == -1) { +// task = current_task; +// break; +// } +// } +// +// } while (true); +// } +// +//private: +// int task; +//}; + +} // namespace os + +namespace main { + +using namespace trygvis::os2::os; + +volatile bool run1 = true; + +void job1(void const *const) { + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + init.GPIO_Pin = GPIO_Pin_8; + GPIO_Init(GPIOB, &init); + + while (run1) { + GPIO_SetBits(GPIOB, GPIO_Pin_8); + GPIO_ResetBits(GPIOB, GPIO_Pin_8); + } +} + +volatile bool run2 = true; + +void job2(void const *const) { + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + init.GPIO_Pin = GPIO_Pin_5; + GPIO_Init(GPIOB, &init); + + while (run2) { + CriticalSection cs; + GPIO_SetBits(GPIOB, GPIO_Pin_5); + GPIO_ResetBits(GPIOB, GPIO_Pin_5); + } +} + +extern "C" +int main(void) { + SystemInit(); + + init_printf(nullptr, dbg_putc); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO + | RCC_APB2Periph_USART1 + | RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_GPIOC, + ENABLE); + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + os_init(); + os_create_thread(job1); + os_create_thread(job2); + os_start(); + + return 0; +} + +} // namespace main +} // namespace os2 +} // namespace trygvis diff --git a/apps/os2/os2_cm3.s b/apps/os2/os2_cm3.s new file mode 100644 index 0000000..dabdfe0 --- /dev/null +++ b/apps/os2/os2_cm3.s @@ -0,0 +1,56 @@ +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +/* + +User threads use the process stack (PSP register), kernel and exception code use the main stack (MSP register). + +*/ + +.thumb_func +.global do_first_context_switch +// void do_first_context_switch(uint8_t *user_stack, void (task)(const void *arg)); +do_first_context_switch: + /* Set PSP to the user task's stack */ + msr psp, r0 + + // Set CONTROL.SPSEL=1 so that we run with two stacks + mov r0, #2 + msr control, r0 + isb + + // Restore the data from hardware_frame_t. + pop {r0 - r3, r12, lr} + // Pop PC and PSR. PSR is ignored, but we branch to the new PC + pop {r4, r5} + bx r4 + +/* +When this function is executed {r0-r3,r12,lr,pc} has been pushed to the stack pointed to by PSP. We push the rest of the +registers to the PSP. The current stack pointer is the MSP. + */ +.thumb_func +.global PendSV_Handler +PendSV_Handler: + // Save the rest of the context to the current process' stack + mrs r0, psp + stmdb r0!, {r4 - r11} + + // Call select_next_task_sp. after return, r0 points to a task_t + bl _ZN7trygvis3os22os16select_next_taskEPh // task_t *select_next_task(uint8_t *current_stack) + + // load task_t.stack and task_t.lr into r1 and lr + ldm r0, {r1, lr} + + ldmia r1!, {r4 - r11} + msr psp, r1 + + // Return, let the CPU restore the hardware part of the context + bx lr +.pool +.size PendSV_Handler,.-PendSV_Handler + +.end diff --git a/apps/serial1/CMakeLists.txt b/apps/serial1/CMakeLists.txt new file mode 100644 index 0000000..0491391 --- /dev/null +++ b/apps/serial1/CMakeLists.txt @@ -0,0 +1,23 @@ +add_executable(serial1.elf serial1.cpp + ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h + ${PLAYGROUND_DIR}/include/playground.h + ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h + ${PLAYGROUND_DIR}/include/stm32f10x_conf.h + # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php + ${TINYPRINTF_DIR}/tinyprintf.c ${TINYPRINTF_DIR}/tinyprintf.h + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) + +target_include_directories(serial1.elf PUBLIC + ${PLAYGROUND_DIR}/include + ${TINYPRINTF_DIR} + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(serial1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +set_target_properties(serial1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(serial1.elf) diff --git a/apps/serial1/serial1.cpp b/apps/serial1/serial1.cpp new file mode 100644 index 0000000..60e9bc9 --- /dev/null +++ b/apps/serial1/serial1.cpp @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include +#include +#include "debug.h" +#include "tinyprintf.h" + +extern "C" void halt(); + +#include "stm32f10x_conf.h" + +extern "C" +__attribute__((naked)) +void HardFault_Handler_C(uint32_t *hardfault_args) { + halt(); +} + +size_t strlen(const char *s) { + size_t size = 0; + while (*s++ != '\0') size++; + return size; +} + +int run = 1; + +volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE; + +/* + * When we get there the stack pointer is set + */ +int main() { + SystemInit(); + + init_printf(nullptr, dbg_putc); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO + | RCC_APB2Periph_USART1 + | RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_GPIOC, + ENABLE); + + /* ***************************************** */ + + // Debug on port B + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + // Make Port B's pin #5 the debug output pin + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_5; + init.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &init); + + /* ***************************************** */ + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); + + /* + * PA9 USART1_TX + * PA10 USART1_RX + */ + + // Enable USART1 + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + + // Make the TX pin an output + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_9; + init.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &init); + + // 8 bit mode + USART1->CR1 &= ~USART_CR1_M; + USART1->CR2 &= ~USART_CR2_STOP_1; + + USART1->CR1 |= USART_CR1_UE /* Set UART Enable */ + | USART_CR1_TE; /* Set Transmission Enable */ + + // Set baud rate + int mantissa = 39; + int fraction = static_cast(16 * 0.0625); // == 1 + // 72M / (16*39.0625) = 115200 + USART1->BRR = static_cast(mantissa << 4 | fraction); + + char c = 'A'; + while (run) { + int txe = USART1->SR & USART_SR_TXE; + +// dbg_printf("1:%d?\n", x); + +// char mm[100]; +// tfp_sprintf(mm, "2:%d?\n", x); +// send_command(SYS_WRITE0, mm); + +// printf(" %u?\n", usart1->SR); +// printf(" %u?\n", 1); + + if (txe) { + GPIO_SetBits(GPIOB, GPIO_Pin_All); + GPIO_ResetBits(GPIOB, GPIO_Pin_All); + + USART1->DR = (uint16_t) c; +// USART1->DR = 0x55; + + if (c == 'Z') { + c = 'a'; + } else if (c == 'z') { + c = '0'; + } else if (c == '9') { + c = '\n'; + } else if (c == '\n') { + c = 'A'; + } else { + c++; + } + } + } + + return 0; +} + diff --git a/apps/serial2/CMakeLists.txt b/apps/serial2/CMakeLists.txt new file mode 100644 index 0000000..3c31c50 --- /dev/null +++ b/apps/serial2/CMakeLists.txt @@ -0,0 +1,23 @@ +add_executable(serial2.elf serial2.cpp + ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h + ${PLAYGROUND_DIR}/include/playground.h + ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h + ${PLAYGROUND_DIR}/include/stm32f10x_conf.h + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/misc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_usart.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) +target_link_libraries(serial2.elf tinyprintf) + +target_include_directories(serial2.elf PUBLIC + ${PLAYGROUND_DIR}/include + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(serial2.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +set_target_properties(serial2.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(serial2.elf) diff --git a/apps/serial2/serial2.cpp b/apps/serial2/serial2.cpp new file mode 100644 index 0000000..c0259ea --- /dev/null +++ b/apps/serial2/serial2.cpp @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "tinyprintf.h" +#include "playground.h" + +extern "C" +__attribute__((naked, used)) +void HardFault_Handler_C(uint32_t *hardfault_args) { + dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); + dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); + dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); + dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); + dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); + dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); + dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); + dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); + dbg_printf("\n"); + + halt(); +} + +size_t strlen(const char *s) { + size_t size = 0; + while (*s++ != '\0') size++; + return size; +} + +int run = 1; + +volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE; + +volatile uint8_t tx_ready = 0; + +/* + * When we get there the stack pointer is set + */ +int main() { + SystemInit(); + + init_printf(nullptr, dbg_putc); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO + | RCC_APB2Periph_USART1 + | RCC_APB2Periph_GPIOA + | RCC_APB2Periph_GPIOB + | RCC_APB2Periph_GPIOC, + ENABLE); + + /* ***************************************** */ + + // Debug on port B + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + // Make Port B's pin #5 the debug output pin + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_5; + init.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &init); + + /* ***************************************** */ + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); + + /* + * PA9 USART1_TX + * PA10 USART1_RX + */ + + // Enable USART1 + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); + + // Make the TX pin an output + GPIO_StructInit(&init); + init.GPIO_Pin = GPIO_Pin_9; + init.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &init); + + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); + NVIC_InitTypeDef NVIC_InitStruct = { + NVIC_IRQChannel: USART1_IRQn, + NVIC_IRQChannelPreemptionPriority: 0, + NVIC_IRQChannelSubPriority: 0, + NVIC_IRQChannelCmd: ENABLE, + }; + NVIC_Init(&NVIC_InitStruct); + NVIC_EnableIRQ(USART1_IRQn); + + // 8 bit mode + USART1->CR1 &= ~USART_CR1_M; + USART1->CR2 &= ~USART_CR2_STOP_1; + + // Set baud rate + int mantissa = 39; + int fraction = static_cast(16 * 0.0625); // == 1 + // 72M / (16*39.0625) = 115200 + USART1->BRR = static_cast(mantissa << 4 | fraction); + + USART1->CR1 |= USART_CR1_UE /* Set UART Enable */ + | USART_CR1_TE /* Set Transmission Enable */ + | USART_CR1_TXEIE; /* Set TX buffer Empty Interrupt Enable */ + + char c = 'A'; + tx_ready = 1; + while (run) { + // wait for TX to be ready + while (!tx_ready); + tx_ready = 0; + + GPIO_SetBits(GPIOB, GPIO_Pin_All); + GPIO_ResetBits(GPIOB, GPIO_Pin_All); + + USART1->DR = (uint16_t) c; + USART_ITConfig(USART1, USART_IT_TXE, ENABLE); + + if (c == 'Z') { + c = 'a'; + } else if (c == 'z') { + c = '0'; + } else if (c == '9') { + c = '\n'; + } else if (c == '\n') { + c = 'A'; + } else { + c++; + } + } + + return 0; +} + +extern "C" +void USART1_IRQHandler() { + tx_ready = 1; + + if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) { + // Disable the interrupt + USART_ITConfig(USART1, USART_IT_TXE, DISABLE); + } +} diff --git a/apps/test1/CMakeLists.txt b/apps/test1/CMakeLists.txt new file mode 100644 index 0000000..eb090b3 --- /dev/null +++ b/apps/test1/CMakeLists.txt @@ -0,0 +1,24 @@ +add_executable(test1.elf test1.cpp + ${PLAYGROUND_DIR}/src/init_low.s ${PLAYGROUND_DIR}/src/init_high.cpp ${PLAYGROUND_DIR}/include/init_high.h + ${PLAYGROUND_DIR}/include/playground.h + ${PLAYGROUND_DIR}/src/debug.cpp ${PLAYGROUND_DIR}/include/debug.h + ${PLAYGROUND_DIR}/include/stm32f10x_conf.h + # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php + ${TINYPRINTF_DIR}/tinyprintf.c ${TINYPRINTF_DIR}/tinyprintf.h + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c + ) + +target_include_directories(test1.elf PUBLIC + ${PLAYGROUND_DIR}/include + ${TINYPRINTF_DIR} + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/CoreSupport + ${STM32F10X_STDPERIPH_LIB}/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x + ${STM32F10X_STDPERIPH_LIB}/Libraries/STM32F10x_StdPeriph_Driver/inc) +target_compile_definitions(test1.elf PUBLIC ${STM32F10X_STDPERIPH_DEFINES}) + +target_compile_options(test1.elf PUBLIC "-O0") +set_target_properties(test1.elf PROPERTIES LINK_FLAGS "-nostartfiles -T${CMAKE_SOURCE_DIR}/cmake/stm32.ld") +add_extra_commands(test1.elf) diff --git a/apps/test1/test1.cpp b/apps/test1/test1.cpp new file mode 100644 index 0000000..a883876 --- /dev/null +++ b/apps/test1/test1.cpp @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include +#include +#include "playground.h" + +extern "C" +__attribute__((naked)) +void HardFault_Handler_C(uint32_t *hardfault_args); + +extern "C" void high(); +extern "C" void low(); + +SCB_Type *__SCB = ((SCB_Type *) SCB_BASE); +//extern SCB_Type *__SCB; + +struct hardfault_data_t { + uint32_t r0; + uint32_t r1; + uint32_t r2; + uint32_t r3; + uint32_t r12; + uint32_t lr; + uint32_t pc; + uint32_t psr; +}; + +volatile struct hardfault_data_t *hardfault_data = (volatile struct hardfault_data_t *) 0x20000800; + +void HardFault_Handler_C(uint32_t *hardfault_args) { + hardfault_data->r0 = hardfault_args[0]; + hardfault_data->r1 = hardfault_args[1]; + hardfault_data->r2 = hardfault_args[2]; + hardfault_data->r3 = hardfault_args[3]; + hardfault_data->r12 = hardfault_args[4]; + hardfault_data->lr = hardfault_args[5]; + hardfault_data->pc = hardfault_args[6]; + hardfault_data->psr = hardfault_args[7]; + + halt(); +} + +void send_command(int command, void *message) { + bool active = (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == CoreDebug_DHCSR_C_DEBUGEN_Msk; + + if (!active) { + return; + } + + __asm volatile ( + "mov r0, %[cmd];" + "mov r1, %[msg];" + "bkpt #0xAB" : : [cmd] "r"(command), [msg] "r"(message) : "r0", "r1", "memory" + ); +} + +size_t strlen(const char *s) { + size_t size = 0; + while (*s++ != '\0') size++; + return size; +} + +int run = 1; + +/* + * When we get there the stack pointer is set + */ +int main() { + SystemInit(); +// SystemCoreClockUpdate(); + + SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTPENDED_Msk | SCB_SHCSR_BUSFAULTENA_Msk; + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); + + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); + RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, + ENABLE); + + GPIO_InitTypeDef init; + GPIO_StructInit(&init); + init.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &init); + + while (run) { +// GPIO_SetBits(GPIOA, GPIO_Pin_All); + GPIO_SetBits(GPIOB, GPIO_Pin_All); +// GPIO_SetBits(GPIOC, GPIO_Pin_All); + +// GPIO_ResetBits(GPIOA, GPIO_Pin_All); + GPIO_ResetBits(GPIOB, GPIO_Pin_All); +// GPIO_ResetBits(GPIOC, GPIO_Pin_All); + } + + return 0; +} diff --git a/debug.cpp b/debug.cpp deleted file mode 100644 index 40f2169..0000000 --- a/debug.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "debug.h" -#include "tinyprintf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -static void append_char(void *v, char c) { - *(*((char **) v))++ = c; -} - -void dbg_printf(const char *fmt, ...) { - char msg[100]; - msg[0] = 0; - - va_list va; - va_start(va, fmt); - char *a = msg; - char **b = &a; - tfp_format(b, append_char, fmt, va); - va_end(va); - append_char(b, '\0'); - - send_command(SYS_WRITE0, msg); -} - -void dbg_putc(void *, char c) { - char cc = c; - send_command(SYS_WRITEC, &cc); -} - -void send_command(enum SemihostingCmd command, void *message) { - int c = command; - - __asm volatile ( - "mov r0, %[cmd];" - "mov r1, %[msg];" - "bkpt #0xAB" : : [cmd] "r"(c), [msg] "r"(message) : "r0", "r1", "memory" - ); -} - -#ifdef __cplusplus -}; -#endif diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index d3bfe17..ea8894b 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable(host1.elf host1.cpp target_include_directories(host1.elf PUBLIC ../tinyprintf - ../include) + ../playground/include) target_compile_definitions(host1.elf PUBLIC TINYPRINTF_DEFINE_TFP_SPRINTF=0 TINYPRINTF_OVERRIDE_LIBC=0) add_executable(elf3 elf3.cpp) diff --git a/include/debug.h b/include/debug.h deleted file mode 100644 index d2926b3..0000000 --- a/include/debug.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef DEBUG_H -#define DEBUG_H - -#ifdef __cplusplus -extern "C" { -#endif - -__attribute__((format (printf, 1, 2))) -void dbg_printf(const char *fmt, ...); - -void dbg_putc(void * junk, char); - -enum SemihostingCmd { - SYS_CLOSE = 0x02, - SYS_CLOCK = 0x10, - SYS_ELAPSED = 0x30, - SYS_ERRNO = 0x13, - SYS_FLEN = 0x0C, - SYS_GET_CMDLINE = 0x15, - SYS_HEAPINFO = 0x16, - SYS_ISERROR = 0x08, - SYS_ISTTY = 0x09, - SYS_OPEN = 0x01, - SYS_READ = 0x06, - SYS_READC = 0x07, - SYS_REMOVE = 0x0E, - SYS_RENAME = 0x0F, - SYS_SEEK = 0x0A, - SYS_SYSTEM = 0x12, - SYS_TICKFREQ = 0x31, - SYS_TIME = 0x11, - SYS_TMPNAM = 0x0D, - SYS_WRITE = 0x05, - SYS_WRITEC = 0x03, - SYS_WRITE0 = 0x04, -}; - -void send_command(enum SemihostingCmd command, void *message); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/include/init_high.h b/include/init_high.h deleted file mode 100644 index c6da514..0000000 --- a/include/init_high.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef INIT_HIGH_H -#define INIT_HIGH_H - -extern "C" { - -void init_high(); - -/** - * Declare all the interrupt/event handlers as weak symbols and make them aliases of the default handler. - */ -extern void Default_Handler() __attribute__((weak)); - -extern void _Reset_Handler(); - -extern void NMI_Handler(); - -extern void HardFault_Handler(); - -extern void MemManage_Handler(); - -extern void BusFault_Handler(); - -extern void UsageFault_Handler(); - -extern void SVC_Handler(); - -extern void DebugMon_Handler(); - -extern void PendSV_Handler(); - -extern void SysTick_Handler(); - -extern void WWDG_IRQHandler(); - -extern void PVD_IRQHandler(); - -extern void TAMPER_IRQHandler(); - -extern void RTC_IRQHandler(); - -extern void FLASH_IRQHandler(); - -extern void RCC_IRQHandler(); - -extern void EXTI0_IRQHandler(); - -extern void EXTI1_IRQHandler(); - -extern void EXTI2_IRQHandler(); - -extern void EXTI3_IRQHandler(); - -extern void EXTI4_IRQHandler(); - -extern void DMA1_Channel1_IRQHandler(); - -extern void DMA1_Channel2_IRQHandler(); - -extern void DMA1_Channel3_IRQHandler(); - -extern void DMA1_Channel4_IRQHandler(); - -extern void DMA1_Channel5_IRQHandler(); - -extern void DMA1_Channel6_IRQHandler(); - -extern void DMA1_Channel7_IRQHandler(); - -extern void ADC1_2_IRQHandler(); - -extern void USB_HP_CAN1_TX_IRQHandler(); - -extern void USB_LP_CAN1_RX0_IRQHandler(); - -extern void CAN1_RX1_IRQHandler(); - -extern void CAN1_SCE_IRQHandler(); - -extern void EXTI9_5_IRQHandler(); - -extern void TIM1_BRK_IRQHandler(); - -extern void TIM1_UP_IRQHandler(); - -extern void TIM1_TRG_COM_IRQHandler(); - -extern void TIM1_CC_IRQHandler(); - -extern void TIM2_IRQHandler(); - -extern void TIM3_IRQHandler(); - -extern void TIM4_IRQHandler(); - -extern void I2C1_EV_IRQHandler(); - -extern void I2C1_ER_IRQHandler(); - -extern void I2C2_EV_IRQHandler(); - -extern void I2C2_ER_IRQHandler(); - -extern void SPI1_IRQHandler(); - -extern void SPI2_IRQHandler(); - -extern void USART1_IRQHandler(); - -extern void USART2_IRQHandler(); - -extern void USART3_IRQHandler(); - -extern void EXTI15_10_IRQHandler(); - -extern void RTCAlarm_IRQHandler(); - -extern void USBWakeUp_IRQHandler(); -} - -#endif diff --git a/include/playground.h b/include/playground.h deleted file mode 100644 index c224908..0000000 --- a/include/playground.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef PLAYGROUND_H -#define PLAYGROUND_H - -extern "C" void halt(); - -template -static inline -size_t SizeOfArray(const T(&)[N]) { - return N; -} - -#endif diff --git a/include/stm32f10x_conf.h b/include/stm32f10x_conf.h deleted file mode 100644 index f663d12..0000000 --- a/include/stm32f10x_conf.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __STM32F10x_CONF_H -#define __STM32F10x_CONF_H - -/* -#include "stm32f10x_adc.h" -#include "stm32f10x_bkp.h" -#include "stm32f10x_can.h" -#include "stm32f10x_cec.h" -#include "stm32f10x_crc.h" -#include "stm32f10x_dac.h" -#include "stm32f10x_dbgmcu.h" -#include "stm32f10x_dma.h" -#include "stm32f10x_exti.h" -#include "stm32f10x_flash.h" -#include "stm32f10x_fsmc.h" -#include "stm32f10x_gpio.h" -#include "stm32f10x_i2c.h" -#include "stm32f10x_iwdg.h" -#include "stm32f10x_pwr.h" -#include "stm32f10x_rcc.h" -#include "stm32f10x_rtc.h" -#include "stm32f10x_sdio.h" -#include "stm32f10x_spi.h" -#include "stm32f10x_tim.h" -#include "stm32f10x_usart.h" -#include "stm32f10x_wwdg.h" -#include "misc.h" -*/ - -#ifdef USE_FULL_ASSERT - #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) - - void assert_failed(uint8_t* file, uint32_t line); -#else - #define assert_param(expr) ((void)0) -#endif - -#endif diff --git a/init_high.cpp b/init_high.cpp deleted file mode 100644 index 700d17a..0000000 --- a/init_high.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include -#include -#include "stm32f10x.h" -#include "debug.h" -#include "init_high.h" -#include "playground.h" - -/** - * Symbols that are defined by the linker - */ -extern uint32_t _copy_data_load, _copy_data_store, _copy_data_store_end; -extern uint32_t _bss_start, _bss_end; - -extern int main(); - -void init_high() { - // Copy data from flash to ram - uint32_t *src = &_copy_data_load; - uint32_t *dest = &_copy_data_store; - uint32_t *end = &_copy_data_store_end; - - while (dest <= end) { - *dest++ = *src++; - } - - // Clear the BSS segment - dest = &_bss_start; - end = &_bss_end; - while (dest <= end) { - *dest++ = 0; - } - - main(); -} - -__attribute__((used)) -struct { - uint32_t CFSR; - uint32_t HFSR; - uint32_t DFSR; - uint32_t AFSR; -// uint32_t MMAR; - uint32_t BFAR; -} Default_Handler_Info; - -__attribute__((used)) -void Default_Handler() { - Default_Handler_Info = { - CFSR: SCB->CFSR, - HFSR: SCB->HFSR, - DFSR: SCB->DFSR, - AFSR: SCB->AFSR, - BFAR: SCB->BFAR, - }; - - dbg_printf("Default handler:\n"); - - dbg_printf("HFSR: 0x%08lx\n", Default_Handler_Info.HFSR); - if (Default_Handler_Info.HFSR & SCB_HFSR_DEBUGEVT) { - dbg_printf(" HFSR.DEBUGEVT\n"); - } - if (Default_Handler_Info.HFSR & SCB_HFSR_FORCED) { - dbg_printf(" HFSR.FORCED\n"); - } - if (Default_Handler_Info.HFSR & SCB_HFSR_VECTTBL) { - dbg_printf(" HFSR.VECTTBL\n"); - } - - dbg_printf("CFSR: 0x%08lx\n", Default_Handler_Info.CFSR); - if (Default_Handler_Info.CFSR & SCB_CFSR_DIVBYZERO) { - dbg_printf(" UFSR.DIVBYZERO\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_UNALIGNED) { - dbg_printf(" UFSR.UNALIGED\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_NOCP) { - dbg_printf(" UFSR.NOCP\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_INVPC) { - dbg_printf(" UFSR.INVPC\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_INVSTATE) { - dbg_printf(" UFSR.INVSTATE\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_UNDEFINSTR) { - dbg_printf(" UFSR.UNDEFINSTR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { - dbg_printf(" BFSR.BFARVALID\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_STKERR) { - dbg_printf(" BFSR.STKERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_UNSTKERR) { - dbg_printf(" BFSR.UNSTKERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) { - dbg_printf(" BFSR.IMPRECISERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) { - dbg_printf(" BFSR.IMPRECISERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_PRECISERR) { - dbg_printf(" BFSR.PRECISERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_IBUSERR) { - dbg_printf(" BFSR.IBUSERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_MMARVALID) { - dbg_printf(" MMFSR.MMARVALID\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_MSTKERR) { - dbg_printf(" MMFSR.MSTKERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_MUNSTKERR) { - dbg_printf(" MMFSR.MUNSTKERR\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_DACCVIOL) { - dbg_printf(" MMFSR.DACCVIOL\n"); - } - if (Default_Handler_Info.CFSR & SCB_CFSR_IACCVIOL) { - dbg_printf(" MMFSR.IACCVIOL\n"); - } - dbg_printf("DFSR: 0x%08lx\n", Default_Handler_Info.DFSR); - dbg_printf("AFSR: 0x%08lx\n", Default_Handler_Info.AFSR); - - if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { - dbg_printf("BFAR: 0x%08lx\n", Default_Handler_Info.BFAR); - } else { - dbg_printf("BFAR: \n"); - } - - dbg_printf("NVIC:\n"); - for (size_t i = 0; i < SizeOfArray(NVIC->IABR); i++) { - dbg_printf(" IABR[%d]: 0x%08lx\n", i, NVIC->IABR[i]); - } - - halt(); -} - -void _Reset_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void NMI_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void HardFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void MemManage_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void BusFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void UsageFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void SVC_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void DebugMon_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void PendSV_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void SysTick_Handler() __attribute__ ((weak, alias("Default_Handler"))); - -void WWDG_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void PVD_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TAMPER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void RTC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void FLASH_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void RCC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel6_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void DMA1_Channel7_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void ADC1_2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USB_HP_CAN1_TX_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USB_LP_CAN1_RX0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void CAN1_RX1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void CAN1_SCE_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI9_5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM1_BRK_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM1_UP_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM1_TRG_COM_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM1_CC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void TIM4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void I2C1_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void I2C1_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void I2C2_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void I2C2_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void SPI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void SPI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USART1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USART2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USART3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void EXTI15_10_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void RTCAlarm_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -void USBWakeUp_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); - -__attribute__((section(".isr_vectors"), used)) -uint32_t isr_vectors[74] = { - (uint32_t) _Reset_Handler, - (uint32_t) NMI_Handler, - (uint32_t) HardFault_Handler, - (uint32_t) MemManage_Handler, - (uint32_t) BusFault_Handler, - (uint32_t) UsageFault_Handler, - 0, - 0, - 0, - 0, - (uint32_t) SVC_Handler, - (uint32_t) DebugMon_Handler, - 0, - (uint32_t) PendSV_Handler, - (uint32_t) SysTick_Handler, - (uint32_t) WWDG_IRQHandler, - (uint32_t) PVD_IRQHandler, - (uint32_t) TAMPER_IRQHandler, - (uint32_t) RTC_IRQHandler, - (uint32_t) FLASH_IRQHandler, - (uint32_t) RCC_IRQHandler, - (uint32_t) EXTI0_IRQHandler, - (uint32_t) EXTI1_IRQHandler, - (uint32_t) EXTI2_IRQHandler, - (uint32_t) EXTI3_IRQHandler, - (uint32_t) EXTI4_IRQHandler, - (uint32_t) DMA1_Channel1_IRQHandler, - (uint32_t) DMA1_Channel2_IRQHandler, - (uint32_t) DMA1_Channel3_IRQHandler, - (uint32_t) DMA1_Channel4_IRQHandler, - (uint32_t) DMA1_Channel5_IRQHandler, - (uint32_t) DMA1_Channel6_IRQHandler, - (uint32_t) DMA1_Channel7_IRQHandler, - (uint32_t) ADC1_2_IRQHandler, - (uint32_t) USB_HP_CAN1_TX_IRQHandler, - (uint32_t) USB_LP_CAN1_RX0_IRQHandler, - (uint32_t) CAN1_RX1_IRQHandler, - (uint32_t) CAN1_SCE_IRQHandler, - (uint32_t) EXTI9_5_IRQHandler, - (uint32_t) TIM1_BRK_IRQHandler, - (uint32_t) TIM1_UP_IRQHandler, - (uint32_t) TIM1_TRG_COM_IRQHandler, - (uint32_t) TIM1_CC_IRQHandler, - (uint32_t) TIM2_IRQHandler, - (uint32_t) TIM3_IRQHandler, - (uint32_t) TIM4_IRQHandler, - (uint32_t) I2C1_EV_IRQHandler, - (uint32_t) I2C1_ER_IRQHandler, - (uint32_t) I2C2_EV_IRQHandler, - (uint32_t) I2C2_ER_IRQHandler, - (uint32_t) SPI1_IRQHandler, - (uint32_t) SPI2_IRQHandler, - (uint32_t) USART1_IRQHandler, - (uint32_t) USART2_IRQHandler, - (uint32_t) USART3_IRQHandler, - (uint32_t) EXTI15_10_IRQHandler, - (uint32_t) RTCAlarm_IRQHandler, - (uint32_t) USBWakeUp_IRQHandler, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; diff --git a/init_low.s b/init_low.s deleted file mode 100644 index bc12b5b..0000000 --- a/init_low.s +++ /dev/null @@ -1,42 +0,0 @@ -.syntax unified -.cpu cortex-m3 -.thumb - -.section .text - -.thumb_func -.global _Reset_Handler -_Reset_Handler: - bl init_high - b halt - -.thumb_func -.global halt -halt: - b . - -.thumb_func -NMI_Handler: - b halt - -.thumb_func -HardFault_Handler: - tst lr, #4 - ite eq - mrseq r0, msp - mrsne r0, psp - b HardFault_Handler_C - -.thumb_func -MemManage_Handler: - b halt - -.thumb_func -BusFault_Handler: - b halt - -.thumb_func -UsageFault_Handler: - b halt - -.end diff --git a/os1.cpp b/os1.cpp deleted file mode 100644 index 9c87a3d..0000000 --- a/os1.cpp +++ /dev/null @@ -1,285 +0,0 @@ -#include -#include -#include -#include - -#include "debug.h" -#include "tinyprintf.h" -#include "playground.h" - -extern "C" -__attribute__((naked, used)) -void HardFault_Handler_C(uint32_t *hardfault_args) { - dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); - dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); - dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); - dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); - dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); - dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); - dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); - dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); - dbg_printf("\n"); - - halt(); -} - -enum class exc_return_t : uint32_t { - RETURN_TO_HANDLER_MODE_USE_MSP = 0xFFFFFFF1, - RETURN_TO_THREAD_MODE_USE_MSP = 0xFFFFFFF9, - RETURN_TO_THREAD_MODE_USE_PSP = 0xFFFFFFFD, -}; - -// This is used from assembly so order is important -struct task_t { - uint8_t *stack; - exc_return_t exc_return; - int flags; - - void init(uint8_t *stack) { - this->stack = stack; - flags = 0x01; - set_ready(); - } - - void deinit() { - flags = 0; - } - - bool is_ready() { - return (flags & 0x02) > 0; - } - - void set_ready() { - flags |= 0x02; - } -} __attribute__((packed)); - -const int max_task_count = 3; -const int stack_size = 100; - -task_t tasks[max_task_count]; -uint8_t stacks[max_task_count][stack_size]; -uint8_t task_count = 0; -int current_task; - -const unsigned int SYSTICK_FREQUENCY_HZ = 10; - -struct hardware_frame_t { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t psr; -}; - -struct software_frame_t { - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; -}; - -extern "C" -void SysTick_Handler() { - static bool on = true; - - if (on) { - GPIO_SetBits(GPIOB, GPIO_Pin_7); - } - else { - GPIO_ResetBits(GPIOB, GPIO_Pin_7); - } - - on = !on; - - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; -} - -void thread_end() { -} - -volatile bool idle_task_run; - -void idle_task(const void *const) { - // trigger PendSV to run - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; - - // wait for the PendSV handler to kick in. After the handler has completed it will do a context switch and - // this point shouldn't be reached. - - idle_task_run = true; - while (idle_task_run) { - GPIOB->BSRR = GPIO_Pin_6; - GPIOB->BRR = GPIO_Pin_6; - } -} - -static -void os_create_thread(void (task)(void const *const), bool create_sw); - -void os_init() { - NVIC_SetPriority(SysTick_IRQn, 0xff); - NVIC_SetPriority(PendSV_IRQn, 0xff); - - SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY_HZ); - - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - init.GPIO_Pin = GPIO_Pin_6; - GPIO_Init(GPIOB, &init); - init.GPIO_Pin = GPIO_Pin_7; - GPIO_Init(GPIOB, &init); - - for (int i = 0; i < max_task_count; i++) { - tasks[i].flags = 0; - } - - os_create_thread(idle_task, false); - current_task = 0; -} - -void os_create_thread(void (task)(void const *const)) { - os_create_thread(task, true); -} - -static -void os_create_thread(void (task)(void const *const), bool create_sw) { - uint8_t *s = stacks[task_count] + stack_size; - - s -= sizeof(hardware_frame_t); - hardware_frame_t *hw = reinterpret_cast(s); - - hw->r0 = 0x00000000; - hw->r1 = 0x01010101; - hw->r2 = 0x02020202; - hw->r3 = 0x03030303; - hw->r12 = 0x0c0c0c0c; - hw->lr = reinterpret_cast(thread_end); - - hw->pc = reinterpret_cast(task); - hw->psr = 0x01000000; - - if (create_sw) { - s -= sizeof(software_frame_t); - software_frame_t *sw = reinterpret_cast(s); - - sw->r4 = 0x04040404; - sw->r5 = 0x05050505; - sw->r6 = 0x06060606; - sw->r7 = 0x07070707; - sw->r8 = 0x08080808; - sw->r9 = 0x09090909; - sw->r10 = 0x0a0a0a0a; - sw->r11 = 0x0b0b0b0b; - } - - task_t *t = &tasks[task_count]; - t->init(s); - t->exc_return = exc_return_t::RETURN_TO_THREAD_MODE_USE_PSP; - - task_count++; -} - -static -int find_first_ready_task() { - task_t *t; - int idx = current_task + 1; - do { - if (idx == max_task_count) { - idx = 1; - } else if (idx == current_task) { - return 0; - } - - t = &tasks[idx]; - } while (!t->is_ready()); - - return idx; -} - -__attribute__((used)) -task_t *select_next_task(uint8_t *current_stack) { - - task_t *t = &tasks[current_task]; - int new_task = find_first_ready_task(); - - if (new_task != current_task) { - t->stack = current_stack; - t = &tasks[new_task]; - current_task = new_task; - } - - return t; -} - -volatile bool run; - -extern "C" void do_first_context_switch(uint8_t *user_stack, void (task)(const void *const arg)); - -void os_start() { - run = true; - - task_t &t = tasks[0]; - - do_first_context_switch(t.stack, idle_task); - - while (run) { - } -} - - -volatile bool run1 = true; - -void job1(void const *const) { - while (run1) { - GPIO_SetBits(GPIOB, GPIO_Pin_8); - GPIO_ResetBits(GPIOB, GPIO_Pin_8); - } -} - -volatile bool run2 = true; - -void job2(void const *const) { - while (run2) { - GPIO_SetBits(GPIOB, GPIO_Pin_5); - GPIO_ResetBits(GPIOB, GPIO_Pin_5); - } -} - -int main(void) { - SystemInit(); - - init_printf(nullptr, dbg_putc); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO - | RCC_APB2Periph_USART1 - | RCC_APB2Periph_GPIOA - | RCC_APB2Periph_GPIOB - | RCC_APB2Periph_GPIOC, - ENABLE); - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - - // Make Port B's pin #5 the debug output pin - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - init.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8; - GPIO_Init(GPIOB, &init); - - os_init(); - os_create_thread(job1); - os_create_thread(job2); - os_start(); - - return 0; -} diff --git a/os1_cm3.s b/os1_cm3.s deleted file mode 100644 index a9083dc..0000000 --- a/os1_cm3.s +++ /dev/null @@ -1,56 +0,0 @@ -.syntax unified -.cpu cortex-m3 -.thumb - -.section .text - -/* - -User threads use the process stack (PSP register), kernel and exception code use the main stack (MSP register). - -*/ - -.thumb_func -.global do_first_context_switch -// void do_first_context_switch(uint8_t *user_stack, void (task)(const void *arg)); -do_first_context_switch: - /* Set PSP to the user task's stack */ - msr psp, r0 - - // Set CONTROL.SPSEL=1 so that we run with two stacks - mov r0, #2 - msr control, r0 - isb - - // Restore the data from hardware_frame_t. - pop {r0 - r3, r12, lr} - // Pop PC and PSR. PSR is ignored, but we branch to the new PC - pop {r4, r5} - bx r4 - -/* -When this function is executed {r0-r3,r12,lr,pc} has been pushed to the stack pointed to by PSP. We push the rest of the -registers to the PSP. The current stack pointer is the MSP. - */ -.thumb_func -.global PendSV_Handler -PendSV_Handler: - // Save the rest of the context to the current process' stack - mrs r0, psp - stmdb r0!, {r4 - r11} - - // Call select_next_task_sp. after return, r0 points to a task_t - bl _Z16select_next_taskPh // task_t *select_next_task(uint8_t *current_stack) - - // load task_t.stack and task_t.lr into r1 and lr - ldm r0, {r1, lr} - - ldmia r1!, {r4 - r11} - msr psp, r1 - - // Return, let the CPU restore the hardware part of the context - bx lr -.pool -.size PendSV_Handler,.-PendSV_Handler - -.end diff --git a/os2.cpp b/os2.cpp deleted file mode 100644 index c104ac2..0000000 --- a/os2.cpp +++ /dev/null @@ -1,341 +0,0 @@ -#include -#include -#include -#include - -#include "debug.h" -#include "tinyprintf.h" -#include "playground.h" - -namespace trygvis { -namespace os2 { - -namespace os { -extern "C" -__attribute__((naked, used)) -void HardFault_Handler_C(uint32_t *hardfault_args) { - dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); - dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); - dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); - dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); - dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); - dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); - dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); - dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); - dbg_printf("\n"); - - halt(); -} - -enum class exc_return_t : uint32_t { - RETURN_TO_HANDLER_MODE_USE_MSP = 0xFFFFFFF1, - RETURN_TO_THREAD_MODE_USE_MSP = 0xFFFFFFF9, - RETURN_TO_THREAD_MODE_USE_PSP = 0xFFFFFFFD, -}; - -// This is used from assembly so order is important -struct task_t { - uint8_t *stack; - exc_return_t exc_return; - int flags; - - void init(uint8_t *stack) { - this->stack = stack; - flags = 0x01; - set_ready(); - } - - void deinit() { - flags = 0; - } - - bool is_ready() { - return (flags & 0x02) > 0; - } - - void set_ready() { - flags |= 0x02; - } -} __attribute__((packed)); - -const int max_task_count = 3; -const int stack_size = 100; - -task_t tasks[max_task_count]; -uint8_t stacks[max_task_count][stack_size]; -uint8_t task_count = 0; -int current_task; - -const unsigned int SYSTICK_FREQUENCY_HZ = 10; - -struct hardware_frame_t { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t psr; -}; - -struct software_frame_t { - uint32_t r4; - uint32_t r5; - uint32_t r6; - uint32_t r7; - uint32_t r8; - uint32_t r9; - uint32_t r10; - uint32_t r11; -}; - -extern "C" -void SysTick_Handler() { - static bool on = true; - - if (on) { - GPIO_SetBits(GPIOB, GPIO_Pin_7); - } - else { - GPIO_ResetBits(GPIOB, GPIO_Pin_7); - } - - on = !on; - - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; -} - -void thread_end() { -} - -volatile bool idle_task_run; - -void idle_task(const void *const) { - // trigger PendSV to run - SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; - - // wait for the PendSV handler to kick in. After the handler has completed it will do a context switch and - // this point shouldn't be reached. - - idle_task_run = true; - while (idle_task_run) { - GPIOB->BSRR = GPIO_Pin_6; - GPIOB->BRR = GPIO_Pin_6; - } -} - -static -void os_create_thread(void (task)(void const *const), bool create_sw); - -void os_init() { - NVIC_SetPriority(SysTick_IRQn, 0xff); - NVIC_SetPriority(PendSV_IRQn, 0xff); - - SysTick_Config(SystemCoreClock / SYSTICK_FREQUENCY_HZ); - - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - init.GPIO_Pin = GPIO_Pin_6; - GPIO_Init(GPIOB, &init); - init.GPIO_Pin = GPIO_Pin_7; - GPIO_Init(GPIOB, &init); - - for (int i = 0; i < max_task_count; i++) { - tasks[i].flags = 0; - } - - os_create_thread(idle_task, false); - current_task = 0; -} - -void os_create_thread(void (task)(void const *const)) { - os_create_thread(task, true); -} - -static -void os_create_thread(void (task)(void const *const), bool create_sw) { - uint8_t *s = stacks[task_count] + stack_size; - - s -= sizeof(hardware_frame_t); - hardware_frame_t *hw = reinterpret_cast(s); - - hw->r0 = 0x00000000; - hw->r1 = 0x01010101; - hw->r2 = 0x02020202; - hw->r3 = 0x03030303; - hw->r12 = 0x0c0c0c0c; - hw->lr = reinterpret_cast(thread_end); - - hw->pc = reinterpret_cast(task); - hw->psr = 0x01000000; - - if (create_sw) { - s -= sizeof(software_frame_t); - software_frame_t *sw = reinterpret_cast(s); - - sw->r4 = 0x04040404; - sw->r5 = 0x05050505; - sw->r6 = 0x06060606; - sw->r7 = 0x07070707; - sw->r8 = 0x08080808; - sw->r9 = 0x09090909; - sw->r10 = 0x0a0a0a0a; - sw->r11 = 0x0b0b0b0b; - } - - task_t *t = &tasks[task_count]; - t->init(s); - t->exc_return = exc_return_t::RETURN_TO_THREAD_MODE_USE_PSP; - - task_count++; -} - -static -int find_first_ready_task() { - task_t *t; - int idx = current_task + 1; - do { - if (idx == max_task_count) { - idx = 1; - } else if (idx == current_task) { - return 0; - } - - t = &tasks[idx]; - } while (!t->is_ready()); - - return idx; -} - -__attribute__((used)) -task_t *select_next_task(uint8_t *current_stack) { - - task_t *t = &tasks[current_task]; - int new_task = find_first_ready_task(); - - if (new_task != current_task) { - t->stack = current_stack; - t = &tasks[new_task]; - current_task = new_task; - } - - return t; -} - -volatile bool run; - -extern "C" void do_first_context_switch(uint8_t *user_stack, void (task)(const void *const arg)); - -void os_start() { - run = true; - - task_t &t = tasks[0]; - - do_first_context_switch(t.stack, idle_task); - - while (run) { - } -} - -class CriticalSection { -public: - CriticalSection() : primask(__get_PRIMASK()) { - __disable_irq(); - } - - ~CriticalSection() { - __set_PRIMASK(primask); - } - -private: - uint32_t primask; -}; - -//class Mutex { -//public: -// Mutex() : task(-1) { -// } -// -// void lock() { -// do { -// { -// CriticalSection cs; -// if (task == -1) { -// task = current_task; -// break; -// } -// } -// -// } while (true); -// } -// -//private: -// int task; -//}; - -} // namespace os - -namespace main { - -using namespace trygvis::os2::os; - -volatile bool run1 = true; - -void job1(void const *const) { - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - init.GPIO_Pin = GPIO_Pin_8; - GPIO_Init(GPIOB, &init); - - while (run1) { - GPIO_SetBits(GPIOB, GPIO_Pin_8); - GPIO_ResetBits(GPIOB, GPIO_Pin_8); - } -} - -volatile bool run2 = true; - -void job2(void const *const) { - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - init.GPIO_Pin = GPIO_Pin_5; - GPIO_Init(GPIOB, &init); - - while (run2) { - CriticalSection cs; - GPIO_SetBits(GPIOB, GPIO_Pin_5); - GPIO_ResetBits(GPIOB, GPIO_Pin_5); - } -} - -extern "C" -int main(void) { - SystemInit(); - - init_printf(nullptr, dbg_putc); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO - | RCC_APB2Periph_USART1 - | RCC_APB2Periph_GPIOA - | RCC_APB2Periph_GPIOB - | RCC_APB2Periph_GPIOC, - ENABLE); - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - - os_init(); - os_create_thread(job1); - os_create_thread(job2); - os_start(); - - return 0; -} - -} // namespace main -} // namespace os2 -} // namespace trygvis diff --git a/os2_cm3.s b/os2_cm3.s deleted file mode 100644 index dabdfe0..0000000 --- a/os2_cm3.s +++ /dev/null @@ -1,56 +0,0 @@ -.syntax unified -.cpu cortex-m3 -.thumb - -.section .text - -/* - -User threads use the process stack (PSP register), kernel and exception code use the main stack (MSP register). - -*/ - -.thumb_func -.global do_first_context_switch -// void do_first_context_switch(uint8_t *user_stack, void (task)(const void *arg)); -do_first_context_switch: - /* Set PSP to the user task's stack */ - msr psp, r0 - - // Set CONTROL.SPSEL=1 so that we run with two stacks - mov r0, #2 - msr control, r0 - isb - - // Restore the data from hardware_frame_t. - pop {r0 - r3, r12, lr} - // Pop PC and PSR. PSR is ignored, but we branch to the new PC - pop {r4, r5} - bx r4 - -/* -When this function is executed {r0-r3,r12,lr,pc} has been pushed to the stack pointed to by PSP. We push the rest of the -registers to the PSP. The current stack pointer is the MSP. - */ -.thumb_func -.global PendSV_Handler -PendSV_Handler: - // Save the rest of the context to the current process' stack - mrs r0, psp - stmdb r0!, {r4 - r11} - - // Call select_next_task_sp. after return, r0 points to a task_t - bl _ZN7trygvis3os22os16select_next_taskEPh // task_t *select_next_task(uint8_t *current_stack) - - // load task_t.stack and task_t.lr into r1 and lr - ldm r0, {r1, lr} - - ldmia r1!, {r4 - r11} - msr psp, r1 - - // Return, let the CPU restore the hardware part of the context - bx lr -.pool -.size PendSV_Handler,.-PendSV_Handler - -.end diff --git a/playground/include/debug.h b/playground/include/debug.h new file mode 100644 index 0000000..d2926b3 --- /dev/null +++ b/playground/include/debug.h @@ -0,0 +1,44 @@ +#ifndef DEBUG_H +#define DEBUG_H + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((format (printf, 1, 2))) +void dbg_printf(const char *fmt, ...); + +void dbg_putc(void * junk, char); + +enum SemihostingCmd { + SYS_CLOSE = 0x02, + SYS_CLOCK = 0x10, + SYS_ELAPSED = 0x30, + SYS_ERRNO = 0x13, + SYS_FLEN = 0x0C, + SYS_GET_CMDLINE = 0x15, + SYS_HEAPINFO = 0x16, + SYS_ISERROR = 0x08, + SYS_ISTTY = 0x09, + SYS_OPEN = 0x01, + SYS_READ = 0x06, + SYS_READC = 0x07, + SYS_REMOVE = 0x0E, + SYS_RENAME = 0x0F, + SYS_SEEK = 0x0A, + SYS_SYSTEM = 0x12, + SYS_TICKFREQ = 0x31, + SYS_TIME = 0x11, + SYS_TMPNAM = 0x0D, + SYS_WRITE = 0x05, + SYS_WRITEC = 0x03, + SYS_WRITE0 = 0x04, +}; + +void send_command(enum SemihostingCmd command, void *message); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/playground/include/init_high.h b/playground/include/init_high.h new file mode 100644 index 0000000..c6da514 --- /dev/null +++ b/playground/include/init_high.h @@ -0,0 +1,120 @@ +#ifndef INIT_HIGH_H +#define INIT_HIGH_H + +extern "C" { + +void init_high(); + +/** + * Declare all the interrupt/event handlers as weak symbols and make them aliases of the default handler. + */ +extern void Default_Handler() __attribute__((weak)); + +extern void _Reset_Handler(); + +extern void NMI_Handler(); + +extern void HardFault_Handler(); + +extern void MemManage_Handler(); + +extern void BusFault_Handler(); + +extern void UsageFault_Handler(); + +extern void SVC_Handler(); + +extern void DebugMon_Handler(); + +extern void PendSV_Handler(); + +extern void SysTick_Handler(); + +extern void WWDG_IRQHandler(); + +extern void PVD_IRQHandler(); + +extern void TAMPER_IRQHandler(); + +extern void RTC_IRQHandler(); + +extern void FLASH_IRQHandler(); + +extern void RCC_IRQHandler(); + +extern void EXTI0_IRQHandler(); + +extern void EXTI1_IRQHandler(); + +extern void EXTI2_IRQHandler(); + +extern void EXTI3_IRQHandler(); + +extern void EXTI4_IRQHandler(); + +extern void DMA1_Channel1_IRQHandler(); + +extern void DMA1_Channel2_IRQHandler(); + +extern void DMA1_Channel3_IRQHandler(); + +extern void DMA1_Channel4_IRQHandler(); + +extern void DMA1_Channel5_IRQHandler(); + +extern void DMA1_Channel6_IRQHandler(); + +extern void DMA1_Channel7_IRQHandler(); + +extern void ADC1_2_IRQHandler(); + +extern void USB_HP_CAN1_TX_IRQHandler(); + +extern void USB_LP_CAN1_RX0_IRQHandler(); + +extern void CAN1_RX1_IRQHandler(); + +extern void CAN1_SCE_IRQHandler(); + +extern void EXTI9_5_IRQHandler(); + +extern void TIM1_BRK_IRQHandler(); + +extern void TIM1_UP_IRQHandler(); + +extern void TIM1_TRG_COM_IRQHandler(); + +extern void TIM1_CC_IRQHandler(); + +extern void TIM2_IRQHandler(); + +extern void TIM3_IRQHandler(); + +extern void TIM4_IRQHandler(); + +extern void I2C1_EV_IRQHandler(); + +extern void I2C1_ER_IRQHandler(); + +extern void I2C2_EV_IRQHandler(); + +extern void I2C2_ER_IRQHandler(); + +extern void SPI1_IRQHandler(); + +extern void SPI2_IRQHandler(); + +extern void USART1_IRQHandler(); + +extern void USART2_IRQHandler(); + +extern void USART3_IRQHandler(); + +extern void EXTI15_10_IRQHandler(); + +extern void RTCAlarm_IRQHandler(); + +extern void USBWakeUp_IRQHandler(); +} + +#endif diff --git a/playground/include/playground.h b/playground/include/playground.h new file mode 100644 index 0000000..c224908 --- /dev/null +++ b/playground/include/playground.h @@ -0,0 +1,12 @@ +#ifndef PLAYGROUND_H +#define PLAYGROUND_H + +extern "C" void halt(); + +template +static inline +size_t SizeOfArray(const T(&)[N]) { + return N; +} + +#endif diff --git a/playground/include/stm32f10x_conf.h b/playground/include/stm32f10x_conf.h new file mode 100644 index 0000000..f663d12 --- /dev/null +++ b/playground/include/stm32f10x_conf.h @@ -0,0 +1,38 @@ +#ifndef __STM32F10x_CONF_H +#define __STM32F10x_CONF_H + +/* +#include "stm32f10x_adc.h" +#include "stm32f10x_bkp.h" +#include "stm32f10x_can.h" +#include "stm32f10x_cec.h" +#include "stm32f10x_crc.h" +#include "stm32f10x_dac.h" +#include "stm32f10x_dbgmcu.h" +#include "stm32f10x_dma.h" +#include "stm32f10x_exti.h" +#include "stm32f10x_flash.h" +#include "stm32f10x_fsmc.h" +#include "stm32f10x_gpio.h" +#include "stm32f10x_i2c.h" +#include "stm32f10x_iwdg.h" +#include "stm32f10x_pwr.h" +#include "stm32f10x_rcc.h" +#include "stm32f10x_rtc.h" +#include "stm32f10x_sdio.h" +#include "stm32f10x_spi.h" +#include "stm32f10x_tim.h" +#include "stm32f10x_usart.h" +#include "stm32f10x_wwdg.h" +#include "misc.h" +*/ + +#ifdef USE_FULL_ASSERT + #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__)) + + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0) +#endif + +#endif diff --git a/playground/src/debug.cpp b/playground/src/debug.cpp new file mode 100644 index 0000000..40f2169 --- /dev/null +++ b/playground/src/debug.cpp @@ -0,0 +1,44 @@ +#include "debug.h" +#include "tinyprintf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static void append_char(void *v, char c) { + *(*((char **) v))++ = c; +} + +void dbg_printf(const char *fmt, ...) { + char msg[100]; + msg[0] = 0; + + va_list va; + va_start(va, fmt); + char *a = msg; + char **b = &a; + tfp_format(b, append_char, fmt, va); + va_end(va); + append_char(b, '\0'); + + send_command(SYS_WRITE0, msg); +} + +void dbg_putc(void *, char c) { + char cc = c; + send_command(SYS_WRITEC, &cc); +} + +void send_command(enum SemihostingCmd command, void *message) { + int c = command; + + __asm volatile ( + "mov r0, %[cmd];" + "mov r1, %[msg];" + "bkpt #0xAB" : : [cmd] "r"(c), [msg] "r"(message) : "r0", "r1", "memory" + ); +} + +#ifdef __cplusplus +}; +#endif diff --git a/playground/src/init_high.cpp b/playground/src/init_high.cpp new file mode 100644 index 0000000..700d17a --- /dev/null +++ b/playground/src/init_high.cpp @@ -0,0 +1,315 @@ +#include +#include +#include "stm32f10x.h" +#include "debug.h" +#include "init_high.h" +#include "playground.h" + +/** + * Symbols that are defined by the linker + */ +extern uint32_t _copy_data_load, _copy_data_store, _copy_data_store_end; +extern uint32_t _bss_start, _bss_end; + +extern int main(); + +void init_high() { + // Copy data from flash to ram + uint32_t *src = &_copy_data_load; + uint32_t *dest = &_copy_data_store; + uint32_t *end = &_copy_data_store_end; + + while (dest <= end) { + *dest++ = *src++; + } + + // Clear the BSS segment + dest = &_bss_start; + end = &_bss_end; + while (dest <= end) { + *dest++ = 0; + } + + main(); +} + +__attribute__((used)) +struct { + uint32_t CFSR; + uint32_t HFSR; + uint32_t DFSR; + uint32_t AFSR; +// uint32_t MMAR; + uint32_t BFAR; +} Default_Handler_Info; + +__attribute__((used)) +void Default_Handler() { + Default_Handler_Info = { + CFSR: SCB->CFSR, + HFSR: SCB->HFSR, + DFSR: SCB->DFSR, + AFSR: SCB->AFSR, + BFAR: SCB->BFAR, + }; + + dbg_printf("Default handler:\n"); + + dbg_printf("HFSR: 0x%08lx\n", Default_Handler_Info.HFSR); + if (Default_Handler_Info.HFSR & SCB_HFSR_DEBUGEVT) { + dbg_printf(" HFSR.DEBUGEVT\n"); + } + if (Default_Handler_Info.HFSR & SCB_HFSR_FORCED) { + dbg_printf(" HFSR.FORCED\n"); + } + if (Default_Handler_Info.HFSR & SCB_HFSR_VECTTBL) { + dbg_printf(" HFSR.VECTTBL\n"); + } + + dbg_printf("CFSR: 0x%08lx\n", Default_Handler_Info.CFSR); + if (Default_Handler_Info.CFSR & SCB_CFSR_DIVBYZERO) { + dbg_printf(" UFSR.DIVBYZERO\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNALIGNED) { + dbg_printf(" UFSR.UNALIGED\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_NOCP) { + dbg_printf(" UFSR.NOCP\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_INVPC) { + dbg_printf(" UFSR.INVPC\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_INVSTATE) { + dbg_printf(" UFSR.INVSTATE\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNDEFINSTR) { + dbg_printf(" UFSR.UNDEFINSTR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { + dbg_printf(" BFSR.BFARVALID\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_STKERR) { + dbg_printf(" BFSR.STKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_UNSTKERR) { + dbg_printf(" BFSR.UNSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) { + dbg_printf(" BFSR.IMPRECISERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IMPRECISERR) { + dbg_printf(" BFSR.IMPRECISERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_PRECISERR) { + dbg_printf(" BFSR.PRECISERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IBUSERR) { + dbg_printf(" BFSR.IBUSERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MMARVALID) { + dbg_printf(" MMFSR.MMARVALID\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MSTKERR) { + dbg_printf(" MMFSR.MSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_MUNSTKERR) { + dbg_printf(" MMFSR.MUNSTKERR\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_DACCVIOL) { + dbg_printf(" MMFSR.DACCVIOL\n"); + } + if (Default_Handler_Info.CFSR & SCB_CFSR_IACCVIOL) { + dbg_printf(" MMFSR.IACCVIOL\n"); + } + dbg_printf("DFSR: 0x%08lx\n", Default_Handler_Info.DFSR); + dbg_printf("AFSR: 0x%08lx\n", Default_Handler_Info.AFSR); + + if (Default_Handler_Info.CFSR & SCB_CFSR_BFARVALID) { + dbg_printf("BFAR: 0x%08lx\n", Default_Handler_Info.BFAR); + } else { + dbg_printf("BFAR: \n"); + } + + dbg_printf("NVIC:\n"); + for (size_t i = 0; i < SizeOfArray(NVIC->IABR); i++) { + dbg_printf(" IABR[%d]: 0x%08lx\n", i, NVIC->IABR[i]); + } + + halt(); +} + +void _Reset_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void NMI_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void HardFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void MemManage_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void BusFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void UsageFault_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void SVC_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void DebugMon_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void PendSV_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void SysTick_Handler() __attribute__ ((weak, alias("Default_Handler"))); + +void WWDG_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void PVD_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TAMPER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RTC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void FLASH_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RCC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel6_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void DMA1_Channel7_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void ADC1_2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USB_HP_CAN1_TX_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USB_LP_CAN1_RX0_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void CAN1_RX1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void CAN1_SCE_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI9_5_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_BRK_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_UP_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_TRG_COM_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM1_CC_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void TIM4_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C1_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C1_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C2_EV_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void I2C2_ER_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void SPI1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void SPI2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART1_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART2_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USART3_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void EXTI15_10_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void RTCAlarm_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +void USBWakeUp_IRQHandler() __attribute__ ((weak, alias("Default_Handler"))); + +__attribute__((section(".isr_vectors"), used)) +uint32_t isr_vectors[74] = { + (uint32_t) _Reset_Handler, + (uint32_t) NMI_Handler, + (uint32_t) HardFault_Handler, + (uint32_t) MemManage_Handler, + (uint32_t) BusFault_Handler, + (uint32_t) UsageFault_Handler, + 0, + 0, + 0, + 0, + (uint32_t) SVC_Handler, + (uint32_t) DebugMon_Handler, + 0, + (uint32_t) PendSV_Handler, + (uint32_t) SysTick_Handler, + (uint32_t) WWDG_IRQHandler, + (uint32_t) PVD_IRQHandler, + (uint32_t) TAMPER_IRQHandler, + (uint32_t) RTC_IRQHandler, + (uint32_t) FLASH_IRQHandler, + (uint32_t) RCC_IRQHandler, + (uint32_t) EXTI0_IRQHandler, + (uint32_t) EXTI1_IRQHandler, + (uint32_t) EXTI2_IRQHandler, + (uint32_t) EXTI3_IRQHandler, + (uint32_t) EXTI4_IRQHandler, + (uint32_t) DMA1_Channel1_IRQHandler, + (uint32_t) DMA1_Channel2_IRQHandler, + (uint32_t) DMA1_Channel3_IRQHandler, + (uint32_t) DMA1_Channel4_IRQHandler, + (uint32_t) DMA1_Channel5_IRQHandler, + (uint32_t) DMA1_Channel6_IRQHandler, + (uint32_t) DMA1_Channel7_IRQHandler, + (uint32_t) ADC1_2_IRQHandler, + (uint32_t) USB_HP_CAN1_TX_IRQHandler, + (uint32_t) USB_LP_CAN1_RX0_IRQHandler, + (uint32_t) CAN1_RX1_IRQHandler, + (uint32_t) CAN1_SCE_IRQHandler, + (uint32_t) EXTI9_5_IRQHandler, + (uint32_t) TIM1_BRK_IRQHandler, + (uint32_t) TIM1_UP_IRQHandler, + (uint32_t) TIM1_TRG_COM_IRQHandler, + (uint32_t) TIM1_CC_IRQHandler, + (uint32_t) TIM2_IRQHandler, + (uint32_t) TIM3_IRQHandler, + (uint32_t) TIM4_IRQHandler, + (uint32_t) I2C1_EV_IRQHandler, + (uint32_t) I2C1_ER_IRQHandler, + (uint32_t) I2C2_EV_IRQHandler, + (uint32_t) I2C2_ER_IRQHandler, + (uint32_t) SPI1_IRQHandler, + (uint32_t) SPI2_IRQHandler, + (uint32_t) USART1_IRQHandler, + (uint32_t) USART2_IRQHandler, + (uint32_t) USART3_IRQHandler, + (uint32_t) EXTI15_10_IRQHandler, + (uint32_t) RTCAlarm_IRQHandler, + (uint32_t) USBWakeUp_IRQHandler, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 +}; diff --git a/playground/src/init_low.s b/playground/src/init_low.s new file mode 100644 index 0000000..bc12b5b --- /dev/null +++ b/playground/src/init_low.s @@ -0,0 +1,42 @@ +.syntax unified +.cpu cortex-m3 +.thumb + +.section .text + +.thumb_func +.global _Reset_Handler +_Reset_Handler: + bl init_high + b halt + +.thumb_func +.global halt +halt: + b . + +.thumb_func +NMI_Handler: + b halt + +.thumb_func +HardFault_Handler: + tst lr, #4 + ite eq + mrseq r0, msp + mrsne r0, psp + b HardFault_Handler_C + +.thumb_func +MemManage_Handler: + b halt + +.thumb_func +BusFault_Handler: + b halt + +.thumb_func +UsageFault_Handler: + b halt + +.end diff --git a/serial1.cpp b/serial1.cpp deleted file mode 100644 index 60e9bc9..0000000 --- a/serial1.cpp +++ /dev/null @@ -1,128 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "debug.h" -#include "tinyprintf.h" - -extern "C" void halt(); - -#include "stm32f10x_conf.h" - -extern "C" -__attribute__((naked)) -void HardFault_Handler_C(uint32_t *hardfault_args) { - halt(); -} - -size_t strlen(const char *s) { - size_t size = 0; - while (*s++ != '\0') size++; - return size; -} - -int run = 1; - -volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE; - -/* - * When we get there the stack pointer is set - */ -int main() { - SystemInit(); - - init_printf(nullptr, dbg_putc); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO - | RCC_APB2Periph_USART1 - | RCC_APB2Periph_GPIOA - | RCC_APB2Periph_GPIOB - | RCC_APB2Periph_GPIOC, - ENABLE); - - /* ***************************************** */ - - // Debug on port B - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - - // Make Port B's pin #5 the debug output pin - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Pin = GPIO_Pin_5; - init.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &init); - - /* ***************************************** */ - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); - - /* - * PA9 USART1_TX - * PA10 USART1_RX - */ - - // Enable USART1 - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); - - // Make the TX pin an output - GPIO_StructInit(&init); - init.GPIO_Pin = GPIO_Pin_9; - init.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &init); - - // 8 bit mode - USART1->CR1 &= ~USART_CR1_M; - USART1->CR2 &= ~USART_CR2_STOP_1; - - USART1->CR1 |= USART_CR1_UE /* Set UART Enable */ - | USART_CR1_TE; /* Set Transmission Enable */ - - // Set baud rate - int mantissa = 39; - int fraction = static_cast(16 * 0.0625); // == 1 - // 72M / (16*39.0625) = 115200 - USART1->BRR = static_cast(mantissa << 4 | fraction); - - char c = 'A'; - while (run) { - int txe = USART1->SR & USART_SR_TXE; - -// dbg_printf("1:%d?\n", x); - -// char mm[100]; -// tfp_sprintf(mm, "2:%d?\n", x); -// send_command(SYS_WRITE0, mm); - -// printf(" %u?\n", usart1->SR); -// printf(" %u?\n", 1); - - if (txe) { - GPIO_SetBits(GPIOB, GPIO_Pin_All); - GPIO_ResetBits(GPIOB, GPIO_Pin_All); - - USART1->DR = (uint16_t) c; -// USART1->DR = 0x55; - - if (c == 'Z') { - c = 'a'; - } else if (c == 'z') { - c = '0'; - } else if (c == '9') { - c = '\n'; - } else if (c == '\n') { - c = 'A'; - } else { - c++; - } - } - } - - return 0; -} - diff --git a/serial2.cpp b/serial2.cpp deleted file mode 100644 index c0259ea..0000000 --- a/serial2.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "tinyprintf.h" -#include "playground.h" - -extern "C" -__attribute__((naked, used)) -void HardFault_Handler_C(uint32_t *hardfault_args) { - dbg_printf("r0 = 0x%08lx (%lu)\n", hardfault_args[0], hardfault_args[0]); - dbg_printf("r1 = 0x%08lx (%lu)\n", hardfault_args[1], hardfault_args[1]); - dbg_printf("r2 = 0x%08lx (%lu)\n", hardfault_args[2], hardfault_args[2]); - dbg_printf("r3 = 0x%08lx (%lu)\n", hardfault_args[3], hardfault_args[3]); - dbg_printf("r12 = 0x%08lx (%lu)\n", hardfault_args[4], hardfault_args[4]); - dbg_printf("lr = 0x%08lx (%lu)\n", hardfault_args[5], hardfault_args[5]); - dbg_printf("pc = 0x%08lx (%lu)\n", hardfault_args[6], hardfault_args[6]); - dbg_printf("psr = 0x%08lx (%lu)\n", hardfault_args[7], hardfault_args[7]); - dbg_printf("\n"); - - halt(); -} - -size_t strlen(const char *s) { - size_t size = 0; - while (*s++ != '\0') size++; - return size; -} - -int run = 1; - -volatile USART_TypeDef *usart1 = (volatile USART_TypeDef *) USART1_BASE; - -volatile uint8_t tx_ready = 0; - -/* - * When we get there the stack pointer is set - */ -int main() { - SystemInit(); - - init_printf(nullptr, dbg_putc); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO - | RCC_APB2Periph_USART1 - | RCC_APB2Periph_GPIOA - | RCC_APB2Periph_GPIOB - | RCC_APB2Periph_GPIOC, - ENABLE); - - /* ***************************************** */ - - // Debug on port B - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - - // Make Port B's pin #5 the debug output pin - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Pin = GPIO_Pin_5; - init.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &init); - - /* ***************************************** */ - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); - - /* - * PA9 USART1_TX - * PA10 USART1_RX - */ - - // Enable USART1 - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE); - - // Make the TX pin an output - GPIO_StructInit(&init); - init.GPIO_Pin = GPIO_Pin_9; - init.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &init); - - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); - NVIC_InitTypeDef NVIC_InitStruct = { - NVIC_IRQChannel: USART1_IRQn, - NVIC_IRQChannelPreemptionPriority: 0, - NVIC_IRQChannelSubPriority: 0, - NVIC_IRQChannelCmd: ENABLE, - }; - NVIC_Init(&NVIC_InitStruct); - NVIC_EnableIRQ(USART1_IRQn); - - // 8 bit mode - USART1->CR1 &= ~USART_CR1_M; - USART1->CR2 &= ~USART_CR2_STOP_1; - - // Set baud rate - int mantissa = 39; - int fraction = static_cast(16 * 0.0625); // == 1 - // 72M / (16*39.0625) = 115200 - USART1->BRR = static_cast(mantissa << 4 | fraction); - - USART1->CR1 |= USART_CR1_UE /* Set UART Enable */ - | USART_CR1_TE /* Set Transmission Enable */ - | USART_CR1_TXEIE; /* Set TX buffer Empty Interrupt Enable */ - - char c = 'A'; - tx_ready = 1; - while (run) { - // wait for TX to be ready - while (!tx_ready); - tx_ready = 0; - - GPIO_SetBits(GPIOB, GPIO_Pin_All); - GPIO_ResetBits(GPIOB, GPIO_Pin_All); - - USART1->DR = (uint16_t) c; - USART_ITConfig(USART1, USART_IT_TXE, ENABLE); - - if (c == 'Z') { - c = 'a'; - } else if (c == 'z') { - c = '0'; - } else if (c == '9') { - c = '\n'; - } else if (c == '\n') { - c = 'A'; - } else { - c++; - } - } - - return 0; -} - -extern "C" -void USART1_IRQHandler() { - tx_ready = 1; - - if (USART_GetITStatus(USART1, USART_IT_TXE) == SET) { - // Disable the interrupt - USART_ITConfig(USART1, USART_IT_TXE, DISABLE); - } -} diff --git a/test1.cpp b/test1.cpp deleted file mode 100644 index a883876..0000000 --- a/test1.cpp +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "playground.h" - -extern "C" -__attribute__((naked)) -void HardFault_Handler_C(uint32_t *hardfault_args); - -extern "C" void high(); -extern "C" void low(); - -SCB_Type *__SCB = ((SCB_Type *) SCB_BASE); -//extern SCB_Type *__SCB; - -struct hardfault_data_t { - uint32_t r0; - uint32_t r1; - uint32_t r2; - uint32_t r3; - uint32_t r12; - uint32_t lr; - uint32_t pc; - uint32_t psr; -}; - -volatile struct hardfault_data_t *hardfault_data = (volatile struct hardfault_data_t *) 0x20000800; - -void HardFault_Handler_C(uint32_t *hardfault_args) { - hardfault_data->r0 = hardfault_args[0]; - hardfault_data->r1 = hardfault_args[1]; - hardfault_data->r2 = hardfault_args[2]; - hardfault_data->r3 = hardfault_args[3]; - hardfault_data->r12 = hardfault_args[4]; - hardfault_data->lr = hardfault_args[5]; - hardfault_data->pc = hardfault_args[6]; - hardfault_data->psr = hardfault_args[7]; - - halt(); -} - -void send_command(int command, void *message) { - bool active = (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == CoreDebug_DHCSR_C_DEBUGEN_Msk; - - if (!active) { - return; - } - - __asm volatile ( - "mov r0, %[cmd];" - "mov r1, %[msg];" - "bkpt #0xAB" : : [cmd] "r"(command), [msg] "r"(message) : "r0", "r1", "memory" - ); -} - -size_t strlen(const char *s) { - size_t size = 0; - while (*s++ != '\0') size++; - return size; -} - -int run = 1; - -/* - * When we get there the stack pointer is set - */ -int main() { - SystemInit(); -// SystemCoreClockUpdate(); - - SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_MEMFAULTPENDED_Msk | SCB_SHCSR_BUSFAULTENA_Msk; - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE); - - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE); - - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOA, - ENABLE); - - GPIO_InitTypeDef init; - GPIO_StructInit(&init); - init.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &init); - - while (run) { -// GPIO_SetBits(GPIOA, GPIO_Pin_All); - GPIO_SetBits(GPIOB, GPIO_Pin_All); -// GPIO_SetBits(GPIOC, GPIO_Pin_All); - -// GPIO_ResetBits(GPIOA, GPIO_Pin_All); - GPIO_ResetBits(GPIOB, GPIO_Pin_All); -// GPIO_ResetBits(GPIOC, GPIO_Pin_All); - } - - return 0; -} -- cgit v1.2.3