Skip to content

Commit f1e335f

Browse files
authored
Merge pull request #8 from Neotron-Compute/cleanup-c-asm
Improve ASM and C examples.
2 parents df11b18 + 4439839 commit f1e335f

File tree

8 files changed

+181
-41
lines changed

8 files changed

+181
-41
lines changed

samples/asmhello/asmhello.S

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,60 @@
1+
/**
2+
* Basic ARM Unified Assembly Language sample which runs on Neotron OS.
3+
*/
4+
15
.syntax unified
2-
.thumb
3-
.cpu cortex-m0plus
4-
.global app_entry
5-
.thumb_func
6+
7+
//
8+
// Functions (.text)
9+
//
610

711
.text
8-
.section ".text"
912

10-
// r0 will contain a pointer to the syscall table
11-
// the write function is the third entry (offset 8)
12-
// and takes the arguments r0=handle, r1=pointer, r2=length
13+
// Entry point for our application.
14+
//
15+
// * r0 will contain a pointer to the syscall table.
16+
// * The write function is the third entry (offset 8)
17+
// and takes the arguments r0=handle, r1=pointer, r2=length
18+
.thumb_func
19+
.global app_entry
20+
.func app_entry
1321
app_entry:
14-
// Save registers
15-
push {r0, r1, r2, lr}
22+
// "A subroutine must preserve the contents of the registers r4-r11
23+
// and SP" - and we only use R4
24+
push {r4, lr}
1625
// Fetch write function address
1726
ldr r3, [r0, #8]
18-
// Set up data length
19-
movs r2, #13
2027
// Set up file handle
2128
movs r0, #1
2229
// Set up data pointer
2330
ldr r1, =message
31+
// Set up data length
32+
ldr r4, =message_len
33+
ldr r2, [r4]
2434
// Call write function
2535
blx r3
2636
// Set return value
2737
movs r0, #0
2838
// Exit
29-
pop {r1, r2, r3, pc}
39+
pop {r4, pc}
40+
.endfunc
41+
42+
//
43+
// Read Only Data (.rodata)
44+
//
3045

31-
.data
32-
.section ".rodata"
46+
.section .rodata
3347

48+
// The message we want to print
49+
.type message,%object
3450
message:
3551
.ascii "Hello world!\n"
52+
53+
// The length of the string with the label `message`
54+
//
55+
// Must come immediately after `message:`
56+
.type message_len,%object
57+
message_len:
58+
.long . - message
59+
60+
// End of file

samples/asmhello/build.sh

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
1-
#!/bin/sh
2-
arm-none-eabi-gcc -mcpu=cortex-m0 -Wl,-T../neotron-cortex-m.ld -o asmhello.elf asmhello.S -nostdlib
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
TARGET=${1:-thumbv6m-none-eabi}
6+
7+
if [ "$TARGET" == "thumbv6m-none-eabi" ]; then
8+
CPU="cortex-m0plus"
9+
elif [ "$TARGET" == "thumbv7m-none-eabi" ]; then
10+
CPU="cortex-m3"
11+
elif [ "$TARGET" == "thumbv7em-none-eabi" ]; then
12+
CPU="cortex-m4"
13+
else
14+
echo "Unknown target"
15+
exit 1
16+
fi
17+
18+
arm-none-eabi-gcc \
19+
-nostartfiles \
20+
-ffreestanding \
21+
-mcpu=$CPU \
22+
-Wl,-T../neotron-cortex-m.ld \
23+
-o asmhello.elf \
24+
asmhello.S \

samples/build.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ echo "Building for ${TARGET}"
2525
cargo build --target ${TARGET} --release
2626

2727
pushd chello
28-
./build.sh
28+
./build.sh ${TARGET}
2929
popd
3030

3131
pushd asmhello
32-
./build.sh
32+
./build.sh ${TARGET}
3333
popd
3434

3535
for program in panic hello fault input-test; do

samples/chello/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
*.elf
2+
*.o
3+

samples/chello/build.sh

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,37 @@
1-
#!/bin/sh
2-
arm-none-eabi-gcc -Os -mcpu=cortex-m0 -Wl,-T../neotron-cortex-m.ld -o chello.elf chello.c -nostdlib
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
TARGET=${1:-thumbv6m-none-eabi}
6+
7+
if [ "$TARGET" == "thumbv6m-none-eabi" ]; then
8+
CPU="cortex-m0plus"
9+
elif [ "$TARGET" == "thumbv7m-none-eabi" ]; then
10+
CPU="cortex-m3"
11+
elif [ "$TARGET" == "thumbv7em-none-eabi" ]; then
12+
CPU="cortex-m4"
13+
else
14+
echo "Unknown target"
15+
exit 1
16+
fi
17+
18+
arm-none-eabi-gcc \
19+
-fdata-sections \
20+
-ffreestanding \
21+
-ffunction-sections \
22+
-flto \
23+
-mcpu=$CPU \
24+
-nostartfiles \
25+
-Os \
26+
-Wall \
27+
-Wconversion \
28+
-Wdouble-promotion \
29+
-Wextra \
30+
-Wl,-gc-sections \
31+
-Wl,-T../neotron-cortex-m.ld \
32+
-Wshadow \
33+
--specs=nano.specs \
34+
--specs=nosys.specs \
35+
-o chello.elf \
36+
stubs.c \
37+
chello.c

samples/chello/chello.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,37 @@
33
*/
44

55
#include "neotron.h"
6+
#include <stdio.h>
7+
#include <sys/stat.h>
8+
#include <unistd.h>
69

7-
int app_entry(const NeotronApi *f)
8-
{
9-
FfiByteSlice buffer = {
10-
.data = "Hello, world",
11-
.data_len = 12
12-
};
13-
Handle fd = {
14-
// fd 1 is STDOUT
15-
._0 = 1
16-
};
17-
f->write(fd, buffer);
18-
return 0;
10+
const NeotronApi *g_api;
11+
12+
static int main(void);
13+
14+
/*
15+
* Called by Neotron OS when the binary is 'run'.
16+
*/
17+
int app_entry(const NeotronApi *f) {
18+
g_api = f;
19+
return main();
1920
}
21+
22+
/*
23+
* Our main function.
24+
*
25+
* Just prints a message and exits.
26+
*/
27+
static int main(void) {
28+
// allocate a buffer
29+
void *buffer = calloc(1024, 1);
30+
// write a string into it
31+
snprintf(buffer, 1023, "Hello, world!\n");
32+
// print the buffer
33+
printf(buffer);
34+
// free the buffer
35+
free(buffer);
36+
return 0;
37+
}
38+
39+
// End of file

samples/chello/stubs.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Newlib stub functions we need.
3+
*/
4+
5+
#include <stdint.h>
6+
#include <sys/stat.h>
7+
#include <unistd.h>
8+
9+
#include "neotron.h"
10+
11+
extern const NeotronApi *g_api;
12+
13+
/*
14+
* Implementation of the newlib library syscall `write`
15+
*/
16+
int _write(int fd, const void *data, size_t count) {
17+
if (fd >= 255) {
18+
return -1;
19+
}
20+
FfiByteSlice buffer = {
21+
.data = data,
22+
.data_len = count,
23+
};
24+
Handle neo_fd = {
25+
._0 = (uint8_t)fd,
26+
};
27+
FfiResult_void result = g_api->write(neo_fd, buffer);
28+
if (result.tag == FfiResult_Ok) {
29+
return (int)count;
30+
} else {
31+
return -1;
32+
}
33+
}
34+
35+
// End of file

samples/neotron-cortex-m.ld

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ MEMORY
2020
}
2121

2222
/* # Entry point = what the BIOS calls to start the OS */
23+
EXTERN(app_entry);
2324
ENTRY(app_entry);
2425

2526
/* # Sections */
@@ -31,42 +32,42 @@ SECTIONS
3132
. = ALIGN(4);
3233
*(.text .text.*);
3334
. = ALIGN(4);
34-
}
35+
} > RAM
3536

3637
/* ### .rodata */
3738
.rodata : ALIGN(4)
3839
{
3940
. = ALIGN(4);
4041
*(.rodata .rodata.*);
4142
. = ALIGN(4);
42-
}
43+
} > RAM
4344

4445
/* ### .data */
4546
.data : ALIGN(4)
4647
{
4748
. = ALIGN(4);
4849
*(.data .data.*);
4950
. = ALIGN(4);
50-
}
51-
52-
/* LMA of .data */
53-
__sidata = LOADADDR(.data);
51+
} > RAM
5452

5553
/* ### .bss */
5654
.bss : ALIGN(4)
5755
{
5856
. = ALIGN(4);
5957
*(.bss .bss.*);
6058
. = ALIGN(4);
61-
}
59+
} > RAM
6260

6361
/* ### .uninit */
6462
.uninit (NOLOAD) : ALIGN(4)
6563
{
6664
. = ALIGN(4);
6765
*(.uninit .uninit.*);
6866
. = ALIGN(4);
69-
}
67+
} > RAM
68+
69+
. = ALIGN(4);
70+
end = .;
7071

7172
/* ## .got */
7273
/* Dynamic relocations are unsupported. This section is only used to detect relocatable code in

0 commit comments

Comments
 (0)