1
0
mirror of https://github.com/rfivet/stm32bringup.git synced 2025-02-21 05:37:09 -05:00

Upgrade toolchain to 14.2.

Update first two sections of documentation accordingly.
This commit is contained in:
Renaud 2025-01-03 11:32:51 +08:00
parent f199ffa8b0
commit 2ee50ead2a
12 changed files with 144 additions and 117 deletions

View File

@ -1,5 +1,5 @@
# Makefile -- stm32bringup
# Copyright © 2020-2024 Renaud Fivet
# Copyright © 2020-2025 Renaud Fivet
### Build environment selection
@ -15,7 +15,8 @@ ifeq (linux, $(findstring linux, $(MAKE_HOST)))
#REVDIR = arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi
#REVDIR = arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi
#REVDIR = arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi
REVDIR = arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
#REVDIR = arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
REVDIR = arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
DRIVE = d
ifeq (cygwin, $(findstring cygwin, $(MAKE_HOST)))
@ -40,7 +41,8 @@ endif
#REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-12.2.rel1-mingw-w64-i686-arm-none-eabi
#REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-12.2.mpacbti-rel1-mingw-w64-i686-arm-none-eabi
#REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.2.Rel1-mingw-w64-i686-arm-none-eabi
REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi
#REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi
REVDIR = GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi
endif
GCCDIR = $(INSTALLDIR)/$(REVDIR)

View File

