Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to program the option bytes #6

Closed
tenbaht opened this issue Nov 21, 2018 · 12 comments
Closed

allow to program the option bytes #6

tenbaht opened this issue Nov 21, 2018 · 12 comments

Comments

@tenbaht
Copy link
Contributor

tenbaht commented Nov 21, 2018

It would be useful to be able to access and modify the option bytes using stm8gal. Especially the ROP (read out protection) bit for unlocking a locked MCU is important.

@gicking
Copy link
Owner

gicking commented Nov 24, 2018

hi Michale,

using option "-x" stm8gal already deactivates the bootloader via option byte (and it's complementary). Via bootloader this is identical to writing other flash memory. So adding this is VERY simple, the question is mainly the "user interface"

  • for maximum flexibility I can add a generic "write option byte" parameter with address and value. As far as I remember the complementary value is always required, and it always is at address+1. Do you know if this is correct?

  • Alternatively, if specific option bytes are always at the same address (like BL), I could add it via function name instead of address + value. Do you know if this is the case?

What would you prefer?

Regards, Georg

@gicking
Copy link
Owner

gicking commented Nov 25, 2018

I just compared the datasheets of STM8AF52xx and STM8L101xx, and unfortunately the option bytes don't match. In addition the STM8L does not require the complementary value, probably to save a few bytes... :-(

@tenbaht
Copy link
Contributor Author

tenbaht commented Nov 26, 2018

stm8flash treats the option bytes simply as a generic memory area that can be read and written. It is the users responsibility to format the content accordingly. Maybe something similar for stm8gal? Using stm8flash looks like this:

stm8flash -c stlinkv2 -p "stm8s103?3" -s opt -r opt.bin

How about an option "-s "? It could default to flash memory if not given. This allows for easy extensions in the future e.g. for EEPROM access.

If you decide to add a device type specifier anyway (because of the uart mode issue) It would be possible to integrate the knowledge about the exact memory layout into stm8gal and allow a more user-friendly interface similar to the fuse definitions with avrdude: avrdude -U efuse:w:0xaa:m. Maybe something like this:

stm8gal -p s103 -s opt1 -w 0x02 -s opt2 -w 0x00

But I am not sure if this is really better than a generic interface similar to stm8flash.

@gicking
Copy link
Owner

gicking commented Nov 26, 2018

I prefer option 1 because it matches the procedure in stm8flash, and also because I don't plan to add a device specifier for the uart mode issue . Besides the many different supported options would just blow up stm8gal.

Do I understand correctly that file opt.bin contains plain binary data, and that -s opt only sets the target address to the start of the option bytes?

Alternatively how about writing option bytes from a hexfile with proper address and value...? Such a hexfile could be easily created from an ASCII-table using hexfile_merger. And as a positive side-effect I wouldn't need to change stm8gal ;-)

@tenbaht
Copy link
Contributor Author

tenbaht commented Nov 26, 2018

I am not sure if only setting the target address is enough. I think the access needs to unlocked first by a magic sequence and two special bits need to be set in the flash control registers. (rm0016, sec. 4.4.6, page 43). But sec. 4.6.5 (page 49) gives hope: "Option byte programming is very similar to data EEPROM byte programming".

I guess there is a reason why the guys at stm8flash add a special option for this memory area (but I don't know for sure). Reading the option byte area of an unlocked STM8S103F3P6 without any option bits set (on Mint 19) looks like this:

$ stm8flash -c stlinkv2 "-pstm8s103?3" -s opt -r opt.hex
Determine OPT area
Due to its file extension (or lack thereof), "opt.hex" is considered as INTEL HEX format!
Reading 64 bytes at 0x4800... OK
Bytes received: 64
$ cat opt.hex 
:204800000000FF00FF00FF00FF00FF0000000000000000000000000000000000000000009D
:20482000000000000000000000000000000000000000000000000000000000000000000078
:00000001FF

Or in binary mode:

$ stm8flash -c stlinkv2 "-pstm8s103?3" -s opt -r opt.bin
Determine OPT area
Due to its file extension (or lack thereof), "opt.bin" is considered as RAW BINARY format!
Reading 64 bytes at 0x4800... OK
Bytes received: 64
$ hd opt.bin
00000000  00 00 ff 00 ff 00 ff 00  ff 00 ff 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000040

@gicking
Copy link
Owner

gicking commented Nov 27, 2018

you are correct about unlocking option byte range. However, this is apparently taken care of by the bootloader or the RAM routines already. Because if you look at main.c line 773 you see that activating the bootloader is done via

bsl_memWrite(ptrPort, physInterface, uartMode, 0x487E, 2, (char*)"\x55\xAA", -1);

and bsl_memWrite() makes no distinction between P-flash or option bytes. So no magic there... :-)

As said, the main question is the "UI", not the actual writing of the option bytes. But let me check again

@gicking
Copy link
Owner

gicking commented Dec 8, 2018

my current idea is to write option bytes just like a "normal" hexfile. Already tested it and it works :-)

