From e5d891fbb9c672cf8c5ec31d7540a9e55747b3a0 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Thu, 19 Jan 2023 00:03:18 -0700 Subject: Switch to use CMake --- .gitignore | 1 + CMakeLists.txt | 58 +++++++++++++++++++++++++++++++++++++ Makefile | 20 ------------- blinky.c | 90 ---------------------------------------------------------- linker/ls.ld | 18 ++++++++++++ ls.ld | 18 ------------ src/blinky.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 167 insertions(+), 128 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 Makefile delete mode 100644 blinky.c create mode 100644 linker/ls.ld delete mode 100644 ls.ld create mode 100644 src/blinky.c diff --git a/.gitignore b/.gitignore index 7cf238f..2cbf855 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o *.elf *.bin +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ee1147f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 3.10) +project (ch537) + +set (CMAKE_SYSTEM_NAME Generic) # Configure for Bare Metal. +set (CMAKE_SYSTEM_PROCESSOR riscv32) + +set (TC_PREFIX riscv32-unknown-elf-) +# set (CMAKE_VERBOSE_MAKEFILE ON) + +include_directories(include linker) + +file (GLOB SOURCES "src/*.c") +file (GLOB LINKER_SCRIPT "linker/*.ld") + +file (REAL_PATH "ch-flash/" CH_FLASH_DIR) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_C_FLAGS "-march=rv32imac -mabi=ilp32 -lgcc -static -nostartfiles -O -std=gnu99" CACHE INTERNAL "C Compiler options") +set(CMAKE_EXE_LINKER_FLAGS "--cref -static -T ${LINKER_SCRIPT}" CACHE INTERNAL "Linker options") + +set (CMAKE_C_COMPILER ${TC_PREFIX}gcc CACHE INTERNAL "C Compiler") +set (CMAKE_OBJCOPY ${TC_PREFIX}objcopy CACHE INTERNAL "Object Copier") +set (CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Linker options for release build type") + +set (CMAKE_C_LINK_EXECUTABLE "${TC_PREFIX}ld -o ") +add_executable(main.elf ${SOURCES}) +set_target_properties(main.elf PROPERTIES + LINK_FLAGS "--nostdlib -e 0") + +# Generates the binary with objcopy. +add_custom_command( + OUTPUT main.bin + DEPENDS main.elf + COMMENT "objcopy -O binary main.elf main.bin" + COMMAND ${CMAKE_OBJCOPY} ARGS -O binary main.elf main.bin +) +add_custom_command( + OUTPUT objdump.txt + DEPENDS main.elf + COMMAND ${TC_PREFIX}objdump -D main.elf > objdump.txt +) +add_custom_target(main_bin ALL DEPENDS main.bin objdump.txt) + +# generates the flash binary +add_custom_command( + OUTPUT ${CH_FLASH_DIR}/ch-flash + COMMAND cd ${CH_FLASH_DIR} && make +) + +add_custom_target( + flash + DEPENDS main.bin ch-flash/ch-flash + COMMAND ${CH_FLASH_DIR}/ch-flash -f main.bin +) + +# add_custom_target( +# debug +# COMMAND "${TC_PREFIX}gdb" -tui -ex "tar ext :3333" -ex "file main.elf") diff --git a/Makefile b/Makefile deleted file mode 100644 index ce65816..0000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -CC=riscv32-unknown-elf-gcc -LD=riscv32-unknown-elf-ld -CPY=riscv32-unknown-elf-objcopy - -all: blinky.bin - -blinky.bin: blinky.elf - $(CPY) -O binary blinky.elf blinky.bin - -blinky.o: blinky.c - $(CC) -Os -lgcc -static -nostartfiles -o blinky.o -c blinky.c - -blinky.elf: blinky.o ls.ld - $(LD) --cref -static -T ls.ld -o blinky.elf blinky.o - -flash: all - sudo ~/Projects/isp55e0/isp55e0 -f blinky.bin - -clean: - rm -rf *.o *.elf *.bin diff --git a/blinky.c b/blinky.c deleted file mode 100644 index 001e185..0000000 --- a/blinky.c +++ /dev/null @@ -1,90 +0,0 @@ -#include - -/* - * Function (or really pointer to code) for the reset interrupt handler. - */ -void on_reset(void); - -/* - * Function which delays for a bit. - */ -void delay(void); - -/* Type def to a void function to make things mor ereadable. */ -typedef void (*isr_routine)(void); - -/* Gpio configuration structure. This is exactly how it is laid out in - * memory. In these registers bit X referes to pin X. */ -typedef struct { - /* The direction of the gpio pin. 1 = output, 0 = input. */ - uint32_t dir; - - /* The value of the gpio pin (for input). */ - uint32_t in; - - /* Write to set the output value for the pin. */ - uint32_t out; - - /* The clear value. Resets the pin to what it is at reset. */ - uint32_t clr; - - /* Sets the pin to be pull-up on logical 1 in input mode. */ - uint32_t pu; - - /* Sets whether the pin should be pull-down (open-drain) for logical 0 or - * drive for logical 1. 1 = pull-down, 0 = drive. */ - uint32_t pd_drv; -} gpio_t; - -/** The ISR Vector structure. This is linked to starting at address 0. */ -__attribute((__section__(".isr_vector"))) volatile struct { - // What NULL points to. nothing useful. - uint32_t reserved__; - // Called when the device boots or reset is pressed. - isr_routine reset_cb; - isr_routine nmi_cb; - isr_routine exc_cb; -} isr_vectors = {.reset_cb = on_reset}; - -// GPIO configuration registers. These are defined in the linker script. -extern volatile gpio_t gpio_a; -extern volatile gpio_t gpio_b; - -/* Main routine. This is called on_reset once everything else has been set up. - */ -static void start(void) -{ - uint32_t bit = 1 << 8; - gpio_a.dir |= bit; // Set to "out" - gpio_a.pd_drv |= bit; // Set to "open drain" - - for (;;) { - gpio_a.out &= ~bit; // Pin low (turns on LED) - delay(); - gpio_a.out |= bit; // Pin high (turns off LED) - delay(); - } -} - -/* - * The reset callback.This has to be a naked function because the stack pointer - * may not be initialized!!. - */ -__attribute((naked)) void on_reset(void) -{ - // Set up the stack pointer to point to the end of SRAM. - asm volatile( - "li sp,0x20008000\n" - "addi sp,sp,-4\n" - "jalr %0\n" - "spin:\n" - "j spin\n" - : - : "r"(start)); -} - -void delay(void) -{ - for (volatile uint32_t i = 0; i < 20000; ++i) - ; -} diff --git a/linker/ls.ld b/linker/ls.ld new file mode 100644 index 0000000..dbac92b --- /dev/null +++ b/linker/ls.ld @@ -0,0 +1,18 @@ +MEMORY +{ + flash : org = 0x00000000, len = 512k + sram : org = 0x20003800, len = 18k +} + +SECTIONS +{ + gpio_a = ABSOLUTE(0x400010A0); + gpio_b = ABSOLUTE(0x400010C0); + + . = ORIGIN(flash); + .text : ALIGN(0x04) { + *(.isr_vector); + . = ALIGN(0x100); + *(.text); + } >flash AT>flash +} diff --git a/ls.ld b/ls.ld deleted file mode 100644 index dbac92b..0000000 --- a/ls.ld +++ /dev/null @@ -1,18 +0,0 @@ -MEMORY -{ - flash : org = 0x00000000, len = 512k - sram : org = 0x20003800, len = 18k -} - -SECTIONS -{ - gpio_a = ABSOLUTE(0x400010A0); - gpio_b = ABSOLUTE(0x400010C0); - - . = ORIGIN(flash); - .text : ALIGN(0x04) { - *(.isr_vector); - . = ALIGN(0x100); - *(.text); - } >flash AT>flash -} diff --git a/src/blinky.c b/src/blinky.c new file mode 100644 index 0000000..ca93df6 --- /dev/null +++ b/src/blinky.c @@ -0,0 +1,90 @@ +#include + +/* + * Function (or really pointer to code) for the reset interrupt handler. + */ +void on_reset(void); + +/* + * Function which delays for a bit. + */ +void delay(void); + +/* Type def to a void function to make things mor ereadable. */ +typedef void (*isr_routine)(void); + +/* Gpio configuration structure. This is exactly how it is laid out in + * memory. In these registers bit X referes to pin X. */ +typedef struct { + /* The direction of the gpio pin. 1 = output, 0 = input. */ + uint32_t dir; + + /* The value of the gpio pin (for input). */ + uint32_t in; + + /* Write to set the output value for the pin. */ + uint32_t out; + + /* The clear value. Resets the pin to what it is at reset. */ + uint32_t clr; + + /* Sets the pin to be pull-up on logical 1 in input mode. */ + uint32_t pu; + + /* Sets whether the pin should be pull-down (open-drain) for logical 0 or + * drive for logical 1. 1 = pull-down, 0 = drive. */ + uint32_t pd_drv; +} gpio_t; + +/** The ISR Vector structure. This is linked to starting at address 0. */ +__attribute((__section__(".isr_vector"))) volatile struct { + // What NULL points to. nothing useful. + uint32_t reserved__; + // Called when the device boots or reset is pressed. + isr_routine reset_cb; + isr_routine nmi_cb; + isr_routine exc_cb; +} isr_vectors = {.reset_cb = on_reset}; + +// GPIO configuration registers. These are defined in the linker script. +extern volatile gpio_t gpio_a; +extern volatile gpio_t gpio_b; + +/* Main routine. This is called on_reset once everything else has been set up. + */ +static void start(void) +{ + uint32_t bit = 1 << 8; + gpio_a.dir |= bit; // Set to "out" + gpio_a.pd_drv |= bit; // Set to "open drain" + + for (;;) { + gpio_a.out &= ~bit; // Pin low (turns on LED) + delay(); + gpio_a.out |= bit; // Pin high (turns off LED) + delay(); + } +} + +/* + * The reset callback.This has to be a naked function because the stack pointer + * may not be initialized!!. + */ +__attribute((naked)) void on_reset(void) +{ + // Set up the stack pointer to point to the end of SRAM. + asm volatile( + "li sp,0x20008000\n" + "addi sp,sp,-4\n" + "jalr %0\n" + "spin:\n" + "j spin\n" + : + : "r"(start)); +} + +void delay(void) +{ + for (volatile uint32_t i = 0; i < 10000; ++i) + ; +} -- cgit