I have limited experience with microcontrollers and I am currently working on implementing a simple bootloader using the code provided in the following repository:
AVR128DA48 Curiosity Nano Bootloader – GitHub (https://github.com/microchip-pic-avr-examples/avr128da48-cnano-bootloader-mplabx/tree/master)
I am using the following
Hardware
- AVR128DA48 Curiosity Nano board
Software
- MPLAB X IDE v6.20
- AVR-GCC Compiler v7.3.0
- AVR-Dx_DFP v2.4.286
- Python v3.10.11
I have been executing the code line-by-line, and at first glance, it seems to work as expected. However, upon further testing, I have encountered issues where it does not work correctly.
To test the bootloader, I am using both the host application to load the entire binary file and RealTerm to send the binary file byte by byte over the serial interface.
Particularly, I have faced and noticed the following vague points in the implementation:
Point #1
I have configured the linker script with -Wl,--section-start=.text=0x200
and .text=0x200
, as specified in Section 3.2 of AN3341, expecting 0x200
to be the start address of the application code. However, the bootloader code starts at 0x100 instead of 0x0000, as I expected based on the fuse values (BOOTSIZE=0x02
and CODESIZE=0x00
).
Point #2
In the Memory Device, the application code does not appear to be written at the expected flash section (0x200 and so on). Instead, the entire flash memory is filled with 0xFFFF values, except for the section containing the compiled code.
Point #3
After the SOFTWARE_RESET case, the Program Counter jumps to address 0x0000 instead of 0x200, where the application code is expected to start. The fuses have been configured correctly (BOOTSIZE=0x02
and CODESIZE=0x00
).
Point #4
While the BOOTSIZE
and CODESIZE
fuses are set to 0x02 and 0x00
, respectively, the start address in the Python host application code is defined as 0x0000, as shown in the snippet below from the addInfo function:
appstart = ih.minaddr() start_address = struct.pack("<i", appstart)
The appstart value, which comes from the hex file, is 0x0000.
Shouldn't the start_address be set to 0x200, considering that the flash memory is word-aligned and the application code is expected to start at that address?
Conclusion
In summary, the main issue is the Flash section where the bootloader code is stored, as well as the inability to write the image in the memory. It seems that writes a word at a specific address but the memory value is still 0xFFFF
.
I would really appreciate any help and suggestions for any of the above questions.
1 Answer 1
I have detected that the problem occurs when the following function is called
PUBLIC_FUNCTION(pgm_word_write)
movw r0, r20
movw r30, r22 // Update R30, R31 pair with address[Byte1,Byte0]
out _SFR_IO_ADDR(RAMPZ), r24 // Update RAMPZ with address[Byte2]
spm
clr r1
ret // Return to caller
END_FUNC(pgm_word_write)
This function is expected to write a word to a specific address in flash memory, but unfortunately it does nothing (function is located in another .S file and not in the main .c file).
While I was monitoring the general registers R0, R20, R30, R22 etc I observed that the instructions movw
, out
and spm
had no effect, even though they executed normally.
The code snippet of the main program that calls the previous function is the following
if ((flash_addr & 0x01) == 0)
{
data_word = rx_data;
}
else
{
data_word |= (rx_data << 8);
/* Program flash word with desired value */
pgm_word_write((flash_addr & 0xFFFFFE), data_word);
}
where,
flash_addr is the flash address where I want to write
rx_data is a 1-byte data
data_word is a 2-byte data
All the necessary processes like page size erase and protected flash write enable have been already done
-
2\$\begingroup\$ Does this answer your question? Or is it providing more information, in which case it should be added as an edit? \$\endgroup\$Tim Williams– Tim Williams2025年03月18日 16:35:55 +00:00Commented Mar 18 at 16:35
-
1\$\begingroup\$ Spiros Andreopoulos - Hi, You posted this as an answer, but It doesn't seem to answer your original question. || An OP's self-answer, like yours here, is usually only appropriate if it is the full & final solution to their question. Otherwise OPs tend to write status updates, or commentary, or further questions (etc.) as an "answer", which aren't valid & real answers. || Is this the full & final solution? If so, please "accept" it to effectively close the question. If this isn't the solution, it shouldn't be here. Pls clarify. \$\endgroup\$2025年03月18日 23:34:09 +00:00Commented Mar 18 at 23:34
-
\$\begingroup\$ This isn't the right answer, but it points out the main problem more clearly \$\endgroup\$Spiros Andreopoulos– Spiros Andreopoulos2025年03月19日 15:10:26 +00:00Commented Mar 19 at 15:10
-
\$\begingroup\$ So, it should be an edit to your question and NOT an answer. \$\endgroup\$Mike– Mike2025年07月24日 08:25:58 +00:00Commented Jul 24 at 8:25
Explore related questions
See similar questions with these tags.