Skip to content
This repository was archived by the owner on Apr 3, 2025. It is now read-only.

Commit c660e58

Browse files
committed
documentation
1 parent 9997113 commit c660e58

File tree

6 files changed

+71
-30
lines changed

6 files changed

+71
-30
lines changed

Makefile

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
export PATH := $(PATH):$(HOME)/local/sdcc/bin
2-
3-
MCU = stm8s003f3
1+
MCU ?= stm8s003f3
42
ARCH = stm8
53

6-
#F_CPU ?= 2000000
74
F_CPU ?= 16000000
85
TARGET ?= main.ihx
96

@@ -17,6 +14,7 @@ CC = sdcc
1714
LD = sdld
1815
AS = sdasstm8
1916
OBJCOPY = sdobjcopy
17+
ASFLAGS = -plosgff
2018
CFLAGS = -m$(ARCH) -p$(MCU)
2119
CFLAGS += -DF_CPU=$(F_CPU)UL -I.
2220
CFLAGS += --stack-auto --noinduction --use-non-free --noinvariant --opt-code-size
@@ -29,7 +27,7 @@ $(TARGET): $(OBJS)
2927
$(CC) $(LDFLAGS) $(OBJS) -o $@
3028

3129
%.rel: %.s
32-
$(AS) -plosgff $<
30+
$(AS) $(ASFLAGS) $<
3331

3432
%.rel: %.c
3533
$(CC) $(CFLAGS) -c $< -o $@
@@ -42,17 +40,27 @@ clean:
4240

4341
size:
4442
@$(OBJCOPY) -I ihex --output-target=binary $(TARGET) $(TARGET).bin
45-
@echo "-----\nImage size:"
43+
@echo '-----\nImage size:'
4644
@stat -L -c %s $(TARGET).bin
4745

48-
opt-dump:
49-
stm8flash -c stlinkv2 -p stm8s003f3 -s opt -r dump_opt.bin
46+
# enable write-protection on first 10 pages
47+
opt-set:
48+
@echo '0x00 0x0a 0xf5 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff' | xxd -r > opt.bin
49+
stm8flash -c stlinkv2 -p stm8s003f3 -s opt -w opt.bin
50+
51+
# reset option-bytes to factory defaults
52+
opt-reset:
53+
@echo '0x00 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff' | xxd -r > opt.bin
54+
stm8flash -c stlinkv2 -p stm8s003f3 -s opt -w opt.bin
55+
56+
dump-opt:
57+
stm8flash -c stlinkv2 -p $(MCU) -s opt -r dump_opt.bin
5058

51-
mem-dump:
52-
stm8flash -c stlinkv2 -p stm8s003f3 -s flash -r dump_flash.bin
59+
dump-flash:
60+
stm8flash -c stlinkv2 -p $(MCU) -s flash -r dump_flash.bin
5361

5462
erase:
5563
tr '\000' '\377' < /dev/zero | dd of=empty.bin bs=8192 count=1
56-
stm8flash -c stlinkv2 -p stm8s003f3 -s flash -w empty.bin
64+
stm8flash -c stlinkv2 -p $(MCU) -s flash -w empty.bin
5765

58-
.PHONY: clean all program
66+
.PHONY: clean all flash size dump-opt dump-flash erase

README.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,48 @@
11
# stm8-bootloader
2-
A serial bootloader for low-density STM8S microcontrollers.
2+
Serial bootloader for STM8S microcontrollers.
33

4-
... work in progress ...
4+
## Features
55

