From: Robin Krens Date: Mon, 15 Jul 2019 16:58:54 +0000 (+0800) Subject: basic memory management and uart wait fix X-Git-Url: https://robinkrens.nl/gitweb/?a=commitdiff_plain;h=3f9ee85c250250580f0ceb38525ddb99ebc6d36e;p=cortex-from-scratch basic memory management and uart wait fix --- diff --git a/Makefile b/Makefile index 9f7f517..9eba3b4 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ AR=$(TOOLROOT)/arm-none-eabi-ar AS=arm-none-eabi-as MKIMG=arm-none-eabi-objcopy -LDFLAGS+= -mthumb -mcpu=cortex-m3 +LDFLAGS+= -mthumb -mcpu=cortex-m0 CFLAGS+= -mcpu=cortex-m3 -mthumb -g as: diff --git a/include/mmap.h b/include/mmap.h index 1aba65b..6fa4adc 100644 --- a/include/mmap.h +++ b/include/mmap.h @@ -7,8 +7,8 @@ * */ -#define BSS_BASE ((volatile uint32_t)(0x20000000)); -#define MEM_SIZE 512000; +#define BSS_BASE ((volatile uint32_t *)(0x20000800)) //TODO: .data flexible siz +#define TOTAL_MEM_SIZE 64000; /* SYSTEM INFO AND DEBUG */ #define MCU_ID ((volatile uint32_t*)( 0xE0042000)) diff --git a/include/stm32.h b/include/stm32.h index 37f039f..4f52257 100644 --- a/include/stm32.h +++ b/include/stm32.h @@ -28,4 +28,10 @@ extern void sysinfo(); /* LIB.C */ extern void addrtohex(const uint32_t); +/* MM.C */ +extern void mm_init(); +extern void * mm_alloc(size_t); +extern void free(void *); +extern void test_memory(uint32_t *); + #endif diff --git a/lib.c b/lib.c index 62c56e8..69bb12d 100644 --- a/lib.c +++ b/lib.c @@ -9,13 +9,12 @@ char hexbuf[8] = {'0', '0','0', '0','0', '0','0', '0'}; -void addrtohex(const uint32_t addr) { +void addrtohex(uint32_t addr) { char tmpbuf[6] = {'A', 'B', 'C', 'D', 'E', 'F'}; memset(&hexbuf, 0, sizeof(uint32_t) * 8); - uint32_t tmp = addr; for (int i = 0; i < 8 ; i++) { - tmp = addr; + uint32_t tmp = addr; tmp = tmp >> (i * 4); tmp = tmp & 0xF; if ((tmp >= 0) && tmp < 10) { @@ -27,20 +26,10 @@ void addrtohex(const uint32_t addr) { } uart_puts("ADDRESS: 0x"); - for (int i = 7; i >= 0; i--) { + for (int i = 7; i >= 0; i--) { uart_putc(hexbuf[i]); - } + } + //uart_puts(hexbuf); uart_putc('\n'); } - -void *malloc(size_t size) { - - - -} - -void free(void * ptr) { - - -} diff --git a/link.ld b/link.ld index d1a01dd..8301b2c 100644 --- a/link.ld +++ b/link.ld @@ -1,9 +1,9 @@ -/* - * MEMORY MAP +/* */ +MEMORY { FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 512K SRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K -} */ +} ENTRY(_start) @@ -20,9 +20,9 @@ SECTIONS .data : { *(.data) - } + } .bss : ALIGN(256) { *(.bss) - } + } } diff --git a/main.c b/main.c index 5b488cf..84496d5 100644 --- a/main.c +++ b/main.c @@ -49,8 +49,19 @@ void main() systick_init(); uart_puts("LOADING SYSTEM 0.1 ...\n"); sysinfo(); - addrtohex((volatile uint32_t) 0x12345678 ); - addrtohex((volatile uint32_t) *SCB_VTOR ); + mm_init(); + + int * p2 = mm_alloc(200); + *p2 = 0x12345678; + + test_memory(p2); + + addrtohex(p2); + addrtohex(*p2); + + + //addrtohex((volatile uint32_t) 0x12345678 ); + //addrtohex((volatile uint32_t) SCB_VTOR ); // asm("cpsie i"); // enable irq , cpsied f (disable faukts( diff --git a/mm.c b/mm.c index ba0cc2c..4f56459 100644 --- a/mm.c +++ b/mm.c @@ -4,18 +4,98 @@ #include #include -uint32_t free_base; +/* TOTAL SRAM MEMORY: 64kB + * 64 chunks of 1kB + * 128 chunks of 512 bytes + * SIMPLE BITMAP IMPLEMENTATION + * */ + +#define CHUNKS 128 +#define FREE 0x00 +#define ALLOC 0x01 + +#define BASE 0x20000400 + +#define SET_SIZE(s) (s << 8) +#define SET_FLAGS(f) (f << 24) +#define IS_ALLOC(c) ((c >> 24) & 0x0F ) +#define PADDR(i) (0x20000400 + (i * 0x200)) +#define I_OFFSET(p) ((p - 0x20000400)) + +uint32_t chunk[CHUNKS]; + +/* + * | FLAGS | SIZE | RESERVED | + * | 0x00 | 0x0000 | 0x00 | + * + * */ void mm_init() { - free_base = MEM_SIZE; + // interrupt vector + chunk[0] = SET_SIZE(96) | SET_FLAGS(ALLOC); + + // test + /* uart_puts("ALLOC:\n"); + int * p = mm_alloc(100); + *p = 0x12345678; + + addrtohex(p); + addrtohex(*p); + + uart_puts("FREE:\n"); + + int * p2 = mm_alloc(100); + *p2 = 0xFFFFAAAA; + addrtohex(p2); + addrtohex(*p2); + free(p); + free(p2); */ } -size_t mm_free() { + void test_memory(uint32_t * ptr) { + + *ptr = 0xEEEEEEEE; + for (int i = 0; i < 100; i++) { + ptr++; + *ptr = 0xEEEEEEEE; + } + +} + + +void * mm_alloc(size_t size) { // in bytes + + if (size > 512) { + uart_puts("SYSERROR: WE CAN'T ALLOCATE THAT MUCH!\n"); + return NULL; + } + + /* check which chunk is free */ + for (int i = 1; i < CHUNKS; i++) { + if (!IS_ALLOC(chunk[i])) { + chunk[i] = SET_SIZE(size) | SET_FLAGS(ALLOC); + return (void *) PADDR(i); + } + } + + uart_puts("SYSERROR: OUT OF MEMORY\n"); + return NULL; +} + +void free(void *ptr) { + + uint32_t index = (uint32_t) I_OFFSET(ptr) / 0x200; - return MEM_SIZE; + uint32_t tmp = chunk[index]; + if (!IS_ALLOC(tmp)) + uart_puts("SYSERROR: ALREADY FREED!\n"); + else if(index < CHUNKS) { + chunk[index] = SET_FLAGS(FREE) | SET_SIZE(0); + } + } diff --git a/start.asm b/start.asm index 294a718..d8c7244 100644 --- a/start.asm +++ b/start.asm @@ -1,4 +1,4 @@ - .equ STACK_TOP, 0x20000800 + .equ STACK_TOP, 0x20008000 /* placed at 32kB, TODO: could place at top of SRAM? */ .text .global _start .global reset, nmi, hardfault @@ -34,7 +34,7 @@ stub: mov R1,#0 udiv.w R2, R0, R1 */ - .data - .word 'x' +/* .data + .word 'x' */ .end diff --git a/uart.c b/uart.c index 93b2c91..a3905c4 100644 --- a/uart.c +++ b/uart.c @@ -43,6 +43,9 @@ void uart_init() { */ } +void wait() { + for (int i = 0; i < 100; i++); +} extern void uart_putc(unsigned char ch) { @@ -50,15 +53,16 @@ extern void uart_putc(unsigned char ch) { while (*USART1_SR & 0x0C) { } // transmit data register empty and complete *USART1_DR = 0x0D; // return line } - - while ((*USART1_SR & 0xFF) == 0x0C) {} // busy bit + + + while (*USART1_SR & 0x0C) {} *USART1_DR = ch; -} -void wait() { - for (int i = 0; i < 100; i++); + + wait(); } + extern void uart_puts(unsigned char *str) { @@ -66,7 +70,6 @@ extern void uart_puts(unsigned char *str) for (i = 0; i < strlen(str); i++) { - wait(); uart_putc(str[i]); } }