Skip to content

Commit 589eb00

Browse files
committed
Initial version of samples added
1 parent b64b54f commit 589eb00

File tree

15 files changed

+703
-41
lines changed

15 files changed

+703
-41
lines changed

README.md

+1-41
Original file line numberDiff line numberDiff line change
@@ -104,49 +104,9 @@ PATH=${INSTALL_ROOT_DIR}/LLVMEmbeddedToolchainForArm-$VERSION/bin:$PATH
104104
clang --config armv6m-none-eabi_nosys -T device.ld -o example example.c
105105
```
106106

107-
108107
### Test the toolchain
109108

110-
Simple examples built with the toolchain can be run with [QEMU User space emulator](https://www.qemu.org/docs/master/user/main.html) making use of semihosting for input and output as follows.
111-
112-
_Note: More complex bare-metal examples may need to use [QEMU Arm System emulator](https://www.qemu.org/docs/master/system/target-arm.html)._
113-
114-
Assuming this example code in `hello.c` file:
115-
```
116-
#include <stdio.h>
117-
118-
int main()
119-
{
120-
printf("Hello Embedded LLVM!\n");
121-
return 0;
122-
}
123-
```
124-
125-
Build the example:
126-
127-
```
128-
$ PATH=${INSTALL_ROOT_DIR}/LLVMEmbeddedToolchainForArm-$VERSION/bin:$PATH
129-
$ clang --config armv6m-none-eabi_rdimon -g -o hello hello.c
130-
```
131-
132-
Run the example with QEMU:
133-
134-
```
135-
$ qemu-arm -cpu cortex-m0 hello
136-
Hello Embedded LLVM!
137-
```
138-
139-
Debug the example with GDB:
140-
141-
Console 1: start QEMU in debug mode:
142-
```
143-
$ qemu-arm -cpu cortex-m0 -g 1234 hello
144-
```
145-
Console 2: attach to QEMU with GDB provided by the [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads):
146-
```
147-
$ arm-none-eabi-gdb hello
148-
(gdb) target remote :1234
149-
```
109+
See the `samples` folder for sample code and instructions on building, running and debugging.
150110

151111
## Known limitations
152112
* Depending on the state of the components, build errors may occur when ``VERSION=HEAD`` is used.

samples/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/*.elf
2+
**/*.hex

samples/Makefile.conf

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# Copyright (c) 2020, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
ifndef VERSION
19+
VERSION=0.1
20+
endif
21+
BIN_PATH=../../../LLVMEmbeddedToolchainForArm-${VERSION}/bin/

samples/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Samples of LLVM Embedded Toolchain for Arm
2+
3+
# Directory structure
4+
5+
* `ldscripts` - Linker scripts used by samples.
6+
* `startup` - Startup code used by samples.
7+
* `src` - Sample source code, Makefile and description, each sub-directory is a separate sample.

samples/ldscripts/microbit.ld

+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/* Linker script to configure memory regions.
2+
* Need modifying for a specific board.
3+
* FLASH.ORIGIN: starting address of flash
4+
* FLASH.LENGTH: length of flash
5+
* RAM.ORIGIN: starting address of RAM bank 0
6+
* RAM.LENGTH: length of RAM bank 0
7+
*/
8+
MEMORY
9+
{
10+
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x40000
11+
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000
12+
}
13+
14+
/* Linker script to place sections and symbol values. Should be used together
15+
* with other linker script that defines memory regions FLASH and RAM.
16+
* It references following symbols, which must be defined in code:
17+
* Reset_Handler : Entry of reset handler
18+
*
19+
* It defines following symbols, which code can use without definition:
20+
* __exidx_start
21+
* __exidx_end
22+
* __copy_table_start__
23+
* __copy_table_end__
24+
* __zero_table_start__
25+
* __zero_table_end__
26+
* __etext
27+
* __data_start__
28+
* __preinit_array_start
29+
* __preinit_array_end
30+
* __init_array_start
31+
* __init_array_end
32+
* __fini_array_start
33+
* __fini_array_end
34+
* __data_end__
35+
* __bss_start__
36+
* __bss_end__
37+
* __end__
38+
* end
39+
* __HeapLimit
40+
* __StackLimit
41+
* __StackTop
42+
* __stack
43+
*/
44+
ENTRY(Reset_Handler)
45+
46+
SECTIONS
47+
{
48+
.text :
49+
{
50+
KEEP(*(.isr_vector))
51+
*(.text*)
52+
53+
KEEP(*(.init))
54+
KEEP(*(.fini))
55+
56+
/* .ctors */
57+
*crtbegin.o(.ctors)
58+
*crtbegin?.o(.ctors)
59+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
60+
*(SORT(.ctors.*))
61+
*(.ctors)
62+
63+
/* .dtors */
64+
*crtbegin.o(.dtors)
65+
*crtbegin?.o(.dtors)
66+
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
67+
*(SORT(.dtors.*))
68+
*(.dtors)
69+
70+
KEEP(*(.eh_frame*))
71+
} > FLASH
72+
73+
.rodata :
74+
{
75+
*(.rodata .rodata.*)
76+
} > FLASH
77+
78+
.ARM.extab :
79+
{
80+
*(.ARM.extab* .gnu.linkonce.armextab.*)
81+
} > FLASH
82+
83+
__exidx_start = .;
84+
.ARM.exidx :
85+
{
86+
*(.ARM.exidx .ARM.exidx* .gnu.linkonce.armexidx.*)
87+
} > FLASH
88+
__exidx_end = .;
89+
90+
/* To copy multiple ROM to RAM sections,
91+
* uncomment .copy.table section and,
92+
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
93+
/*
94+
.copy.table :
95+
{
96+
. = ALIGN(4);
97+
__copy_table_start__ = .;
98+
LONG (__etext)
99+
LONG (__data_start__)
100+
LONG (__data_end__ - __data_start__)
101+
LONG (__etext2)
102+
LONG (__data2_start__)
103+
LONG (__data2_end__ - __data2_start__)
104+
__copy_table_end__ = .;
105+
} > FLASH
106+
*/
107+
108+
/* To clear multiple BSS sections,
109+
* uncomment .zero.table section and,
110+
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
111+
/*
112+
.zero.table :
113+
{
114+
. = ALIGN(4);
115+
__zero_table_start__ = .;
116+
LONG (__bss_start__)
117+
LONG (__bss_end__ - __bss_start__)
118+
LONG (__bss2_start__)
119+
LONG (__bss2_end__ - __bss2_start__)
120+
__zero_table_end__ = .;
121+
} > FLASH
122+
*/
123+
124+
/* Location counter can end up 2byte aligned with narrow Thumb code but
125+
__etext is assumed by startup code to be the LMA of a section in RAM
126+
which must be 4byte aligned */
127+
__etext = ALIGN (4);
128+
129+
.data : AT (__etext)
130+
{
131+
__data_start__ = .;
132+
*(vtable)
133+
*(.data*)
134+
135+
. = ALIGN(4);
136+
/* preinit data */
137+
PROVIDE_HIDDEN (__preinit_array_start = .);
138+
KEEP(*(.preinit_array))
139+
PROVIDE_HIDDEN (__preinit_array_end = .);
140+
141+
. = ALIGN(4);
142+
/* init data */
143+
PROVIDE_HIDDEN (__init_array_start = .);
144+
KEEP(*(SORT(.init_array.*)))
145+
KEEP(*(.init_array))
146+
PROVIDE_HIDDEN (__init_array_end = .);
147+
148+
149+
. = ALIGN(4);
150+
/* finit data */
151+
PROVIDE_HIDDEN (__fini_array_start = .);
152+
KEEP(*(SORT(.fini_array.*)))
153+
KEEP(*(.fini_array))
154+
PROVIDE_HIDDEN (__fini_array_end = .);
155+
156+
KEEP(*(.jcr*))
157+
. = ALIGN(4);
158+
/* All data end */
159+
__data_end__ = .;
160+
161+
} > RAM
162+
163+
.bss :
164+
{
165+
. = ALIGN(4);
166+
__bss_start__ = .;
167+
*(.bss*)
168+
*(COMMON)
169+
. = ALIGN(4);
170+
__bss_end__ = .;
171+
} > RAM
172+
173+
.heap (COPY):
174+
{
175+
__end__ = .;
176+
PROVIDE(end = .);
177+
*(.heap*)
178+
__HeapLimit = .;
179+
} > RAM
180+
181+
/* .stack_dummy section doesn't contains any symbols. It is only
182+
* used for linker to calculate size of stack sections, and assign
183+
* values to stack symbols later */
184+
.stack_dummy (COPY):
185+
{
186+
*(.stack*)
187+
} > RAM
188+
189+
/* Set stack top to end of RAM, and stack limit move down by
190+
* size of stack_dummy section */
191+
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
192+
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
193+
PROVIDE(__stack = __StackTop);
194+
195+
/* Check if data + heap + stack exceeds RAM limit */
196+
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
197+
}
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
# Copyright (c) 2020, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
include ../../Makefile.conf
19+
20+
build: hello.elf
21+
22+
hello.elf: *.c
23+
$(BIN_PATH)clang --config armv6m-none-eabi_rdimon_baremetal -g -T ../../ldscripts/microbit.ld -o hello.elf ../../startup/startup_ARMCM0.S $^
24+
25+
%.hex: %.elf
26+
$(BIN_PATH)llvm-objcopy -O ihex $< $@
27+
28+
run: hello.hex
29+
# -m option is a workaround to ensure correct initialization of semihosting
30+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$< -m 1073741824k
31+
32+
debug: hello.hex
33+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$< -m 1073741824k -s -S
34+
35+
clean:
36+
rm *.elf *.hex
37+
38+
.PHONY: clean run debug
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
This sample shows how to use semihosting with [QEMU Arm System emulator](https://www.qemu.org/docs/master/system/target-arm.html) targeting the [micro:bit board model](https://www.qemu.org/2019/05/22/microbit/).
2+
3+
It uses the startup code and the linker script file from the GNU Arm Embedded Toolchain samples.
4+
5+
Usage:
6+
* `VERSION=0.1 make build` to build the sample.
7+
* `VERSION=0.1 make run` to run the the sample with QEMU Arm System emulator.
8+
* `VERSION=0.1 make debug` to run the the sample with QEMU Arm System emulator with GDB server listening on the default port 1234.
9+
10+
To debug attach to QEMU with GDB provided by the [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads):
11+
12+
```
13+
$ arm-none-eabi-gdb hello.elf
14+
(gdb) target remote :1234
15+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <stdio.h>
2+
3+
int main(void) {
4+
printf("Hello World!\n");
5+
return 0;
6+
}
7+
8+
void SystemInit() {}

samples/src/baremetal-uart/Makefile

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#
2+
# Copyright (c) 2020, Arm Limited and affiliates.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
include ../../Makefile.conf
19+
20+
build: hello.elf
21+
22+
hello.elf: *.c
23+
$(BIN_PATH)clang --config armv6m-none-eabi_nosys -g -T ../../ldscripts/microbit.ld -o hello.elf ../../startup/startup_ARMCM0.S $^
24+
25+
%.hex: %.elf
26+
$(BIN_PATH)llvm-objcopy -O ihex $< $@
27+
28+
run: hello.hex
29+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$< -m 1073741824k
30+
31+
debug: hello.hex
32+
qemu-system-arm -M microbit -semihosting -nographic -device loader,file=$< -m 1073741824k -s -S
33+
34+
clean:
35+
rm *.elf *.hex
36+
37+
.PHONY: clean run debug

0 commit comments

Comments
 (0)