6-
TL;DR
6+
* **small** - fits in 9 pages (547 bytes w/ SDCC v3.6.8 #9951)
7+
* **fast** - uploads 4k binary in 1 second @115200bps
8+
* **configurable** - can be adjusted for parts with different flash block size
9+
10+
## Configuration
11+
12+
The default configuration targets low-density devices (STM8S003). Configuration is located in `config.h`.
13+
* **BLOCK_SIZE** - flash block size according to device datasheet. This should be set to 64 for low-density devices or 128 for devices with >8k flash.
14+
* **BOOT_ADDR** - application boot address.
15+
* **BOOT_PIN** - entry jumper. This is set to PD3 by default.
16+
* **RELOCATE_IVT** - when set to 1 (default) the interrupt vectors are relocated. When set to 0 the bootloader will overwrite it's own interrupt vector table with the application's IVT, thus eliminating additional CPU overhead during interrupts. Write-protection cannot be used in this case and resulting binary is slightly larger.
17+
18+
### Changing boot address
19+
Boot address must be a multiple of BLOCK_SIZE. Address is set in 2 places:
20+
* config.h
21+
* init.s
22+
23+
Main application is compiled with `--code-loc <address>` option. When RELOCATE_IVT is set to 0, 0x80 must be subtracted from application address and isr29 must be implemented: `void dummy_isr() __interrupt(29) __naked { ; }`.
24+
25+
## Build instructions
26+
Build and flash the bootloader:
727

8-
Short PD3 -> GND.
928
``` bash
1029
$ make && make flash
30+
```
31+
32+
Enable write-protection (UBC) on pages 0-10:
33+
34+
``` bash
35+
make opt-set
36+
```
37+
38+
## Uploading the firmware
39+
40+
There is a demo application inside `app` directory which toggles PD4 via interrupts. To upload the application short PD3 to ground, power-cycle the MCU and run the uploader utility.
41+
42+
``` bash
1143
$ cd app && make
1244
$ python ../uploader/boot.py -p /dev/ttyUSB0 firmware.bin
1345
```
46+
47+
## Porting
48+
TBD

app/Makefile

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
export PATH := $(PATH):$(HOME)/local/sdcc/bin
2-
3-
MCU = stm8s003f3
1+
MCU ?= stm8s003f3
42
ARCH = stm8
53

64
F_CPU ?= 2000000
75
TARGET ?= main.ihx
86

9-
SRCS := $(wildcard *.c $(LIBDIR)/*.c)
7+
SRCS := $(wildcard *.c)
108
OBJS = $(SRCS:.c=.rel)
119

1210
CC = sdcc
13-
LD = sdld
1411
OBJCOPY = sdobjcopy
1512
CFLAGS = -m$(ARCH) -p$(MCU)
1613
CFLAGS += -DF_CPU=$(F_CPU)UL -I. -I$(LIBDIR)
@@ -33,4 +30,4 @@ $(TARGET): $(OBJS)
3330
clean:
3431
rm -f *.map *.asm *.rel *.ihx *.o *.sym *.lk *.lst *.rst *.cdb *.bin
3532

36-
.PHONY: clean all program
33+
.PHONY: clean all

app/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ void tim4_isr() __interrupt(TIM4_ISR) {
1414
TIM4_SR &= ~(1 << TIM4_SR_UIF);
1515
}
1616

17-
inline void timer_config() {
17+
static void timer_config() {
1818
/* Prescaler = 128 */
1919
TIM4_PSCR = 0b00000111;
2020

main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ inline void ram_cpy() {
191191
f_ram[i] = ((uint8_t *) ram_flash_write_block)[i];
192192
}
193193

194-
// size: 750 -> 744 -> 738 -> 729 -> 721 -> 658 -> 644:654 -> 640:560 -> 623:547
195194
void bootloader_main() {
196195
BOOT_PIN_CR1 = 1 << BOOT_PIN;
197196
if (!(BOOT_PIN_IDR & (1 << BOOT_PIN))) {

uploader/boot.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
BLOCK_SIZE = 64 # 128 for parts with >8k flash
55

6-
REQ_ENTER = [0xde, 0xad, 0xbe, 0xef]
7-
ACK = [0xaa, 0xbb]
8-
NACK = [0xde, 0xad]
6+
REQ_ENTER = (0xde, 0xad, 0xbe, 0xef)
7+
ACK = (0xaa, 0xbb)
8+
NACK = (0xde, 0xad)
99
FILE = None
1010

1111
def crc8_update(data, crc):
@@ -59,10 +59,12 @@ def bootloader_exec(port, baud):
5959
ser.flushOutput()
6060
chunk = bytearray(f.read(BLOCK_SIZE))
6161
ack = ser.read(2)
62-
if ack == bytearray(NACK):
62+
if ack == bytearray(ACK):
63+
print('Done')
64+
elif ack == bytearray(NACK):
6365
print('CRC mismatch')
64-
return
65-
print('Done')
66+
else:
67+
print('Invalid response')
6668
ser.close()
6769

6870
if __name__ == "__main__":

0 commit comments

Comments
 (0)