@ -27,10 +27,10 @@ IDE or encapsulate those paths and names in <b>Makefile</b> variables.
<pre>
### Build environment selection
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
BINPFX = $(GCCDIR)/bin/arm-none-eabi-
CC = $(BINPFX)gcc
BINPFX = $(GCCDIR)/bin/arm-none-eabi-
CC = $(BINPFX)gcc
### Build rules
@ -49,11 +49,11 @@ share the same name prefix <b>arm-none-eabi-</b>. So I have created a
</ul>
<pre>
$ make
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-gcc --version
arm-none-eabi-gcc.exe (Arm GNU Toolchain 13.3.Rel1 (Build arm-13.24)) 13.3.1 202
40614
Copyright (C) 2023 Free Software Foundation, Inc.
arm-none-eabi-gcc.exe (Arm GNU Toolchain 14.2.Rel1 (Build arm-14.52)) 14.2.1 202
41119
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
</pre>
@ -65,20 +65,20 @@ means that the <b>Makefile</b> on Linux will be the same as the Windows one
except for the value of the <b>GCCDIR</b> variable.
<pre>
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
</pre>
By selecting the path based on the development environment, there is no need
to make changes while switching between OS. <b>Gmake</b> has the built-in
to make changes while switching between OS. <b><i>gmake</i></b> has the built-in
variable <b>MAKE_HOST</b> that can be tested for this.
<pre>
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = $(GCCDIR)/bin/arm-none-eabi-
@ -94,9 +94,9 @@ version:
</pre>
I use the path prefix <b>$(HOME)/Packages</b> instead of <b>~/Packages</b> when
defining <b>GCCDIR</b> as some sub-processes called by <i>gmake</i> may have
issues with <b>~</b> expansion (in this case <i>ld</i>). This way <i>gmake</i>
will handle the expansion before calling the sub-processes.
defining <b>GCCDIR</b> as some sub-processes called by <b><i>gmake</i></b> may
have issues with <b>~</b> expansion (in this case <i>ld</i>). This way
<b><i>gmake</i></b> will handle the expansion before calling the sub-processes.
<h2>Toolchains chain of events</h2>
In order to generate a file that can be loaded in the micro-controller, I
@ -109,7 +109,8 @@ executable (<b>.elf</b>)
loading or flashing (<b>.bin</b> or <b>.hex</b>).
</ol>
<h3>1. Compile</h3>
<b>Gmake</b> has default rules to built <b>.o</b> files out of <b>.c</b> files.
<b><i>gmake</i></b> has default rules to built <b>.o</b> files out of <b>.c</b>
files.
As I have already defined with <b>CC</b> the command to compile, I can make a
simple test of this step by creating an empty <b>.c</b> file and checking what
happens when I try to compile it.
@ -118,7 +119,7 @@ happens when I try to compile it.
$ touch empty.c
$ make empty.o
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-gcc -c -o empty.o empty.c
</pre>
Compilation is succesful and <b>empty.o</b> file is generated.
@ -139,9 +140,9 @@ use the simplest script: <b>mem.ld</b>.
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = $(GCCDIR)/bin/arm-none-eabi-
@ -152,6 +153,11 @@ LD_SCRIPT = $(GCCDIR)/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld
### Build rules
.PHONY: version
version:
$(CC) --version
%.elf: %.o
$(LD) -T$(LD_SCRIPT) -o $@ $<
@ -159,23 +165,24 @@ LD_SCRIPT = $(GCCDIR)/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld
<pre>
$ make empty.elf
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-ld -T"D:/Program Files (x86)/GNU
Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld -o empty.elf empty.o
</pre>
Link terminates successfully and creates <b>empty.elf</b>.
<h3>3. Convert</h3>
Finally, I use the command <b>objcopy</b> to convert the executable <b>.elf</b>
file into binary or intel hex format suitable to load in the micro-controller.
Finally, I use the command <b><i>objcopy</i></b> to convert the executable
<b>.elf</b> file into binary or intel hex format suitable to load in the
micro-controller.
<pre>
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = $(GCCDIR)/bin/arm-none-eabi-
@ -187,6 +194,11 @@ LD_SCRIPT = $(GCCDIR)/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld
### Build rules
.PHONY: version
version:
$(CC) --version
%.elf: %.o
$(LD) -T$(LD_SCRIPT) -o $@ $<
@ -203,23 +215,23 @@ empty <b>empty.c</b> file, I can successfully build.
<pre>
$ make empty.bin empty.hex
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-gcc -c -o empty.o empty.c
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-ld -T"D:/Program Files (x86)/GNU
Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld -o empty.elf empty.o
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-objcopy -O binary empty.elf empty
.bin
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-m
"D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-m
ingw-w64-i686-arm-none-eabi"/bin/arm-none-eabi-objcopy -O ihex empty.elf empty.h
ex
rm empty.o empty.elf
</pre>
Notice that <b>gmake</b> automatically removes the intermediary <b>.o</b> and
<b>.elf</b> files on completion.
Notice that <b><i>gmake</i></b> automatically removes the intermediary
<b>.o</b> and <b>.elf</b> files on completion.
<p>
The generated <b>empty.bin</b> is empty.
@ -229,7 +241,7 @@ of the long command names. Also I need a way to clean the working directory
back to its initial state.
<ul>
<li>By prefixing <b>BINPFX</b> with <i>@</i>, commands will not be displayed by
<i>gmake</i> when they are executed. Adding an <b>echo</b> of the command
<b><i>gmake</i></b> when they are executed. Adding an <b>echo</b> of the command
target in the rules helps to keep track of the build progression.
<li>A new <b>clean</b> rule will remove all generated files.
</ul>
@ -237,9 +249,9 @@ target in the rules helps to keep track of the build progression.
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = @$(GCCDIR)/bin/arm-none-eabi-
@ -251,7 +263,10 @@ LD_SCRIPT = $(GCCDIR)/share/gcc-arm-none-eabi/samples/ldscripts/mem.ld
### Build rules
.PHONY: clean
.PHONY: clean version
version:
$(CC) --version
clean:
@echo CLEAN
@ -289,6 +304,6 @@ source file (<b>empty.c</b>) to an empty binary file (<b>empty.bin</b>).
<a href="12_bootstrap.html">Next</a>, I will select a micro-controller
from the STM32 family and generate a binary file that it can execute.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -84,7 +84,7 @@ LD_SCRIPT = $(GCCDIR)/share/gcc-arm-none-eabi/samples/ldscripts/nokeep.ld
<pre>
$ make empty.elf
empty.elf
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-13.3.rel1-mi
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi\bin\arm-none-eabi-ld.exe: warning: cannot find entry
symbol Reset_Handler; defaulting to 00000000
rm empty.o
@ -175,7 +175,7 @@ LD_SCRIPT = f030f4.ld
At boot time, the Arm core fetches the initial address of the stack pointer
and the address where to start execution from the first two entries of its
interrupt routine table. I have to modify <b>boot.c</b> to initialize such a
table in accord with the symbols defined in the link script.
table in accordance with the symbols defined in the link script.
<pre>
/* Memory locations defined by linker script */
@ -262,9 +262,9 @@ indented.
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = @$(GCCDIR)/bin/arm-none-eabi-
@ -280,7 +280,10 @@ LD_SCRIPT = f030f4.ld
### Build rules
.PHONY: clean
.PHONY: clean version
version:
$(CC) --version
clean:
@echo CLEAN
@ -302,6 +305,6 @@ clean:
</pre>
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -83,7 +83,7 @@ First I activate the connection in the programmer.
</pre>
Then program and verify the bootstrap code. Either binary, Intel hex or
Motorola S rec format are supported. Our <b>Makefile</b> as rules for binary
Motorola S rec format are supported. Our <b>Makefile</b> has rules for binary
and Intel hex, <b><i>objcopy</i></b> also support Motorola S record as an output
format. Last build produced <b>boot.hex</b>.
@ -158,6 +158,6 @@ application.
<a href="14_ledon.html">Next</a>, I will provide feedback of execution directly
through the board.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -170,9 +170,9 @@ their <code>SRCS</code> line is uncommented.
### Build environment selection
ifeq (linux, $(findstring linux, $(MAKE_HOST)))
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-eabi
GCCDIR = $(HOME)/Packages/arm-gnu-toolchain-14.2.rel1-x86_64-arm-none-eabi
else
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi"
GCCDIR = "D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi"
endif
BINPFX = @$(GCCDIR)/bin/arm-none-eabi-
@ -260,6 +260,6 @@ This step was mainly to achieve a better structure for future evolution.
<a href="19_publish.html">Next</a>, I will make the code available in a
public git repository.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -111,7 +111,7 @@ To build I update the software composition in <b>Makefile</b> by adding a new
<pre>SRCS = startup.c usart1tx.c hello.c</pre>
Calling make, I can see that there is now some variable in <b>BSS</b> section
of the RAM. It is <code>lastchar</code> local to <code>kputc()</code>. Because
of the RAM. It is <code>lastc</code> local to <code>kputc()</code>. Because
of word alignment <code>BSS</code> occupies 4 bytes.
<pre>
@ -155,6 +155,6 @@ support for other stdio functions when needed.
<a href="24_stm32flash.html">Next</a>, I will switch to an open source tool
for flashing over serial connection that works on both Windows and Linux.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -98,15 +98,15 @@ Unfortunately, when I try to build an executable, the link phase fails.
<pre>
$ make
f030f4.elf
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-13.3.rel1-mi
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi\bin\arm-none-eabi-ld.exe: uptime.1.o: in function `kp
utu':
D:\Projects\stm32bringup\docs/uptime.1.c:13:(.text+0x6): undefined reference to
D:\home\Projects\stm32bringup/uptime.1.c:13:(.text+0x6): undefined reference to
`__aeabi_uidivmod'
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi\bin\arm-none-eabi-ld.exe: D:\Projects\stm32bringup\do
cs/uptime.1.c:14:(.text+0x14): undefined reference to `__aeabi_uidiv'
make: *** [Makefile:45: f030f4.elf] Error 1
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi\bin\arm-none-eabi-ld.exe: D:\home\Projects\stm32bring
up/uptime.1.c:14:(.text+0x14): undefined reference to `__aeabi_uidiv'
make: *** [Makefile:49: f030f4.elf] Error 1
</pre>
The compiler has generated code that references two functions
@ -123,12 +123,12 @@ no integer division support. So integer division needs to be implemented
by code as it is not supported by hardware.
I need to pass the linker a reference to GNU Arm Embedded Toolchain
library for Cortex-M0. The library file is <b>libggc.a</b>, the option -l and
library for Cortex-M0. The library file is <b>libgcc.a</b>, the option -l and
-L of the linker tell what the library name is (-lgcc => libgcc.a) and
where to look for it.
<pre>
LIBDIR = $(GCCDIR)/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp
LIBDIR = $(GCCDIR)/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp
LIB_PATHS = -L$(LIBDIR)
LIBS = -lgcc
@ -158,16 +158,16 @@ symbols (<code>__aeabi_uidiv</code> and <code>__aeabi_idiv0</code>).
<pre>
Archive member included to satisfy reference by file (symbol)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_udivsi3.o)
uptime.1.o (__aeabi_uidiv)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_dvmd_tls.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/
arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/1
3.3.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/1
4.2.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
</pre>
<h2>Testing</h2>
@ -205,12 +205,13 @@ the <b>gcc</b> library.
<li> LIBS = -lstm32
</ul>
</ol>
The <code>ar</code> command distributed by the GNU Arm embedded toolchain is
the same <b>GNU ar</b> as the Linux or Cygwin and MSYS2 distributions on
Windows. So I use my native environment implementation for convenience.
This is true for the utility commands (<code>ar</code>, <code>objcopy</code>,
<code>objdump</code> and <code>size</code>) but not for <code>gcc</code> and
<code>ld</code>.
The <b><i>ar</i></b> command distributed by the GNU Arm embedded toolchain is
the same <b>GNU <i>ar</i></b> as found in the Linux distributions or Cygwin and
MSYS2 distributions on Windows. So I use my native environment implementation
for convenience.
This is true for the utility commands (<b><i>ar</i></b>, <b><i>objcopy</i></b>,
<b><i>objdump</i></b> and <b><i>size</i></b>) but not for <b><i>gcc</i></b> and
<b><i>ld</i></b>.
<h2>Checkpoint</h2>
@ -225,6 +226,6 @@ I can use <code>ar</code> to extract locally those modules from the library.
<a href="26_uptime.html">Next</a>, I will write <code>uptime</code> with a
better structure.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -241,12 +241,12 @@ Unfortunately, the build fails at the link phase.
<pre>
$ make
f030f4.elf
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-13.3.rel1-mi
D:\Program Files (x86)\GNU Arm Embedded Toolchain\arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi\bin\arm-none-eabi-ld.exe: uptime.o: in function `main
':
D:\Projects\stm32bringup\docs/uptime.c:41:(.text.startup+0xa4):
undefined reference to `putchar'
make: *** [Makefile:49: f030f4.elf] Error 1
D:\home\Projects\stm32bringup/uptime.c:41:(.text.startup+0xa4): undefined refere
nce to `putchar'
make: *** [Makefile:53: f030f4.elf] Error 1
</pre>
The linker found a reference to <code>putchar()</code> at line 41 of
@ -284,7 +284,7 @@ The build now complete successfully.
$ make
f030f4.elf
text data bss dec hex filename
1797 0 12 1809 711 f030f4.elf
1325 0 12 1337 539 f030f4.elf
f030f4.hex
f030f4.bin
</pre>
@ -297,14 +297,24 @@ code to handle <code>switch()</code> statement are now referenced.
<pre>
Archive member included to satisfy reference by file (symbol)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a(_thumb1_case_sqi.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_thumb1_case_sqi.o)
printf.o (__gnu_thumb1_case_sqi)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_udivsi3.o)
uptime.o (__aeabi_uidiv)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a(_divsi3.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_divsi3.o)
uptime.o (__aeabi_idiv)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a(_dvmd_tls.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_dvmd_tls.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/
arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/1
4.2.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
</pre>
<h2>Test</h2>
@ -326,14 +336,14 @@ make sure days and weeks values are correct. Its also clear that the
test coverage for the printf format interpreter is not sufficient as I have
coded more than is necessary to implement <b>uptime</b>.
<p>
I didnt expect gcc to optimize call to high level C functions,
replacing <code>printf()</code> by <code>putchar()</code>, thus forcing me to
write additional code. So far I am not concerned by execution speed, so this
I didnt expect gcc to optimize calls to high level C functions,
replacing some <code>printf()</code> by <code>putchar()</code>, thus forcing me
to write additional code. So far I am not concerned by execution speed, so this
type of optimization is a bit counter productive.
<p>
<a href="27_library.html">Next</a>, I will make sure that what belongs to the
library category fits in an actual library file.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -36,7 +36,7 @@ int puts( const char *s) {
<h2>Updating Makefile</h2>
I need to tell <b>GNU make</b> how to manage and use the library, which
means updating <b>Makefile</b>.
means updating <b>Makefile</b> with the following informations:
<p>
Whats the name, the content and the rule to maintain the library:
@ -88,7 +88,7 @@ Build terminates successfully producing the same executable as before.
$ make
f030f4.elf from startup.o uplow.2.o uptime.o
text data bss dec hex filename
1797 0 12 1809 711 f030f4.elf
1325 0 12 1337 539 f030f4.elf
f030f4.hex
f030f4.bin
</pre>
@ -100,26 +100,22 @@ newly created library.
<pre>
Archive member included to satisfy reference by file (symbol)
.\libstm32.a(printf.o) uptime.o (printf)
.\libstm32.a(putchar.o) uptime.o (putchar)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
libstm32.a(printf.o) uptime.o (printf)
libstm32.a(putchar.o) uptime.o (putchar)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_thumb1_case_sqi.o)
.\libstm32.a(printf.o) (__gnu_thumb1_case_sqi)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
libstm32.a(printf.o) (__gnu_thumb1_case_sqi)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_udivsi3.o)
uptime.o (__aeabi_uidiv)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
(_divsi3.o)
uptime.o (__aeabi_idiv)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-13.3.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp\libgcc.a
D:/Program Files (x86)/GNU Arm Embedded Toolchain/arm-gnu-toolchain-14.2.rel1-mi
ngw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libgcc.a
(_dvmd_tls.o)
D:/Program Files (x86)/GNU Arm Embedded Toolchain/
arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/1
3.3.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
arm-gnu-toolchain-14.2.rel1-mingw-w64-i686-arm-none-eabi/lib/gcc/arm-none-eabi/1
4.2.1/thumb/v6-m/nofp\libgcc.a(_udivsi3.o) (__aeabi_idiv0)
</pre>
<h2>Building hello</h2>
@ -147,7 +143,7 @@ Checking the map file produced in the link phase, I can see that only
<pre>
Archive member included to satisfy reference by file (symbol)
.\libstm32.a(puts.o) hello.o (puts)
libstm32.a(puts.o) hello.o (puts)
</pre>
<h2>Checkpoint</h2>
@ -159,6 +155,6 @@ implementation of the standard C library output functions is a simple step.
<a href="28_clocks.html">Next</a>, I will continue on the topic of asynchronous serial
transmission and look into baud rate and clock configuration.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -310,7 +310,7 @@ Build complete successfully, this is for PLL HSE board configuration.
$ make
f030f4.elf from startup.o clocks.o uptime.o
text data bss dec hex filename
1901 0 12 1913 779 f030f4.elf
1441 0 12 1453 5ad f030f4.elf
f030f4.hex
f030f4.bin
</pre>
@ -328,6 +328,6 @@ me some flexibility and ease of setup.
<a href="29_interrupt.html">Next</a>, I will implement interrupt driven
transmission.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -246,18 +246,18 @@ Build completes successfully
$ make
f030f4.elf from startup.txeie.o txeie.o uptime.o
text data bss dec hex filename
2097 0 20 2117 845 f030f4.elf
1641 0 20 1661 67d f030f4.elf
f030f4.hex
f030f4.bin
</pre>
Checking the map and lst files I can verify that
<ul>
<li> This code has grown by 128 bytes due to the 32 extra interrupt handlers.
<li> 128 bytes of the code growth is due to the 32 extra interrupt handlers.
<li> Previous implementation of <code>kputc()</code> was using 4 bytes of bss
to hold lastchar (1 byte). The new version uses 12 bytes to hold the round
robin buffer (8 bytes), its in and out indexes (2 bytes) and lastchar (1 byte).
to hold lastc (1 byte). The new version uses 12 bytes to hold the round robin
buffer (8 bytes), its in and out indexes (2 bytes) and lastc (1 byte).
<li> The compiler optimizes the modulo instruction in <code>% size</code> to
bit masking <code>& (size 1)</code> as the size 8 is a power of 2.
@ -274,6 +274,6 @@ second, there is plenty of idle time.
<a href="index.html#part3">Next</a>, I will use an external sensor to do some
measurement.
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>

View File

@ -12,7 +12,7 @@
Getting started with a micro-controller usually means picking up a board,
an IDE, some RTOS or a set of libraries. Depending of your level of experience,
your budget and the solutions you select, the learning curve may be a steep
one and what you will learn can be very limited if you end up cornered in a
one and what you will learn could be very limited if you end up cornered in a
sandbox with no understanding of whats going on under the hood.
<p>
Commercial solutions and mature open source projects are a must if you want to
@ -64,7 +64,7 @@ for further evolution.
Its time to move to a more talkative interface so that the board not
only winks but also speaks. Again I will go through several steps to get
to a working asynchronous serial communication.
to a working interrupt driven asynchronous serial communication.
<ul>
<li> <a href="21_uart.html">Validate</a> the serial connection by wiring a
board with an USB to UART adapter and using a Serial Flash loader application
@ -88,7 +88,7 @@ long the system has been running.
</ul><ul>
<li> <a href="28_clocks.html">Configure</a> baud rate and clocks.
</ul><ul>
<li> Handle the transmission with <a href="29_interrupt.html">interrupt</a>.
<li> Handle the transmission with <a href="29_interrupt.html">interrupts</a>.
</ul>
<h2><a id="part3">Part III: Sensors! So hot! So wet!</a></h2>
@ -123,6 +123,6 @@ during startup.
<li> <a href="AA_factory.html">Factory-programmed</a> values.
</ul>
<hr>© 2020-2024 Renaud Fivet
<hr>© 2020-2025 Renaud Fivet
</body>
</html>