From 43b1749173f70bdf67884d920b93f6a5b1f19a1d Mon Sep 17 00:00:00 2001 From: Robin Krens Date: Thu, 15 Aug 2019 02:17:55 +0800 Subject: [PATCH] added commenting, removed deprecated functions --- Makefile | 2 +- README.md | 60 +++++++++++++++++++++++++++++++++++ clock.c | 2 +- drivers/tm1637.c | 3 -- drivers/tsensor.c | 9 +++--- drivers/uart.c | 11 +++---- img/screenshot.png | Bin 0 -> 10773 bytes include/drivers/tm1637.h | 3 ++ include/lib/regfunc.h | 11 ++++--- include/sys/robsys.h | 4 +-- ivt.c | 3 +- lib/regfunc.c | 28 ++++++++++++----- lib/stdio.c | 14 +++++++++ lib/string.c | 12 ++++++- link.ld | 24 +++++++++++++- main.c | 79 ++++++++++++++++------------------------------- rtc.c | 5 +-- start.asm | 16 +++------- sysinfo.c | 12 +++---- systick.c | 20 +++++++++--- term.c | 47 ++++++++++++++-------------- 21 files changed, 228 insertions(+), 137 deletions(-) create mode 100644 README.md create mode 100644 img/screenshot.png diff --git a/Makefile b/Makefile index 678ac90..949e287 100644 --- a/Makefile +++ b/Makefile @@ -10,11 +10,11 @@ AS=arm-none-eabi-as MKIMG=arm-none-eabi-objcopy # Compiler flags -# TODO:Cortex-m3 or Cortex-m0? LDFLAGS+= -mthumb -mcpu=cortex-m3 ASFLAGS+= -mcpu=cortex-m3 -mthumb -g CFLAGS+= -mcpu=cortex-m3 -mthumb -g -ffreestanding +# Include directory INCLUDE+= -Iinclude BIN = bin diff --git a/README.md b/README.md new file mode 100644 index 0000000..605b49a --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# CORTEX M3 FROM SCRATCH + +This is my little 'Cortex M3 from scratch' project. No external libraries +or IDEs are used. Everything is written from scratch. My development environment +consist of nothing more than: + + * GCC-arm-none (standard ARM cross compiler) + * VIM editor + * stm32flash + +The board I use is a cheap Chinese STM32F103 ripoff. In theory, you should be able to +port this code to any Cortex M0/M3/M4/M7 board. + +## PROGRESS STATUS +Setup bare development environment [COMPLETED] + FILES: Makefile, link.d +Boot and jump to C [COMPLETED] + FILES: start.asm, main.c, include/sys/mmap.h, include/sys/robsys.h +Interrupt Handling [COMPLETED] + FILE: ivt.c, lib/string.c +Basic input and output (UART) [COMPLETED] + FILES: driver/uart.c, lib/stdio.c +SysTick [COMPLETED] + FILE: systick.c +System Info [COMPLETED] + FILE: sysinfo.c +High Speed External Clock / tuning [COMPLETED] + FILE: clock.c +RTC (Real Time Clock) [COMPLETED] + FILE: rtc.c +Built-in-shell [COMPLETED] + FILE: term.c +Port printf/libc library [COMPLETED] + FILE: lib/tinyprintf.c +Basic drivers + EEPROM: driver/at24c.c [COMPLETED] + UART drivers/uart.c [COMPLETED] + LED segment display: drivers/tm1637.c [COMPLETED] + Temperature sensor: drivers/tsensor.c [IN PROGRESS] + OLED display [PLANNED] + Joystick [PLANNED] +Memory Management [IN PROGRESS] + FILE: lib/pool.c +User Mode [PLANNED] +System Call PendV implementation [PLANNED] +Stack trace debug [IN PROGRESS] +Memory Protection Unit [PLANNED] +Loadable programs from EEPROM [PLANNED] +Multiple processes and scheduling [PLANNED] + +## SCREENSHOTS +Here is a screenshot that shows the terminal just after booting: + +![Screenshot](https://github.com/robinkrens/cortex-from-scratch/raw/master/img/ +screenshot.png "screenshot") + + + + + diff --git a/clock.c b/clock.c index 02a26ab..498097c 100644 --- a/clock.c +++ b/clock.c @@ -5,7 +5,7 @@ * Initial version * * $DESCRIPTION$ - * 1. Routines to setup the high speed external (HSE) clock. + * Routines to setup the high speed external (HSE) clock. * Initially a (less accurate) high speed internal (HSI) * clock is used. PPL is enabled; HSE is input for PPL. * PPL is multiplied to get the desired clock speed. diff --git a/drivers/tm1637.c b/drivers/tm1637.c index 1d78f7a..86a18af 100644 --- a/drivers/tm1637.c +++ b/drivers/tm1637.c @@ -37,9 +37,6 @@ #define TIMEOUT 5000 -#define DOT true -#define NODOT false - #define WRITE_CMD 0x20 /* STM32F1 microcontrollers do not provide the ability to pull-up SDA and SCL lines. Their diff --git a/drivers/tsensor.c b/drivers/tsensor.c index 3799095..d1ebcd4 100644 --- a/drivers/tsensor.c +++ b/drivers/tsensor.c @@ -2,10 +2,11 @@ * * $LOG$ * 2019/8/4 - ROBIN KRENS - * Initial version + * PreInitial version * * $DESCRIPTION$ - * Temperature sensor + * Temperature sensor + * [in dev] * * */ @@ -29,7 +30,7 @@ bool s1, s2; void * update_handler() { - s1 = false; +/* s1 = false; s2 = false; ccr1 = 0xFFFFFFFF; ccr2 = 0xFFFFFFFF; @@ -74,7 +75,7 @@ bool s1, s2; printf("EDGE UP\n"); s1 = false; - s2 = false; + s2 = false; */ } static void reset() { diff --git a/drivers/uart.c b/drivers/uart.c index 0090ef2..5e53362 100644 --- a/drivers/uart.c +++ b/drivers/uart.c @@ -70,10 +70,10 @@ void uart_putc(unsigned char ch) { if (ch == '\n') { while(!rchkbit(USART1_SR, 6)); - regw_u8(USART1_DR, 0x0D, 0, OWRITE); // return line + rwrite(USART1_DR, 0x0D); // return line } while(!rchkbit(USART1_SR, 6)); - regw_u8(USART1_DR, ch, 0, OWRITE); + rwrite(USART1_DR, ch); } char uart_getc(void) { @@ -99,13 +99,10 @@ char uart_getc(void) { void set_baudrate() { -// rwrite(USART1_BRR, 0x000001A1); 48 MHZ -// rwrite(USART1_BRR, 0x0000022B); 64 MHz -// rwrite(USART1_BRR, 0x00000138); 36 MHz // rwrite(USART1_BRR, 0x00000271); 72 MHz #ifdef ENABLE_HSE - rwrite(USART1_BRR, 0x00000138); + rwrite(USART1_BRR, 0x00000138); // 36 MHz #else - rwrite(USART1_BRR, 0x00000045); + rwrite(USART1_BRR, 0x00000045); // 8 Mhz #endif } diff --git a/img/screenshot.png b/img/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..d2823f726ea4333a53f35e34dbbde2ce769e1f55 GIT binary patch literal 10773 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 literal 0 HcmV?d00001 diff --git a/include/drivers/tm1637.h b/include/drivers/tm1637.h index 64e1f78..f9ada9c 100644 --- a/include/drivers/tm1637.h +++ b/include/drivers/tm1637.h @@ -1,6 +1,9 @@ #ifndef __TM1637_H #define __TM1637_H +#define DOT true +#define NODOT false + /* HELPER SUBROUTINES DECLARATIONS */ static void start_condition(); static void stop_condition(); diff --git a/include/lib/regfunc.h b/include/lib/regfunc.h index b13c28f..ca5992c 100644 --- a/include/lib/regfunc.h +++ b/include/lib/regfunc.h @@ -1,10 +1,13 @@ /* regfunc.h */ -extern char * regtohex(uint32_t ); -extern uint32_t hextoreg(char *); +/* DEPRECATED extern char * regtohex(uint32_t ); */ +extern uint32_t hextoreg(char *); // TODO: scanf extern void rsetbit(volatile uint32_t *, short); extern void rclrbit(volatile uint32_t *, short); extern void rsetbitsfrom(volatile uint32_t *, short, int); extern int rchkbit(volatile uint32_t *, short); extern void rwrite(volatile uint32_t *, uint32_t); -extern void regw_u8(volatile uint32_t *, uint8_t, short, short); -extern void regw_u32(volatile uint32_t *, uint32_t, short, short); + +/* DEPRECATED + * extern void regw_u8(volatile uint32_t *, uint8_t, short, short); + * extern void regw_u32(volatile uint32_t *, uint32_t, short, short); +*/ diff --git a/include/sys/robsys.h b/include/sys/robsys.h index 6962770..8070e60 100644 --- a/include/sys/robsys.h +++ b/include/sys/robsys.h @@ -9,8 +9,8 @@ * rates etc. */ //#define ENABLE_HSE -//efine CRYSTAL_MHZ 8 -//efine CLKSPEED_MHZ 72 +//#define CRYSTAL_MHZ 8 +//#define CLKSPEED_MHZ 72 extern void clock_init(); // extern int clock_test(); // extern void clock_reset(); diff --git a/ivt.c b/ivt.c index 02c45ec..d62a8dd 100644 --- a/ivt.c +++ b/ivt.c @@ -113,7 +113,6 @@ __attribute__ ((interrupt)) void * dummy_isr( struct interrupt_frame * frame ) { uint8_t nr = *SCB_VTOR_ST & 0xFF; - //printf("PC:%p\n",frame->lr); printf("EXCEPTION: %s\n", exception_message(nr)); printf("STACK TRACE:\n"); printf("R0:%p\n",frame->r0); @@ -149,6 +148,6 @@ void ivt_init() { * relocated to other memory locations. We can do this by setting * a register in the NVIC called the vector table offset register */ - regw_u32(SCB_VTOR, (uint32_t) &ivt, 0, OWRITE); + rwrite(SCB_VTOR, (uint32_t) &ivt); } diff --git a/lib/regfunc.c b/lib/regfunc.c index 9ea7d7b..f5bc539 100644 --- a/lib/regfunc.c +++ b/lib/regfunc.c @@ -1,3 +1,14 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/20 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Helper functions to set registers + * + * */ + #include #include #include @@ -24,6 +35,7 @@ void rclrbit(volatile uint32_t * reg, short pos) { *reg = *reg & ~(0x1 << pos); } +// check if a bit is set int rchkbit(volatile uint32_t * reg, short pos) { if ((*reg >> pos) & 0x1) return 1; @@ -36,7 +48,7 @@ void rwrite(volatile uint32_t * reg, uint32_t val) { } -/* write value (uint8_t) to register */ +/* DEPRECATED write value (uint8_t) to register void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) { switch(flag) { @@ -50,9 +62,9 @@ void regw_u8(volatile uint32_t * reg, uint8_t val, short shift, short flag) { *reg = *reg & ~(val << shift); break; } -} +} */ -/* write value (uint32_t) to register */ +/* DEPRECATED write value (uint32_t) to register void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) { switch(flag) { @@ -66,11 +78,9 @@ void regw_u32(volatile uint32_t * reg, uint32_t val, short shift, short flag) { *reg = *reg & ~(val << shift); break; } -} - -/* Print out the hexidecimal representation of an integer - After implementation of scanf or sth this will be obsolete. */ +} */ +/* Deprecated use printf instead char hexbuf[8]; char * regtohex(uint32_t addr) { char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'}; @@ -89,7 +99,9 @@ char * regtohex(uint32_t addr) { } } return &hexbuf[0]; -} +} */ + +// TODO: implement simple scanf functions int singlehextoreg(char hex) { int conv = 0; diff --git a/lib/stdio.c b/lib/stdio.c index 9ef20ee..6b0f2a2 100644 --- a/lib/stdio.c +++ b/lib/stdio.c @@ -1,3 +1,17 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/23 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * The 'classic' putc and getchar functions. Should not be used directly + * use the tinyprintf library instead + * + * Can be extended for multiple interfaces (serial, tft or oled screens) + * + */ + #include #include #include diff --git a/lib/string.c b/lib/string.c index 2edc71a..933234c 100644 --- a/lib/string.c +++ b/lib/string.c @@ -1,10 +1,20 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/20 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Re-implementation of POSIX String functions + * + */ + #include #include #include #include -// TODO: add more void *memcpy(void *dest, void *src, size_t count) { const char *sp = (const char *)src; diff --git a/link.ld b/link.ld index 1f6b5f6..d8361dc 100644 --- a/link.ld +++ b/link.ld @@ -1,4 +1,26 @@ -/* */ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/7/20 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Linker file for Cortex-M3 STM32 based boards + * Boards have similar FLASH and SRAM ORIGINs + * LENGTHs differs of course. + * + * _start flag is the first procedure to be + * executed (linked to beginning of FLASH at + * 0x08000000). The procedure should do some + * basic things, such as set up the stack and + * reset and hard fault handler (see start.asm) + * * + * _endofbss flag is used to calculate the end + * of .bss and the start of (a possible) kernel + * heap + * + * */ + MEMORY { FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K diff --git a/main.c b/main.c index da28711..221d7d6 100644 --- a/main.c +++ b/main.c @@ -5,7 +5,7 @@ * Initial version * * $DESCRIPTION$ - * Main intialize basic components of the boards + * Main initialize basic components of the board * and jumps to a terminal * * */ @@ -24,77 +24,50 @@ #include #include #include -#include +//#include #include -//void sleep() { -// -// __asm__ __volatile__("wfe"); -// -//} - void main() { + + /* Initialize the clock system, */ clock_init(); + + /* Setup the interrupt vector table */ ivt_init(); + + /* Initialze basic input and output over serial */ uart_init(); -// cputs("ROBSYS LOADING...\n"); - //systick_init(); -// tsensor_output(0xFFFF, 0x7FFF); + /* Cortex M* integrated systick, can be replaced + * by the more accurate RTC. + systick_init(); + */ + + /* Set up a very small libc library */ init_printf(NULL, putc); - // SPEED_TEST -/* cputs("START TEST (8MHz) \n"); - int a; - for (int i = 0; i < 20000000; i++) { - a + 2; - } - a = 0; - cputs("END TEST\n"); - - //! - clock_init(); - cputs("START TEST (??MHz) \n"); - for (int i = 0; i < 20000000; i++) { - a + 2; - } - cputs("END TEST\n"); */ + /* Display some basic info at startup */ sysinfo(); - -// tsensor_input(5000); -// run(); - + /* On board LEDs*/ led_init(); -// eeprom_at24c_init(); -// eeprom_test(); - tm1637_init(); + /* Real time clock */ rtc_init(); + /* Eeprom Driver + eeprom_at24c_init(); + eeprom_test(); + */ + + /* LED Segment Driver */ + tm1637_init(); - //uint32_t test = hextoreg("12345678"); - -// cputs(regtohex(test)); - - //extern void stub(); - //stub(); - //__asm__ __volatile__ ("ldc p1, cr1, r0"); - -/* while(1) { - int r; - for (int i = 0; i < 50000; i++) { - r = 0; - } - led_on(); - for (int i = 0; i < 50000; i++) { - r = 0; - } - led_off(); - } */ + /* Start up terminal */ terminal(); + /* Should not be here, endless loop */ for(;;) { } diff --git a/rtc.c b/rtc.c index 1f1136a..f169a85 100644 --- a/rtc.c +++ b/rtc.c @@ -46,18 +46,15 @@ void * rtc_handler() { grid2 = ((cntvalue % 1000) - grid0 - grid1) / 100; grid3 = ((cntvalue % 10000) - grid0 - grid1 - grid2) / 1000; - printf("%d, %d, %d, %d\n", grid0, grid1, grid2, grid3); - + //printf("%d, %d, %d, %d\n", grid0, grid1, grid2, grid3); char current[4] = { dn[grid3], dn[grid2], dn[grid1], dn[grid0] }; - //char current[4] = { dn[1], dn[1], dn[1], dn[1] }; for (int i = 0; i < 4; i++) { set_grid(i, current[i], false); } set_display(true, 0); - } // Simple LED blink diff --git a/start.asm b/start.asm index 180f9a4..f2c16bc 100644 --- a/start.asm +++ b/start.asm @@ -5,8 +5,10 @@ * Initial version * * $DESCRIPTION$ - * - * */ + */ + +/* _start sets up the stack and jumps to the reset vector */ + .equ STACK_TOP, 0x20010000 /* placed at 64kB, top of SRAM */ .text .global _start @@ -34,14 +36,6 @@ nmi: hardfault: b hardfault -.global stub -stub: - ldr R0,=10 - mov R1,#0 - ldc2 11, cr0, [r1, #4] - udiv.w R2, R0, R1 - - .data - .word 'x' + .end diff --git a/sysinfo.c b/sysinfo.c index bd5d1bb..2792f14 100644 --- a/sysinfo.c +++ b/sysinfo.c @@ -2,7 +2,9 @@ * * $LOG$ * 2019/7/20 - ROBIN KRENS - * Initial version + * Initial version + * Display some system information, calculate + * the amount of SRAM available * * */ @@ -50,18 +52,12 @@ void sysinfo() { uint32_t current_stack = get_msp(); uint32_t stack_usage = (SRAM_OFFSET + SRAM_SIZE) - current_stack; - uint32_t data_bss = &_endofbss - SRAM_OFFSET; + uint32_t data_bss = (uint32_t) &_endofbss - SRAM_OFFSET; uint32_t mem_free = SRAM_SIZE - stack_usage - data_bss; printf("# TOTAL MEMORY: %#x\n", SRAM_SIZE); -// cputs(regtohex(SRAM_SIZE)); -// cputchar('\n'); printf("# FREE MEMORY: %#x\n", mem_free); -// cputs(regtohex(mem_free)); -// cputchar('\n'); printf("# STACK USAGE: %#x\n", stack_usage); -// cputs(regtohex(stack_usage)); -// cputchar('\n'); } diff --git a/systick.c b/systick.c index 05f515f..589e286 100644 --- a/systick.c +++ b/systick.c @@ -1,3 +1,16 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/8/14 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * SysTick of Cortex M* MCUs. Have a look at the more complex RTC + * in case more accurate timing is needed. + * + * + * */ + #include #include #include @@ -6,7 +19,7 @@ #include #include -#include +#include struct interrupt_frame { @@ -23,15 +36,14 @@ struct interrupt_frame { //__attribute__ ((interrupt)) void * systick_handler(/* struct interrupt_frame * frame */) { -// cputs("TICKING\n"); -// for(;;); + printf("Ticking...\n"); } void systick_init() { /* Every time the counter counts down to zero - * a systick exception is asserted. Systick has + * a systick exception is invoked. Systick has * exception number 15. in the vector table */ ivt_set_gate(15, systick_handler, 0); diff --git a/term.c b/term.c index 7ce25ce..d1a6431 100644 --- a/term.c +++ b/term.c @@ -1,3 +1,14 @@ +/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL + * + * $LOG$ + * 2019/8/14 - ROBIN KRENS + * Initial version + * + * $DESCRIPTION$ + * Small terminal with some built-in debug commands + * + * */ + #include #include #include @@ -18,15 +29,14 @@ #define WHITESPACE "\t\r\n " #define BUILTINCMDS 4 -int help(int, char**); - /* * Built in commands * info -- shows basic info of system * uptime -- uptime; read from the RTC register * reset -- software reset TODO - * show [ADDRESS-ADDRESS] -- shows SRAM range - * switchmode -- switch to unprivileged mode + * showmem xxxxxxxx -- shows address value + * led -- led on/off + * switchmode -- switch to unprivileged mode TODO * */ static char buf[BUFSIZE]; @@ -37,7 +47,7 @@ struct cmd { int (*function)(int argc, char ** argsv); }; -struct cmd builtincmds[4]; +struct cmd builtincmds[BUILTINCMDS]; int info(int argc, char ** argsv) { sysinfo(); @@ -45,38 +55,30 @@ int info(int argc, char ** argsv) { } int uptime(int arg, char ** argsv) { - //cputs("CURRENT UPTIME: "); - //cputs(regtohex(*RTC_CNTL)); - //cputchar('\n'); - printf("CURRENT UPTIME: %p\n", *RTC_CNTL); + printf("CURRENT UPTIME: %d seconds \n", *RTC_CNTL); } int led(int argc, char ** argsv) { - if (argsv[1] != NULL) { if (strcmp(argsv[1], "on")) { - cputs("LED ON\n"); + printf("LED ON\n"); led_on(); } else if (strcmp(argsv[1], "off")) { - cputs("LED OFF\n"); + printf("LED OFF\n"); led_off(); } } return 0; } -int show(int argc, char ** argsv) { +int showmem(int argc, char ** argsv) { if ((argsv[1] != NULL) && (strlen(argsv[1]) == 8)) { uint32_t * check = (uint32_t *) hextoreg(argsv[1]); - cputs("REGISTER 0x"); - cputs(argsv[1]); - cputs(" VALUE: "); - cputs(regtohex(*check)); - cputchar('\n'); + printf("LOCATION 0x%s, VALUE: %#x\n", argsv[1], *check); return 1; } @@ -102,7 +104,7 @@ int exec_cmd(char * buf) { // save and scan past next arg if (argc == MAXARGS-1) { - cputs("Too many arguments"); + printf("Too many arguments\n"); return 0; } argv[argc++] = buf; @@ -118,7 +120,7 @@ int exec_cmd(char * buf) { if (strcmp(argv[0], builtincmds[i].name)) return builtincmds[i].function(argc, argv); } - cputs("Unknown command"); + printf("Unknown command\n"); return 0; } @@ -131,15 +133,14 @@ void terminal() { builtincmds[1].name = "led"; builtincmds[1].function = led; - builtincmds[2].name = "show"; - builtincmds[2].function = show; + builtincmds[2].name = "showmem"; + builtincmds[2].function = showmem; builtincmds[3].name = "uptime"; builtincmds[3].function = uptime; char *buf; - //cputs("WELCOME TO ROBSYS!\n"); while (1) { buf = readline("root# "); -- 2.7.4