I am trying to understand the optiboot code for the arduino located here:
arduino/hardware/arduino/avr/bootloaders/optiboot/optiboot.c
I have been able to figure out most of it (this was helpful) but am having problems with the following. The most helpful would be source documents so I can answer these questions for myself in the future. Can you help me with the following?
asm(" .section .version\n"
"optiboot_version: .word " MAKEVER(OPTIBOOT_MAJVER, OPTIBOOT_MINVER) "\n"
" .section .text\n");
Where is the ".section" command documented? Where is ".version" located? I expected the data sheet to answer the first question and this to answer the 2nd but no dice.
#define rstVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+4))
#define wdtVect (*(uint16_t*)(RAMSTART+SPM_PAGESIZE*2+6))
where are SPM_PAGESIZE, VIRTUAL_BOOT_PARTITION, and SOFT_UART defined? Why do these lines of code use an offset?
void appStart() {
watchdogConfig(WATCHDOG_OFF);
__asm__ __volatile__ (
#ifdef VIRTUAL_BOOT_PARTITION
// Jump to WDT vector
"ldi r30,4\n"
"clr r31\n"
#else
// Jump to RST vector
"clr r30\n"
"clr r31\n"
#endif
"ijmp\n"
);
I understand that this is loading the Z-register and jumping to the address stored in it. I further understand jumping to the RST vector. However, what is a VIRTUAL_BOOT_PARTITION? Where is it defined?
UBRR0L = (uint8_t)( (F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1 );
From the equation listed in table 20-1 here, I would have thought the equation should be:
UBRR0L = (uint8_t)( (F_CPU) / (BAUD_RATE * 8L) - 1 );
Why is there an extra BAUD_RATE * 4L there? Why is it using 4L and 8L rather than just 4 and 8?
if(ch == STK_GET_PARAMETER) {
unsigned char which = getch();
verifySpace();
if (which == 0x82) {
// Send optiboot version as "minor SW version"
putch(OPTIBOOT_MINVER);
} else if (which == 0x81) {
//0x81 - major version
putch(OPTIBOOT_MAJVER);
} else {
/*
* GET PARAMETER returns a generic 0x03 reply for
* other parameters - enough to keep Avrdude happy
*/
putch(0x03);
}
}
Where is 0x03 defined? The comments indicate it is a "do nothing" response, but how would I know that? I am looking here but perhaps there is another source.
if(ch == STK_LOAD_ADDRESS) {
// LOAD ADDRESS
uint16_t newAddress;
newAddress = getch();
newAddress = (newAddress & 0xff) | (getch() << 8);
#ifdef RAMPZ
// Transfer top bit to RAMPZ
// note: RAMPZ is only defined for devices with > 64K of memory
RAMPZ = (newAddress & 0x8000) ? 1 : 0;
#endif
newAddress += newAddress; // Convert from word address to byte address
address = newAddress;
verifySpace();
}
what is RAMPZ? what is being done in the "newAddress += newAddress" line? The comment does not give me much understanding.
// Copy buffer into programming buffer
bufPtr = buff;
addrPtr = (uint16_t)(void*)address;
ch = SPM_PAGESIZE / 2;
do {
uint16_t a;
a = *bufPtr++;
a |= (*bufPtr++) << 8;
__boot_page_fill_short((uint16_t)(void*)addrPtr,a);
addrPtr += 2;
} while (--ch);
// Write from programming buffer
__boot_page_write_short((uint16_t)(void*)address);
boot_spm_busy_wait();
It looks like this code is writing pages twice. What is the difference between "__boot_page_fill_short" and "__boot_page_write_short"? I took a look here but didn't see the distinction.
Thanks!