Procedure:

  1. create plain option byte table like in this example
  2. use hexfile_merger tool to convert to hexfile via hexfile_merger -i table.txt -o option.s19
  3. dump option bytes via stm8gal -p /dev/ttyUSB0 -r 0x4800 0x487F pre.txt
  4. upload result to STM8 via stm8gal -p /dev/ttyUSB0 -w option.s19
  5. dump option bytes again via stm8gal -p /dev/ttyUSB0 -r 0x4800 0x487F post.txt
  6. comparison via diff pre.txt post.tx confirms the intended change in OPT2/NOPT2
4,5c4,5
< 0x4803	0x00
< 0x4804	0xff
---
> 0x4803	0x80
> 0x4804	0x7f

I understand that calling an extra tool is inconvenient, but that can be overcome rather easily by adding an import filter for plain tables (like this). Then changing option bytes becomes as easy as RTFM... ;-) I actually prefer this method over cryptic commandline parameters, because it is more transparent. But what do you think?

IMHO the only disadvantage is that stm8gal can currently only upload one file at a time --> to upload a software AND change the option bytes it must be called twice. Changing that could be done by adding support for multiple file import (like hexfile_merger).

But first things first: is changing option bytes via plain ASCII tables the way to go? Please let me know what you think. Thanks in advance!

PS: By the way, as the memory dumps from steps 3+5 have the same format as the import file in step 1, they are convenient starting points for option byte setups :-)

gicking added a commit that referenced this issue Dec 8, 2018
add examples for changing option bytes, see
#6
@tenbaht
Copy link
Contributor Author

tenbaht commented Dec 8, 2018

Sound like a good start. I will try it next week.

Would it be possible to support using the txt files as input files directly? It would be a custom hex file format.

Instead of hexfile_merger the standard objcopy (or sdobjcopy from the sdcc package) can do the job of converting binary data into a valid s19 file:

$ echo -n "abcd" > test.bin # just 4 bytes of nonsense data
$ sdobjcopy --change-addresses 0x4800 -I binary -O srec test.bin test.s19
$ cat test.s19
S0080000612E7331398B
S10748006162636426
S9034800B4

How about supporting raw binary data as input? That would save the conversion step to s19. The address transformation can be handled by either specifing a memory type (like -s option) or an address parameter (like -a 0x4800).

@gicking
Copy link
Owner

gicking commented Dec 10, 2018

yes, I plan to support both ASCII tables and binary data as input format. Then changing option bytes becomes very easy. My current idea is like this:

ASCII Table:
file format is currently detected by file extension. I will simply add a new filter for "*.txt" for tables like this:

# OPT2 alternate function
0x4803  0x80
0x4804 0x7F

Binary File:
add a new option -wb addr file (="write binary"), like you proposed. Then the above conversion step to s19 would no longer be required.

Let me know what you think :-)

PS: one more question: I remember that Cosmic allows to specify static data with address. That is how I used to set option bytes from within a project without having to change them only. Unfortunately I don't recall how this is done, but does SDCC allow this as well? If yes, that is yet another option, i.e. encapsulated in the resulting build output. At least I should point out this option in the Readme.md.

@gicking
Copy link
Owner

gicking commented Dec 10, 2018

ASCII table seems to work now, see branch "addTableAndBinary". Please try and let me know. Thanks in advance!

Syntax is same as before (stm8gal -p /dev/ttyUSB0 -w OPT2.txt). Simple example tables can be found in folder "option_bytes".

@gicking
Copy link
Owner

gicking commented Dec 20, 2018

just uploaded branch "addTableAndBinary" which now allows multiple uploads (and downloads) in one run. In addition it is now possible to change a value in flash or RAM directly (option -s), or via an ASCII table (*.txt). That way option bytes (or any other memory) can be changed easily.

Note however, that inconsistent option bytes (NOPT != OPT^0xFF) result in an endless reset cycle, i.e. bootloader is effectively disabled --> recover requires SWIM and stm8flash. Therefore always change option bytes pairs if applicable (is device dependent)

Please let me know what you think of this. Also please let me know if the previos UART mode detection is working for your boards...? Thanks a lot in advance!

@gicking
Copy link
Owner

gicking commented Feb 2, 2019

Writing option bytes works in v1.3.0 via hexfiles, binary files or files with plain text, e.g.

# OPT2 alternate function
0x4803  0x80
0x4804 0x7F

Warning: use option bytes with cary! If OPT and NOPT (=inverse) bytes don't match. the STM8 stays in an endless reset cycle. This condition can only be fixed via SWIM interface.

@gicking gicking closed this as completed Feb 2, 2019
MarkStokes71 pushed a commit to MarkStokes71/stm8gal that referenced this issue Feb 17, 2021
add examples for changing option bytes, see
gicking#6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants