aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2015-12-18 21:19:35 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2015-12-18 21:19:35 +0100
commit022daa0619f7d571db6e81c09ab5c0f0af389c18 (patch)
treea2b1c7f6d36f1f3ddfd109bc28ddbf71a9f85196
parent7bc66b8b61d818f0beaaf9a944abd6e086e0fae6 (diff)
downloadstm32f103-playground-022daa0619f7d571db6e81c09ab5c0f0af389c18.tar.gz
stm32f103-playground-022daa0619f7d571db6e81c09ab5c0f0af389c18.tar.bz2
stm32f103-playground-022daa0619f7d571db6e81c09ab5c0f0af389c18.tar.xz
stm32f103-playground-022daa0619f7d571db6e81c09ab5c0f0af389c18.zip
o Functional initialization of .data and .bss.
o Adding a minimal printf library
-rw-r--r--CMakeLists.txt2
-rw-r--r--cmake/stm32.ld23
-rw-r--r--gdb-start8
-rw-r--r--test1.cpp118
-rwxr-xr-xtmp/printf/printf.c245
-rwxr-xr-xtmp/printf/printf.h124
6 files changed, 431 insertions, 89 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0834db0..8a8ef4d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,8 @@ project(teensy-playground C CXX ASM)
#include(cmake/Teensy.cmake)
add_executable(test1.elf test1.cpp init.s include/stm32f10x_conf.h
+ # http://www.sparetimelabs.com/tinyprintf/tinyprintf.php
+ tmp/printf/printf.h tmp/printf/printf.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/CoreSupport/core_cm3.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c
tmp/STM32F10x_StdPeriph_Lib_V3.5.0/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_rcc.c
diff --git a/cmake/stm32.ld b/cmake/stm32.ld
index ea06a98..d15b4c2 100644
--- a/cmake/stm32.ld
+++ b/cmake/stm32.ld
@@ -13,13 +13,8 @@ MEMORY
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
-_data_start = ORIGIN(RAM);
-_data_end = ORIGIN(RAM) + LENGTH(RAM);
_estack = ORIGIN(RAM) + LENGTH(RAM);
-_Min_Heap_Size = 0; /* required amount of heap */
-_Min_Stack_Size = 0x100; /* required amount of stack */
-
SECTIONS
{
.text :
@@ -28,10 +23,26 @@ SECTIONS
init.s:(.text)
*(.text)
KEEP(*(.text.*))
+ *(.rodata*)
} >FLASH
- .data :
+ . = ORIGIN(RAM);
+
+ .data ALIGN(4) :
{
*(.data*)
+ } >RAM AT >FLASH
+
+ .bss ALIGN(4) (NOLOAD) :
+ {
+ *(.bss)
+ *(.bss.*)
} >RAM
+
+ _copy_data_store = ADDR(.data);
+ _copy_data_store_end = _copy_data_store + SIZEOF(.data);
+ _copy_data_load = LOADADDR(.data);
+
+ _bss_start = ADDR(.bss);
+ _bss_end = _bss_start + SIZEOF(.bss);
}
diff --git a/gdb-start b/gdb-start
index 3973a49..c7da6c3 100644
--- a/gdb-start
+++ b/gdb-start
@@ -4,18 +4,12 @@ define flash_test1
monitor arm semihosting enable
monitor reset halt
-monitor stm32f1x.cpu mwb 0x20000000 0x5a 20480
-
set confirm off
file build/test1.elf
load build/test1.elf
set confirm on
-#monitor flash probe 0
-#monitor stm32f1x mass_erase 0
-#monitor flash write_bank 0 test1.elf.bin 0
-# delete breakpoint
-# hbreak main
+monitor stm32f1x.cpu mwb 0x20000000 0x5a 20480
end
monitor reset halt
diff --git a/test1.cpp b/test1.cpp
index 114af80..e9ede35 100644
--- a/test1.cpp
+++ b/test1.cpp
@@ -4,6 +4,8 @@
#include <stm32f10x_rcc.h>
#include <stm32f10x_gpio.h>
+#include "tmp/printf/printf.h"
+
#include "stm32f10x_conf.h"
extern "C"
@@ -55,7 +57,38 @@ void send_command(int command, void *message) {
);
}
+//static
+const char *msg_a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";
+
+//uint32_t message3[] = {
+// 2,
+// (uint32_t) "YOYO\r\n",
+// 6
+//};
+
+extern uint32_t _copy_data_load, _copy_data_store, _copy_data_store_end;
+extern uint32_t _bss_start, _bss_end;
+
+/*
+ * When we get there the stack pointer is set
+ */
int main() {
+ // 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;
+ }
+
uint32_t message[] = {
2,
(uint32_t) "Hello World! again\r\n",
@@ -63,6 +96,15 @@ int main() {
};
send_command(0x05, &message);
+ uint32_t message2[] = {
+ 2,
+ (uint32_t) msg_a,
+ 28
+ };
+ send_command(0x05, &message2);
+
+ send_command(0x05, &message);
+
SystemInit();
SystemCoreClockUpdate();
// RCC->APB2ENR = RCC_APB2ENR_IOPCEN;
@@ -98,81 +140,5 @@ int main() {
}
}
- if (0) {
- GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);
- GPIOA->CRL |= GPIO_CRL_MODE0;
-
- GPIOB->CRL &= ~(GPIO_CRL_MODE5 | GPIO_CRL_CNF5);
- GPIOB->CRL |= GPIO_CRL_MODE5;
-
- while (1) {
- GPIOB->BSRR = -1;
- GPIOB->BSRR = -1;
-
- send_command(0x05, &message);
-
- GPIOA->BRR = -1;
- GPIOA->BRR = -1;
-
- send_command(0x05, &message);
- }
- }
-
- if (0) {
- do {
- volatile uint32_t *port_b = (uint32_t *) (0x40010c00);
- volatile uint32_t *port_b_crl = (uint32_t *) (port_b + 0x00);
- volatile uint32_t *port_b_crh = (uint32_t *) (port_b + 0x04);
-// volatile uint32_t *port_b_idr = (uint32_t *) (port_b + 0x08);
-// volatile uint32_t *port_b_odr = (uint32_t *) (port_b + 0x0c);
- volatile uint32_t *port_b_bsrr = (uint32_t *) (port_b + 0x10);
-// volatile uint32_t *port_b_brr = (uint32_t *) (port_b + 0x14);
-
- // mode=output, max speed 10MHz
- *port_b_crl = 0x11111111;
- *port_b_crh = 0x11111111;
-
- *port_b_bsrr = 0xffff0000;
-
- *port_b_bsrr = 0x0000ffff;
- } while (1);
- }
-
return 0;
}
-
-extern "C" void high() {
-
- do {
- volatile uint32_t *port_b = (uint32_t *) (0x40010c00);
- volatile uint32_t *port_b_crl = (uint32_t *) (port_b + 0x00);
- volatile uint32_t *port_b_crh = (uint32_t *) (port_b + 0x04);
- volatile uint32_t *port_b_bsrr = (uint32_t *) (port_b + 0x10);
-
- *port_b_crl = 0x11111111;
- *port_b_crh = 0x11111111;
- *port_b_bsrr = 0xffff0000;
-
- *port_b_bsrr = 0x0000ffff;
- } while (1);
-}
-
-extern "C" void low() {
-
- do {
- volatile uint32_t *port_b = (uint32_t *) (0x40010c00);
- volatile uint32_t *port_b_crl = (uint32_t *) (port_b + 0x00);
- volatile uint32_t *port_b_crh = (uint32_t *) (port_b + 0x04);
- volatile uint32_t *port_b_bsrr = (uint32_t *) (port_b + 0x10);
-
- *port_b_crl = 0x11111111;
- *port_b_crh = 0x11111111;
- *port_b_bsrr = 0xffff0000;
-
- *port_b_bsrr = 0xffff0000;
- } while (1);
-}
-
-//extern "C" void _Reset_Handler() {
-//
-//}
diff --git a/tmp/printf/printf.c b/tmp/printf/printf.c
new file mode 100755
index 0000000..3950a5f
--- /dev/null
+++ b/tmp/printf/printf.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
+ * contributors may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#include "printf.h"
+
+typedef void (*putcf) (void*,char);
+static putcf stdout_putf;
+static void* stdout_putp;
+
+
+#ifdef PRINTF_LONG_SUPPORT
+
+static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf)
+ {
+ int n=0;
+ unsigned int d=1;
+ while (num/d >= base)
+ d*=base;
+ while (d!=0) {
+ int dgt = num / d;
+ num%=d;
+ d/=base;
+ if (n || dgt>0|| d==0) {
+ *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
+ ++n;
+ }
+ }
+ *bf=0;
+ }
+
+static void li2a (long num, char * bf)
+ {
+ if (num<0) {
+ num=-num;
+ *bf++ = '-';
+ }
+ uli2a(num,10,0,bf);
+ }
+
+#endif
+
+static void ui2a(unsigned int num, unsigned int base, int uc,char * bf)
+ {
+ int n=0;
+ unsigned int d=1;
+ while (num/d >= base)
+ d*=base;
+ while (d!=0) {
+ int dgt = num / d;
+ num%= d;
+ d/=base;
+ if (n || dgt>0 || d==0) {
+ *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
+ ++n;
+ }
+ }
+ *bf=0;
+ }
+
+static void i2a (int num, char * bf)
+ {
+ if (num<0) {
+ num=-num;
+ *bf++ = '-';
+ }
+ ui2a(num,10,0,bf);
+ }
+
+static int a2d(char ch)
+ {
+ if (ch>='0' && ch<='9')
+ return ch-'0';
+ else if (ch>='a' && ch<='f')
+ return ch-'a'+10;
+ else if (ch>='A' && ch<='F')
+ return ch-'A'+10;
+ else return -1;
+ }
+
+static char a2i(char ch, char** src,int base,int* nump)
+ {
+ char* p= *src;
+ int num=0;
+ int digit;
+ while ((digit=a2d(ch))>=0) {
+ if (digit>base) break;
+ num=num*base+digit;
+ ch=*p++;
+ }
+ *src=p;
+ *nump=num;
+ return ch;
+ }
+
+static void putchw(void* putp,putcf putf,int n, char z, char* bf)
+ {
+ char fc=z? '0' : ' ';
+ char ch;
+ char* p=bf;
+ while (*p++ && n > 0)
+ n--;
+ while (n-- > 0)
+ putf(putp,fc);
+ while ((ch= *bf++))
+ putf(putp,ch);
+ }
+
+void tfp_format(void* putp,putcf putf,char *fmt, va_list va)
+ {
+ char bf[12];
+
+ char ch;
+
+
+ while ((ch=*(fmt++))) {
+ if (ch!='%')
+ putf(putp,ch);
+ else {
+ char lz=0;
+#ifdef PRINTF_LONG_SUPPORT
+ char lng=0;
+#endif
+ int w=0;
+ ch=*(fmt++);
+ if (ch=='0') {
+ ch=*(fmt++);
+ lz=1;
+ }
+ if (ch>='0' && ch<='9') {
+ ch=a2i(ch,&fmt,10,&w);
+ }
+#ifdef PRINTF_LONG_SUPPORT
+ if (ch=='l') {
+ ch=*(fmt++);
+ lng=1;
+ }
+#endif
+ switch (ch) {
+ case 0:
+ goto abort;
+ case 'u' : {
+#ifdef PRINTF_LONG_SUPPORT
+ if (lng)
+ uli2a(va_arg(va, unsigned long int),10,0,bf);
+ else
+#endif
+ ui2a(va_arg(va, unsigned int),10,0,bf);
+ putchw(putp,putf,w,lz,bf);
+ break;
+ }
+ case 'd' : {
+#ifdef PRINTF_LONG_SUPPORT
+ if (lng)
+ li2a(va_arg(va, unsigned long int),bf);
+ else
+#endif
+ i2a(va_arg(va, int),bf);
+ putchw(putp,putf,w,lz,bf);
+ break;
+ }
+ case 'x': case 'X' :
+#ifdef PRINTF_LONG_SUPPORT
+ if (lng)
+ uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf);
+ else
+#endif
+ ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf);
+ putchw(putp,putf,w,lz,bf);
+ break;
+ case 'c' :
+ putf(putp,(char)(va_arg(va, int)));
+ break;
+ case 's' :
+ putchw(putp,putf,w,0,va_arg(va, char*));
+ break;
+ case '%' :
+ putf(putp,ch);
+ default:
+ break;
+ }
+ }
+ }
+ abort:;
+ }
+
+
+void init_printf(void* putp,void (*putf) (void*,char))
+ {
+ stdout_putf=putf;
+ stdout_putp=putp;
+ }
+
+void tfp_printf(char *fmt, ...)
+ {
+ va_list va;
+ va_start(va,fmt);
+ tfp_format(stdout_putp,stdout_putf,fmt,va);
+ va_end(va);
+ }
+
+static void putcp(void* p,char c)
+ {
+ *(*((char**)p))++ = c;
+ }
+
+
+
+void tfp_sprintf(char* s,char *fmt, ...)
+ {
+ va_list va;
+ va_start(va,fmt);
+ tfp_format(&s,putcp,fmt,va);
+ putcp(&s,0);
+ va_end(va);
+ }
+
+
diff --git a/tmp/printf/printf.h b/tmp/printf/printf.h
new file mode 100755
index 0000000..9723b0f
--- /dev/null
+++ b/tmp/printf/printf.h
@@ -0,0 +1,124 @@
+/*
+File: printf.h
+
+Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
+contributors may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+
+This library is realy just two files: 'printf.h' and 'printf.c'.
+
+They provide a simple and small (+200 loc) printf functionality to
+be used in embedded systems.
+
+I've found them so usefull in debugging that I do not bother with a
+debugger at all.
+
+They are distributed in source form, so to use them, just compile them
+into your project.
+
+Two printf variants are provided: printf and sprintf.
+
+The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'.
+
+Zero padding and field width are also supported.
+
+If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the
+long specifier is also
+supported. Note that this will pull in some long math routines (pun intended!)
+and thus make your executable noticably longer.
+
+The memory foot print of course depends on the target cpu, compiler and
+compiler options, but a rough guestimate (based on a H8S target) is about
+1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space.
+Not too bad. Your milage may vary. By hacking the source code you can
+get rid of some hunred bytes, I'm sure, but personally I feel the balance of
+functionality and flexibility versus code size is close to optimal for
+many embedded systems.
+
+To use the printf you need to supply your own character output function,
+something like :
+
+void putc ( void* p, char c)
+ {
+ while (!SERIAL_PORT_EMPTY) ;
+ SERIAL_PORT_TX_REGISTER = c;
+ }
+
+Before you can call printf you need to initialize it to use your
+character output function with something like:
+
+init_printf(NULL,putc);
+
+Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
+the NULL (or any pointer) you pass into the 'init_printf' will eventually be
+passed to your 'putc' routine. This allows you to pass some storage space (or
+anything realy) to the character output function, if necessary.
+This is not often needed but it was implemented like that because it made
+implementing the sprintf function so neat (look at the source code).
+
+The code is re-entrant, except for the 'init_printf' function, so it
+is safe to call it from interupts too, although this may result in mixed output.
+If you rely on re-entrancy, take care that your 'putc' function is re-entrant!
+
+The printf and sprintf functions are actually macros that translate to
+'tfp_printf' and 'tfp_sprintf'. This makes it possible
+to use them along with 'stdio.h' printf's in a single source file.
+You just need to undef the names before you include the 'stdio.h'.
+Note that these are not function like macros, so if you have variables
+or struct members with these names, things will explode in your face.
+Without variadic macros this is the best we can do to wrap these
+fucnction. If it is a problem just give up the macros and use the
+functions directly or rename them.
+
+For further details see source code.
+
+regs Kusti, 23.10.2004
+*/
+
+
+#ifndef __TFP_PRINTF__
+#define __TFP_PRINTF__
+
+#include <stdarg.h>
+
+void init_printf(void* putp,void (*putf) (void*,char));
+
+void tfp_printf(char *fmt, ...);
+void tfp_sprintf(char* s,char *fmt, ...);
+
+void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va);
+
+#define printf tfp_printf
+#define sprintf tfp_sprintf
+
+#endif
+
+
+