4
\$\begingroup\$

I am working on a project in which I want to include the functionality of reprogramming the main microcontroller via wireless transmission.

First, I have figured there needs to be a dedicated microcontroller programmed to facilitate this function, but how exactly would it need to be implemented?

Assuming the code is already compiled before transmission, would the code need to be stored in any specific way prior to being read and used to program the main controller?

Also, what exactly is the process required to facilitate the actual programming of the controller?

\$\endgroup\$
  • 3
    \$\begingroup\$ You might like to look into bootloaders, e.g. this tutorial and see if they would help. \$\endgroup\$ – David Nov 3 '13 at 22:01
  • 1
    \$\begingroup\$ Some microcontrollers need relatively simple, low voltage programming, and can be done in circuit. Some need high voltage programming on a dedicated programmer. Anything you decide to do depends on the exactly programming protocol. The Atmel AVRs can often be programmed with a simple spi like protocol for one. \$\endgroup\$ – Passerby Nov 4 '13 at 1:40
3
\$\begingroup\$

Some controllers can write to their own program flash under software control; others cannot. If you need to use a secondary processor to program the primary one, it's really not much different from any other task that requires willing certain pins in certain sequences with certain timing constraints. The one biggest thing to look for is that some parts can be programmed in a variety of ways, some of which may be much faster than others. If the part to be programmed can write to parts of its own flash under software control but can't do everything and thus requires the use of a secondary processor, it may sometimes be fastest to have the secondary processor program the primary one with just enough of a boot loader to receive its code via some other means (such as a UART) than to use the in-circuit programming mode for everything.

\$\endgroup\$
2
\$\begingroup\$

I recently did a similar project, except that the update was over UART instead of wireless. Everything was in one microcontroller, a Silicon Labs SiM3C166. The on-board flash was logically segmented into 3 sections, the boot loader, the active application and the pending application (there was actually a 4th, small section containing a hash of the pending application, to verify that it had been loaded correctly).

The application code included code to receive the new image and write it into the "pending" section. Once the entire image was loaded and verified against the hash, the code did a soft reset. This starts the bootloader, which is located at address 0.

The function of the bootloader is simple to verify the pending application against its hash and compare it against the existing application. If the hash is valid and the new image is different then the old one, it copies the new application over the old one and then erases the hash.

Finally, regardless of if the application was copied or not, it transferred control to the current application. (This consisted of relocating the interrupt vector block to the application space and branching to the first word of the application.)

Things to note: the application had to be linked to be located at an address other than 0, specifically to the base of the "active" section of flash. This included moving the interrupt vectors. The ARM M3 processor has a system register that points at the interrot vector table and this was used to switch from the boot loader vectors to the application vectors.

Once the application code is running, the boot loader code is not used again until the processor resets.

Hopefully, this will give you an idea of what can be done.

\$\endgroup\$
1
\$\begingroup\$

What chip are you using? I wrote a bootloader for the Atmel ATMEGA and XMEGA chips that supports a user level API for updating the firmware on the chip via an arbitrary protocol. The bootloader is called xboot and it is available on github. Basically, the user application can download the code however it likes. It passes it block by block to xboot, which writes it to the upper half of flash memory. Once it is done, it passes xboot the 'golden' CRC of the new firmware and resets. xboot will then verify the CRC and, if it matches, copy the firmware over the lower half of flash memory. Then it jumps into the reset vector in the lower half of flash memory to start the program. Only downside: your program has to be less than half of the size of flash memory. Also, the boot block needs to be big enough to hold xboot. So it should work on the -328 atmega on the Arduino, but it is too big for the -168.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.