Suppose I have an assembled and linked .hex file that was built for a Tiny2313. Somehow, I need to get the raw bytes represented by that .hex file into a Mega162 as byte constants that can be read by the Mega162 so the Mega162 can send it to a bootloader running on Tiny2313 chips connected to the Mega162:
ldi XH, high(flashcode) ldi XL, low(flashcode) // ... add some whole multiple of 32 // ... and read 32 bytes for broadcasting to eager, waiting bootloader: ld r16, X+ rcall sendByteToWaitingBootloader // etc // the next line basically shows what I want to do, though obviously not the right way to do it... .cseg .org 0x400 ; just an example flashcode: .db #include "newcodeforslaves.hex"
How can I do it?
Remember, I don't want to literally load the ascii values for each character in the .hex file... I want to load the bytes represented by them. If, say, the .hex file represented 2000 bytes, and flashcode: points at flash memory location 0x400 in the Mega162, I'd want the first byte at 0x400, the second at 0x401, etc... all the way to the end. Assuming, of course, that there aren't any other hidden problems waiting to bite me.
Background Info on the bootloader scheme I came up with (not strictly necessary to answer the problem above):
A mega162 controller's TXD pin is connected to the RXD pins of 50 Tiny2313 slaves at roughly 1 foot intervals.
At reset, the Tiny2313s wait up to 1 second for something (presumably the controller) to pull and hold the bus low for at least 1/10 of a second. If nothing pulls the bus low, they go into "headless" mode and assume there's no controller. At that point, they look for a signature at the end of .cseg indicating that code to handle that scenario exists, and do an rjmp to 0x302 if it does (where, presumably, there's another rjmp leading to that code). Otherwise, they go into "zombie" mode (headless and stupid, they nevertheless try to output random colors to four RGB leds).
If the bus is pulled low for at least 1/10 second, but less than 3 seconds, the slaves do an rjmp to 0x300, where there's presumably another rjmp to the main event loop's entry point which enables their USARTs and waits for normal operating commands from the controller (this is the normal case).
If the bus stays low for more than 10 seconds, they assume any code outside the safe core is corrupt and go straight into zombie mode.
If the bus is held low for more than 3 seconds, but less than 10 seconds, the slaves enter bootloader mode and prepare to reflash themselves. The basic sequence is this:
* multi-processor mode is set for the USART.
* the master sends 0x69 flagged as an address. The slaves see it and clear MPCM.
* the master sends a byte representing the page to be reflashed twice. If the two bytes differ, the slave turns the LEDs red and aborts the whole thing.
* the master sends 32 bytes, representing data from a .hex file some whole multiple of 32 from the reset vector at 0x0000. They're buffered in the first 32 bytes of the slave's sram.
* the master sends another 32 bytes, presumably representing the same data. They're buffered in the second 32 bytes of the slave's sram.
* the master sends the crc32 twice, pauses, deactivates its USART, turns the pin into an input, pauses, then waits for the bus to go high.
* Meanwhile, the slaves deactivate their USART, turn their pin into an output, and pull it low to indicate that they're busy. They proceed to verify that both new pages are identical and match the crc32, then compare them to the existing page. If there's no difference, they turn the LEDs green, turn their pins into inputs, and wait for the bus to go high. Otherwise, they rewrite the page and verify it (retrying up to 3 times if they fail).
* When the bus goes high, the master and slaves all re-enable their USARTs. The master sends 0xc5 ("need another try?"), the page offset (twice), the crc32 (twice), then disables the usart and watches the bus for 2 seconds to see whether anyone pulls it low. The slaves that reflashed successfully (or didn't need to reflash) just set multiple CPU mode so they can ignore the next round of broadcasts, sit there and wait. Slaves that couldn't reflash due to a data error disable the usart, pull the bus low for 1 second, then re-enable their usarts, whereupon the pages and crcs are resent, and everything continues as before. I haven't really decided how many times I want to retry before either aborting the whole reflash or skipping ahead to the next page anyway.