1.12 Application Design Considerations
In an ideal world, the development of the application code could be done with no considerations of how the bootloader works, and for most issues the two can be developed independently. However, since they co-exist on the same chip and the bootloader is setup before the application, there are dependencies between the two. The key areas where the interaction cannot be avoided is the configuration of shared peripherals, memory map, interrupts, and other areas.
- Shared Resources
-
The configuration of shared resources is one of the main issues that need to be dealt with. For instance, consider what happens if both the bootloader and application both use the UART but they use it in different modes. During the development of the application the application firmware would have always configured the UART from the reset state since they were not using the bootloader and hence, they only had to modify the UART registers based on the initial system reset values. However, if the bootloader configures the UART while it's running and before jumping to the application code, the UART will no longer have the same initial value that it did without the bootloader and if these differences are not dealt with, the application's use of the UART could fail at this point. So for the shared resource, the application code needs to be aware of how the bootloader is using the peripheral and the settings the bootloader used and the effect of those settings on the application usage.
- Interrupts
-
While interrupts between the bootloader and application are not "shared", since the application interrupt vector does reside in the bootloader flash address space, the user needs to work with the bootloader owner to make sure all the interrupts are forwarded to the application using the correct methodology.
- Configuration Bits
-
It's very important that the configuration bits must be the same between the bootloader and application. It's so important that application configuration bits match the bootloader's configuration bits that when MCC pulls in the configuration of the bootloader, it verifies that they are the same and if they are not, MCC will display the differences. The reason for this is straight forward. The configuration bits are only read at device reset prior to running the bootloader firmware. Some of these configuration bits will control clocks and other device characteristics. If these do not match the application settings, the application my be expecting a specific clock and if the bootloader has a different setting, the application code will fail.
- Shutting Off Boot Peripherals
-
If the bootloader enabled any interrupts or peripherals then they should be disabled before branching to the application code. For instance, if the bootloader code enabled the Timer and Timer Interrupt. If these are not enabled prior running the application code, they can cause unexpected Timer Interrupts in the application code leading to system crashes and unexpected events. One common failure mode is a device reset. Since there may be no interrupt handler for this interrupt in the application, a device reset could occur. Upon device reset, the bootloader will then run again, it will enable these interrupts and verify the application code. The application code will run again with the Timer interrupt enabled and cause the sequence to repeat continually. Likewise, if the UART was configured in the bootloader and not disabled prior to running the application, random noise on the wires or unexpected baud rate changes could cause the UART to see phantom data or frame errors leaving the UART in an unexpected state when the application takes control of the UART
Other considerations closely match/mirror the bootloader considerations covered in Bootloader Development Considerations