what’s the difference between board_fuses.lfuse and board_bootloader.lfuse.
when would you use one vs the other?
Where do you see those two being referenced?
If you run pio run -t bootloader
it will burn the bootloader according to the board_bootloader
settings with its respective fuses (lfuse, hfuse, efuse, …). See code
When using pio run -t program
for normal programming it will use the fuses set by board_fuses
. See
Optimally if you program a custom bootloader and a firmware, the fuses should match.
If you are not using a custom bootloader or using the pio run -t bootloader
target, bootloader fuses will not be used anyway and can be ignored.
I, i never used lock bits until now. I’m using an atmega328p with arduino as isp programmer; i use this platformio.ini:
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:nanoatmega3283t]
platform = atmelavr
framework = arduino
board = uno
lib_extra_dirs =
D:\Documenti-Gio\Arduino-PROJECTS\libraries
upload_protocol = stk500v1
; FUSES STANDARD + FULL SWING CRYSTAL
board_fuses.lfuse = 0xF7
board_fuses.hfuse = 0xDE
board_fuses.efuse = 0xFD
upload_flags =
-P$UPLOAD_PORT
-b$UPLOAD_SPEED
-e
upload_port = COM4
upload_speed = 19200
Now i made a project that i would like to protect from only reading and copy. I read a bit about LB fuses and it seems to me that i have to put LB at 0x00.
Can i simply add line…
board_fuses.lock_bits = 0x00
… to my platformio.ini and program my chip as before or is needed a different method to program lock bits?
Looking at PIO’s code to get the fuses
The logic reads as follows. If a board_fuses.lock
exists (e.g., from your platformio.ini
or the board’s definition file), it will be used. Otherwise, the default value is the return value of the get_lock_bits
function.
So you have to write
board_fuses.lock = 0x00
into your platformio.ini
and then run the “Fuses” target in VSCode or pio run -t fuses
from the commandline, as outlined in the above mentioned docs. That will cause an avrdude
invocation which will program the lock bits to your desired value.
I’m playng with fuses… A question: upload_flag -e can restore board_fuses.lock to a non-locked state?
I mean if i set fuses (even bit lock at 0x00), then i flash my code with -e flag, the mcu is no longer locked. Is this a normal behaviour?
A related question: how can i read fuses state on connected mcu in platformio?
But if you have to erase the chip to unlock it, the program is also gone with it, so the protection worked? According to https://www.avrfreaks.net/forum/erasing-chip-not-resetting-lock-bits that’s normal. Atmel / now Microchip engineers would be the people to ask to make sure.
PlatformIO has no “read fuses” command but:
- isn’t the state of the fuse shown in the AVRdude output in each programming?
- You can use advanced scripting + custom targets to implement a new target which triggers the appropriate
avrdude
command to read out fuses (and / or Flash and EEPROM contents) to stdout or a file. E.g.,avrdude -c usbtiny -p m328p -U flash:r:extracted.hex:i -U lfuse:r:-:b
is a command that will attempt to use AVRDude with theusbtiny
programmer to readout the flash contents in intel-hex format to the fileextracted.hex
and the LFUSE content in binary to stdout (-
). All options are documented in avrdude and various internet pages. - There also exist GUI programs for AVRDude to make it easier.
@maxgerhardt, I noted that the pio don’t get lock value from board.lock and yes from board.lock_bit.
I did the following test:
My platformio.ini
[env:test]
platform = atmelavr
board = ATmega328PB
board_fuses.lock = 0xFF
board_fuses.efuse = 0xFD
board_fuses.hfuse = 0xD6
board_fuses.lfuse = 0xE2
and the pio run -t fuses
:
Selected fuses: [lfuse = 0xE2, hfuse = 0xD6, efuse = 0xFD]
avrdude -p atmega328pb -C "/home/mario/.platformio/packages/tool-avrdude/avrdude.conf" -e -c arduino -Ulock:w:0x0f:m -Uhfuse:w:0xD6:m -Ulfu
se:w:0xE2:m -Uefuse:w:0xFD:m
Note that the lock fuse is has not value I defined in platformio.ini (-Ulock:w:0x0f:m and I defined 0xFF).
when I put board_lock_bit
in platformio.ini, I get the correct set for lock fuse.
My new platformio.ini
[env:test]
platform = atmelavr
board = ATmega328PB
board_fuses.lock = 0xFF
board_fuses.lock_bits = 0xFF
board_fuses.efuse = 0xFD
board_fuses.hfuse = 0xD6
board_fuses.lfuse = 0xE2
and the pio run -t fuses
:
Selected fuses: [lfuse = 0xE2, hfuse = 0xD6, efuse = 0xFD]
avrdude -p atmega328pb -C "/home/mario/.platformio/packages/tool-avrdude/avrdude.conf" -e -c arduino -Ulock:w:0xFF:m -Uhfuse:w:0xD6:m -Ulfu
se:w:0xE2:m -Uefuse:w:0xFD:m
Note that the lock fuse now get the correct value (-Ulock:w:0xFF:m).
I don’t know if is a problem in platformio. I don’t found any documentation about difference between lock and lock_bit in platformio documentation.
The logic has changed since the time I’ve posted it. Have a look at
The fuses target will use board_fuses.lock_bits
and when burning the bootloader (pio run -t bootloader
) it will uses bootloader_fuses.lock_bits
. No more board_fuses.lock
.
Theses fuses are also explained in the docs.