Hello Kinetis community.
Attached there is a guide on how to modify an existing KDS project to be loaded using the KBOOT Flash Resident bootloader.
Basically it explains 2 procedures:
1- Manipulating linker file to move application and vectors.
2- Adding data for the Bootloader Configuration Area (BCA).
I am also including 3 adapted KDS v3.0.0 example projects ready to be used with KBOOT Flash Resident bootloader in a FRDM-K22F:
- Baremetal project.
- KSDK project.
- KSDK project with Processor Expert support.
The application simply toggles the red, green and blue LEDs sequentially.
I hope you find the document and projects useful!
Regards!
Jorge Gonzalez
Jorge - thank you for this guide and examples!
Just a couple of notes about some issues that I ran into.
I created a KDS 3.0, KDSK, Processor Expert project from scratch and followed the instructions in the document: How to adapt KDS applications for KBOOT.pdf
Using the FRDM-K22F board.
After building the project the bootloader would load the application but it wouldn't run.
I then looked at the example project contained in: FRDMK22F_KDSK_PE.zip
The ProcessorExpert.ld linker file was different than what I came up with by following the guide.
After copying ProcessorExpert.ld from the example into my project - the application would run correctly after being loaded by the bootloader.
The main issue I think is the MEMORY area in ProcessorExpert.ld. The document shows this in section 3.2 KSDK + Processor Expert project, and I had originally copied it verbatim to my project:
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x0000A000, LENGTH = 0x000003C0
m_bca (RX) : ORIGIN = 0x0000A3C0, LENGTH = 0x00000040
m_text (RX) : ORIGIN = 0x0000A400, LENGTH = 0x00075C00
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00010000
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}
For comparison, the example project in the zip file used:
MEMORY {
m_interrupts (RX) : ORIGIN = 0x0000A000, LENGTH = 0x00000400
m_interrupts_ram (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00000400
m_bca (RX) : ORIGIN = 0x0000A3C0, LENGTH = 0x00000040
m_text (RX) : ORIGIN = 0x0000A400, LENGTH = 0x00075C00
m_data (RW) : ORIGIN = 0x1FFF0400, LENGTH = 0x0000FC00
m_data_2 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}
* Another issue in section 3.2 KSDK + Processor Expert project of the document
After editing the areas and ranges in Build Options -> Generate Linker File -> ROM/RAM Areas, a Generate Processor Expert Code should be performed so that ProcessorExpert.ld is updated with the new values. Then the Generate linker file checkbox should be unchecked.
Thanks again! =)
Jorge, first off thanks for putting this guide together, it is very helpful.
I did run into an issue though when I tried to do this for a K22 project in KDS 3.1 without KSDK - I do not have a startup<device>.s file in the project. I searched for all .s files in the project and there are none. After experimenting with KDS and KSDK, it seems that only KSDK projects contain that .s file. Do you know how to get around this without migrating the project to KSDK?
Thanks!
Hello Jacob Peery:
Most projects in KDS should have the startup assembly file, as it has the entry point of the application and the startup code to execute before reaching main. The exception to this are the projects with Processor Expert enabled but without KSDK. If this is your case then you are right, the assembly file is not present. I did not cover this kind of project in my document, but the steps are basically the same:
- Add offset for vector table and application.
- Remove the flash configuration data. For this you can comment out the definition of _cfm from the static file CPU_Init.c.
- Add BCA section placement to linker file and define the BCA values somewhere in your source files. You can take the previous definition of _cfm as example to do this.
I hope this helps. Let me find some time and I will update the document with this use case.
Regards!
Jorge Gonzalez
Hey Jorge,
I modified the linker file per your guide, then modified CPU_Init.c as recommended above and - drum roll - it works! Here's what I have in the linker file:
MEMORY {
m_interrupts (RX) : ORIGIN = 0x0000A000, LENGTH = 0x000003C0
m_bca (RX) : ORIGIN = 0x0000A3C0, LENGTH = 0x00000040
m_text (RX) : ORIGIN = 0x0000A400, LENGTH = 0x00075C00
m_data (RW) : ORIGIN = 0x1FFF0400, LENGTH = 0x0000FC00
m_data_20000000 (RW) : ORIGIN = 0x20000000, LENGTH = 0x00010000
m_interrupts_ram (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x00000400
//m_cfmprotrom (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}
..............................
.bca :
{
. = ALIGN(4);
KEEP(*(.bca)) /* Bootloader Configuration Area (BCA) */
. = ALIGN(4);
} > m_bca
I commented out everything related to cfm protect in the linker file per your guide.
Now in CPU_Init.c I have:
// REMOVED BY JAKE
//__attribute__ ((section (".cfmconfig"))) const uint8_t _cfm[0x10] = {CPU_FLASH_CONFIG_FIELD};
// ADDED BY JAKE
__attribute__ ((section (".bca"))) const uint8_t _bca[0x40] = {
'k', 'c', 'f', 'g', // header
0xFF, 0xFF, 0xFF, 0xFF, // crc start addr
0xFF, 0xFF, 0xFF, 0xFF, // crc byte count
0xFF, 0xFF, 0xFF, 0xFF, // crc expected val
0x10, // enabled periphs (USB only)
0xFF, // I2C slave addr
0x88, 0x13, // periph detect timeout (5 sec)
0xFF, 0xFF, // usb vid
0xFF, 0xFF, // usb pid
0xFF, 0xFF, 0xFF, 0xFF, // usb strings ptr
0xFF, // clk flags
0xFF, // clk divider
0xFF, // boot flags
0xFF, // reserved 1
0xFF, 0xFF, 0xFF, 0xFF, // mmcau config ptr
0xFF, 0xFF, 0xFF, 0xFF, // key blob ptr
0xFF, // reserved 2
0xFF, // can config 1
0xFF, 0xFF, // can config 2
0xFF, 0xFF, // can tx id
0xFF, 0xFF, // can rx id
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // end padding
};
Thanks for the help Jorge!
Hi Jorge,
Shouldn't I be able to load and debug the offset image with the debugger?
I followed the steps, and I can build the offset image, and I can build and run the bootloader.
Then I run the bootloader and plug into0 the USB, and run the kinetis updater app on my pc and load the offset image to the offset location.
This all works, but then when the bootloader resets and tries to jump to my offset image (which I checked that it was present with the memory browser),
the code locks up, and it looks like it is locking up in the system_init when it is fiddling with the MCG (clocks).
My offset image has the clocks set up differently using PE, because I have a 16Mhz crystal and my system runs at 96Mhz.
I also have tried to use the debugger to load and run the offset image, and that doesn't seem to work either (often getting hung in system_init).
Is there a way to load the symbols for both the bootloader and my loadable image so that I can debug them together?
Brynn
P.S. I haven't gotten back to the I2C example you made for me, but I looked at it and what you did was pretty much what I tried unsuccessfully before.
Hello Brynn:
This document might be helpful:
Debugging Bootloader and Application using Kinetis Design Studio
About the code lock up, I think the issue is that the bootloader configures clocks to use the USB module, while Processor Expert generated code assumes that the clock configuration is the default after reset (FEI mode with default MCG register values). This must be a KBOOT problem but I need time to investigate it. Right now the workaround would be to revert back to default clock configuration so the PE code can work as expected or commenting out the PE clock initialization and do it manually. Sorry for the inconvenience.
Regards!
Jorge Gonzalez
Tonkabot & Jorge_Gonzalez I have run into the same exact thing, locking up.
What I do is I will download and debug the freedom_bootloader project onto my board, then I "Stop debugging" and then I will download and debug my application, then start trying to make it fail. To do that, I will keep pushing the reset button on the FRDM-K22F board (while watching Device Manager) until it eventually leaves bootloader mode, but never enters my application. The green LED stays on as if its still in bootloader mode and the HID-compliant device disappears in device manager. In my application I toggle the green LED, so I know its not hitting my code.
When I enter this state, I click the "break" button in my application window to see what's getting executed. It turns out that while (kMcgFllSrcExternal != CLOCK_HAL_GetFllSrc(MCG)) {} is stuck when mcg_mode_error_t CLOCK_SYS_BootToPee(const mcg_config_t * config) is called in board.c (aka in BOARD_ClockInit() during call to CLOCK_SetBootConfig).
I put a breakpoint in crt0.s (which I copied exactly from led_demo.eww project) and notice it gets when SystemInit is trying to execute.
ldr r0,=SystemInit
blx r0
In SystemInit, the application executes this line and never returns until SystemInit gets called again: WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */
For reference, what I'm trying to do is use the USB Virtual COM baremetal IAR example project as a base for my user application.
Also:
1. In IAR, should I "Override default program entry" and set the "Entry symbol" to Reset_Handler, like it is in led_demo?
2. Should I be editing "K22FN512xxx12_application_0xA000.icf" from its defaults? I notice the CSTACK and HEAP are rather small (or 0) and since I'm using the baremetal OS, I think I might need to increase those sizes. In my application with the OS, I notice some very big differences in the .mapping file, like where .bss is located in my application vs. the led_demo application. Is this something to worry about? Here is my example. ".bss$$Base 0x1fff006c -- Gb - Linker created -"
3. If I "Generate additional output" to output a binary file, is this what I should use with blhost to flash the chip?
4. In bootloader.eww, I notice that in "memory_map_K22F512.c" the SRAM is defined as 0x1fff8000-0x2000ffff, is this correct?
5. In bootloader.eww, the preprocessor defined symbols for the C/C++ compiler and Assembler defines NDEBUG while in the active configuration is Debug. Should this instead be DEBUG, or should I be defining DEBUG in the bootloader_config.h file?
6. Are there any workarounds right now to avoid this lockup?
Lastly, I would be highly interested in seeing a more complex demo vs. just going off of led_demo.eww. More specifically, using the baremetal OS and including the additional header files so the linker has a more complex scenario and might better represent a typical usage. I don't want to sound greedy, but is that something you could provide us? If you would like to use my demo application I'm working with right now as a start, let me know how you'd like me to send it to you and I can do so.
Thanks, for asking this question and giving an answer quickly, I've been stuck on this for far too many hours!
Kevin
After loading both the bootloader and my app using the how to debug bootloader technique posted above,
I can see that it gets to my app and locks up on the following line in SystemInit(void) found in system_MK22F25612.c:
while((MCG->S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */
So we have proof that it can't change the clock like it wants to, as we guessed before.
But now that we know exactly where it is failing, it won't be that bad to fix it.
Kevin, I can answer your question #4 above: in the 512k part you are using you have a lower SRAM block at 0x1fff8000 to 0x1fffffff that is 32KB long, and an upper SRAM block from 0x20000000 to 0x2000ffff that is 32K long. They did it so code sees one contiguous chunk that runs through both blocks.
In my part, the 256k flash part has only 48KB SRAM, a lower SRAM block at 0x1fff8000 to 0x1fffffff that is 32KB long, , and an upper SRAM block from 0x20000000 to 0x20007fff that is 16K long.
Brynn
P.S. One time when I was debugging it actually made it past the while line above and ran my app correctly.
It looks to me like the bootloader is running in clock mode 'FEI' to start with, but I couldn't tell if it switches to a different mode to run the USB section which is the only bootloader method I have enabled.
My app looks like it runs in the 'PEE' clock mode, chosen because we have a 16Mhz crystal and want to use the USB, we run at 96Mz.
Is there a simple way to reset the MCG back into it's default reset state ('FEI' I presume) that I can poke into the SystemInit function prior to the existing code that sets it to 'PEE' ?
Tonkabot thanks for answering #4, makes sense now.
As for where your app is getting stuck, mine must be getting stuck at a different spot. In SystemInit, WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ is executed and it never returns. However, running the app from a clean download to the board, it doesn't hit the breakpoint on the line you indicated, so I'm guessing I don't have something #defined that you do.
If you have any luck in finding a fix, feel free to share! :smileyhappy:
My app uses KSDK 1.3 and processor expert. I imagine that could make for some differences if yours is not built with those tools.
Also, if I do a reset with the debugger, then poke the SP and PC with the correct addresses (sp=0x20008000 and pc= 0xa3c0 in my case) then if I run my app works perfectly.
When the bootloader sets up that sp and then jumps to my code (and it does get both those addresses correct) is when it locks up in the clock code.
I have an idea how to make mine work, and will try it if I get to it first:
have some custom code in the bootloaders reset handler (asm), or SystemInit function (C). It checks the reset source and RFVBAT.REG0 (which is a non-volatile register that does not change on reset or even loss of power, because it is powered by the VBAT pin which is always on in my system).
By storing a key value in that RFVBAT.REG0 I can than jump directly to my app code if it is right.
After a successful boot load the bootloader would store this key value, and then instead of trying to jump to the application it would just do a Reset ( NVIC_SystemReset(); )
Which restarts the bootloader, but this time it jumps directly to my app.
Keys might be
0x0 means run the bootloader
0xa000 means look at the vector table at 0xa000 and use the SP and PC as the starting SP and address to jump to
Johnson Controls is in Minnesota, right? So am I.
Tonkabot and Jorge_Gonzalez
I believe I found the problem, and it found in the CLOCK_SYS_BootToPee function inside fsl_clock_manager.c at this point in time:
// First prepare the external OSC clock.
CLOCK_HAL_PrepareOsc(MCG, oscsel);
// Set to FBE mode.
CLOCK_HAL_SetClksFrdivIrefs(MCG, kMcgClkOutSrcExternal,
config->frdiv,
kMcgFllSrcExternal);
while (kMcgFllSrcExternal != CLOCK_HAL_GetFllSrc(MCG)) {}
The lock up occurs because their is a synchronization issue, or IREFST in MCG_S is just not being updated. With a breakpoint set on CLOCK_HAL_SetClksFrdiveIrefs, you can see that MCG_C1_IREFS = 1 and MCG_S_IREFST = 1. When CLOCK_HAL_SetClksFrdiveIrefs is executed, it clears MCG_C1_IREFS (to 0) and in a working scenario, MCG_S_IREFST also gets cleared to 0 (MCG_S = 0x0A), and the user application runs as expected.
In the locking scenario, after CLOCK_HAL_SetClksFrdiveIrefs is executed, MCG_C1_IREFS is cleared (to 0), however MCG_S_IREFST does NOT get cleared (EVEN THOUGH MCG_C1_IREFS IS 0!), so MCG_S = 0x1A, and that is why it is locking up on while (kMcgFllSrcExternal != CLOCK_HAL_GetFllSrc(MCG)) {}.
In other words, my results show that the issue is hardware related (MCG_S_IREFST doesn't properly reflect MCG_C1_IREFS because of a synchronization error).
MCG_S_IREFST documentation states:
Internal Reference Status
This bit indicates the current source for the FLL reference clock. The IREFST bit does not update
immediately after a write to the IREFS bit due to internal synchronization between clock domains.
Jorge, KBOOT runs/boots in FEE, and when it exits, it puts itself back into FEI (see where clock_mode_switch gets called in clock_config_K22F512.c). After a reset and the user application is executed, at least in mine and what I assume PE generates, CLOCK_SYS_BootToPee is called which attempts to switch MCG modes from FEI, to FBE, to PBE, to PEE as documented in the BootToPee function in fsl_clock_manager.c. With this information, is there anyway we can force MCG_S_IREFST to update or help the internal synchronization between clock domains so it updates MCG_S_IREST?
I have solved the clock lock-up issue, mainly by working around it.
I have code at the beginning of the bootloader that looks to see what the reset source was.
If the reset source was a POR reset (RCM->SRS0 & 0x80) then I just jump to my application by loading the SP and PC from the vector table at the offset where my app is.
[I do need to add more error checking and CRC and stuff]
If the reset source was anything else (a PIN reset, meaning the reset pin caused it is most likely) it continues to run the bootloader.
These decisions are made before the clocks are changed, so no problem.
I can get away with this because my system has a reset generator chip like a cell phone, where if I hold the power button down for 7 seconds it pulls the reset line low.
Any shorter press of the power button just turns the power on (and reset source is a POR reset), or with software a press of 1-7 seconds tells the device to turn off.
Brynn
I jerry-rigged the led_demo project to recreate the issue. The (my) idea was to just add the KSDK 1.3.0 Platform code (for the FRDM-K22F) to the KBOOT package and call the default "hardware_init()" found in all of the KSDK examples. The issue is recreated recreated if you follow these steps with JLink OpenSDA V2.1 driver installed on FRDM-K22F development board:
1. Install KBOOT 1.2 package (mine was extracted to a directory named "FSL_Kinetis_Bootloader_1_2_0")
2. Open the IAR project, "%INSTALL_DIRECTORY\FSL_Kinetis_Bootloader_1_2_0\targets\MK22F51212\bootloader.eww"
3. Make the freedom_bootloader - Debug project the active project. (Right-click "freedom_bootloader - Debug" > Set as Active..)
4. Go to aforementioned project's options. (Highlight "freedom_bootloader - Debug" and press Alt + F7)
5. Change Debugger > Driver, to "J-Link/J-Trace" and click "OK"
6. Press Ctrl+D to Download & Debug the bootloader and press F5 to run the application when it breaks on main
7. You can now stop the debugging the bootloader by exiting IAR
Flash user application
1. Download source used here: http://www.filedropper.com/mk22f512122
2. Unzip the contents to a directory
3. Open "led_demo.eww"
4. Build the "ksdk_platform_lib" project
5. Build the "led_demo_FRDM-K22F" project (note that the linker file used is in the same location as the led_demo.eww file, which uses places application at offset 0xA000)
6. Make sure "led_demo_FRDM-K22F" is the active project
7. Download & Debug the application, press F5 to run the application after it breaks on main()
8. At this point the RGB LED should be changing, just like it does in the normal led_demo (except blinking at a faster rate). Don't stop the debugging at this point, continue below.
Make it happen
1. Now, press the "Reset" button on the FRDM-K22F board
2. Wait ~5 seconds (bootloader is waiting for peripheral activity)
3. If the user application ends up running, the debugger will break on main(). Press F5 to continue running. Then repeat step 1 & 2 until you get the symptoms found below.
4. If the user application doesn't appear to be running, break via the debugger and observe where it is stuck--it will loop forever at this point, assuming it goes untouched.
5. If the clock is stuck, repeating the steps beginnging at step 1 may or may not fix the issue. It is a shot in the dark as to whether it will get stuck or not. I have tried this on two FRDM-K22F boards and Board 1 gets stuck anyways between 50%-75& of the time, and Board 2 gets stuck about 10% of the time.
Let me know if there are any additional questions or the source doesn't build.
Kevin
I was able to replicate the behavior reported using KBOOT 1.2 to program the led_demo. The led_dmeo hangs at the following line in fsl_clock manager.c when attempting to transition from FEI to PEE:
while (kMcgFllSrcExternal != CLOCK_HAL_GetFllSrc(MCG)) {}
The processor is the waiting for the MCG_S_IREFST bit to clear to indicate the external reference to the FLL is selected.
After looking into the v1.2 bootloader source code, we have identified a sequence in the freedom_bootloader project that is causing this problem. The issue occurs when transitioning from FEE to FEI in the function clock_mode_switch() in clock_config_K22F512.c.
There is an errata for the MCG (e7735) that indicates when switching from FEE to FEI, the IREFST bit will set before the clock mux switches. In the bootloader code the external reference clock (48 MHz IRC) is disabled a few instructions after polling for IREFST = 1. However, the errata suggests waiting for a delay of 2 cycles of the slow IRC + 2 cycles of OSCERCLK after MCG_S[IREFST] has been set to 1. Adding the suggested delay after polling for IREFST = 1 will give time for the FLL reference mux to switch to the internal reference clock (slow irc) before disabling the external reference clock (48 MHz IRC). I confirmed that adding this delay allows the led_demo to run properly.
We are working to update this in the bootloader source code.
This is the solved my issue, thank you Bryan.
This issue exists in KBOOT v2.0 as well. For those wanting to fix the issue, in the clock_mode_switch() in clock_config_K22F512.c file, I added this (in KBOOT v.1.2):
while (!MCG_BRD_S_IREFST(MCG)); // Wait until internal reference clock is ready.
int dummy_var = 0;
for(int i = 0; i < 10000; i++)
{
dummy_var = MCG_S;
}
// This is required due to ERR007993
MCG_CLR_C4(MCG, MCG_C4_DMX32_MASK);
bryancole-b46824 I also reported on some other potential typo/issues in a supplementary post: Clock synchronization issue with KBOOT bootloader and MCG mode switching with FRDM-K22F . Are you able to tell if the findings reported there (RE: max flexbus clock speed and clock dividers) should be changed or addressed?
Hello Kevin,
We have also ran into this issue. I was curious with your fix did you put this at the top of clock_mode_switch to be the first check or was this embedded in one of the checks for the expected mode?
Frank
Never mind was simple enough...
Frank
With the possibility of winning the topic digger prize, I'm bringing this topic back to life.
I'm currently studying the Kinetis bootloader and I ran into a problem regarding the Strings in the USB communication.
The board is a FRDM-KL27Z, bootloader is the ROM one
My problem is that the strings are not recognized by windows (the device name is just a '?'). If I left it default (usbStringsPointer == 0xFFFFFFFF), the device name is correctly shown ("Kinetis Bootloader").
I'm configuring the BCA as follows:
__attribute__((section(".bca"))) const bootloader_config_t BootloaderConfig =
{
.tag = 0x6766636B, //!< Magic Number - "kcfg"
.crcStartAddress = 0xFFFFFFFF, //!< Disable CRC check
.crcByteCount = 0xFFFFFFFF, //!< Disable CRC check
.crcExpectedValue = 0xFFFFFFFF, //!< Disable CRC check
.enabledPeripherals = 0xF0, //!< USB HID
.i2cSlaveAddress = 0xFF, //!< Use default I2C address(0x10)
.peripheralDetectionTimeoutMs = 3000, //!< Use user-defined timeout(ms)
.usbVid = 0x2504, //!< Use default Vendor ID(0x15A2)
.usbPid = 0x0303, //!< Use default Product ID(0x0073)
.usbStringsPointer = (uint32_t)&g_language_list, //!< Use default USB String
.clockFlags = 0xFF, //!< 0 bit cleared: Enable High speed mode. NOTE: Enabling high speed mode makes UART connection worse or requires pull-up on Rx line!
.clockDivider = 0xFF, //!< Use clock divider(0)
};
Descriptors:
/* Define string descriptor size */
uint32_t g_string_desc_size[USB_STRING_COUNT + 1] = { sizeof(g_usb_str_0), sizeof(g_usb_str_1), sizeof(g_usb_str_2),
sizeof(g_usb_str_3), sizeof(g_usb_str_n) };uint8_t *g_string_descriptors[USB_STRING_COUNT + 1] = { g_usb_str_0, g_usb_str_1, g_usb_str_2, g_usb_str_3,
g_usb_str_n };usb_language_t g_usb_lang[USB_LANGUAGE_COUNT] = { {
g_string_descriptors, g_string_desc_size, (uint16_t)0x0409,
} };usb_language_list_t g_language_list = {
g_usb_str_0, sizeof(g_usb_str_0), g_usb_lang, USB_LANGUAGE_COUNT,
};
And g_usb_str_0 and g_usb_str_* as follows:
uint8_t g_usb_str_0[USB_STRING_DESCRIPTOR_0_LENGTH + USB_STRING_DESCRIPTOR_HEADER_LENGTH] = {
sizeof(g_usb_str_0), USB_DESCRIPTOR_TYPE_STRING, 0x09, 0x04
};uint8_t g_usb_str_n[USB_STRING_DESCRIPTOR_ERROR_LENGTH + USB_STRING_DESCRIPTOR_HEADER_LENGTH] = {
sizeof(g_usb_str_n),
USB_DESCRIPTOR_TYPE_STRING,
'B', 0,
'A', 0,
'D', 0,
' ', 0,
'S', 0,
'T', 0,
'R', 0,
'I', 0,
'N', 0,
'G', 0
};
Any ideas?
Jorge:
In your excellent document "How to adapt KDS applications for KBOOT bootloader", you recommend deleting the m_flash_config memory area.
If your application was ever NOT to be loaded via a bootloader, e.g. via a JTAG programmer, it seems that you might want to keep the m_flash_config section -- is that true? Or my thinking muddled about how m_flash_config is interpreted?
Jorge,
I'm working with the bootloader and I've created an application with procesor expert. I have a problem when I used the PEE mode with external cristal for clock configuration.
If I don´t use the bootloader my application start always correct, but when I use the KBOOT (version 2.0.0) my application does not always start well. Sometimes it starts well but sometimes it does not start.
Hello Angel,
You might be running into the same clocking issue discussed above due to a silicon errata. Please give a check to the explanation provided by Bryan Cole and the fix suggested by Kevin Luty in their latest comments.
Regards!
Jorge Gonzalez
I highly suggest you take a close look at the clock initialization code.
From my experience, such automatically generated code assume that the registers are at the reset state, which is not always true, specially when you have a bootloader that runs before the application.
The code generated by the clock generation tool under MCU Xpresso (Welcome to MCUXpresso | MCUXpresso Config Tools) usually works for me.
This thread (and several others) beg a larger question: has anyone written a software routine that makes best effort to return the chip to its reset state? Of course, there would be one variant per chip architecture, but this would be a generally useful tool, especially for apps that expect to be launched from the bootloader.
An even better alternative would be to make sure the bootloader completely cleans up after itself, leaving the chip in "as close to reset as possible" state. I know that's not possible for ROM based bootloaders since the code is already baked in, but for flash-resident bootloaders, this would be a worthwhile improvement.
Or are there complexities that I'm overlooking?
I agree with you, that the bootloader should make as easy as possible porting an application to use it, but, I believe more important is to have drivers (SDK) that don't rely on the reset state of the microcontroller. If during the application, one intends to use the same peripheral for two different purposes, with two different configurations, the initialization code should be robust enough and at least check if the peripheral is already initialized. I had this problem with one of the timers (PTM, if I recall) which was being initialized "twice" (one by the bootloader and one by my application).
Bruno:
I completely agree with you that drivers should not rely on the reset state of the microcontroller.
Usually, when your app starts up, you know that the system has just (re)started. The bootloader is a special case in that it leaves the hardware in an unknown state -- and it doesn't document that state -- so the burden is now on your app to put each and every module back into a known state, even if your app doesn't use that module.
So therefore each driver should provide a means to return to the reset state -- or at least a predictable state -- which they currently lack. For your PTM case, there should be a CLOCK_reset() method.
And once you have this, since it would be irksome to have to call { ADC16_reset(), CLOCK_reset(), CMP_reset(), COP_reset() ... UART_reset() }, wouldn't it be great to have a single SYSTEM_reset() method that calls all of them?