MKW30Z OTAP demo gUseBootloaderLink_d=1 issue

Showing results for 
Search instead for 
Did you mean: 

MKW30Z OTAP demo gUseBootloaderLink_d=1 issue

Contributor V
IAR 7.50;  KW40Z_Connectivity_Software_1.0.1 (KSDK_1.3.0)
The issue is generated when gUseBootloaderLink_d=1 is present in Linker section.
The leds don't flash; callback functions on timers are not executed (on LED.c LED_FlashTimeout not triggered).
The advertising works, but no BT connection is possible (BleApp_ConnectionCallback is not triggered)
When that setting is removed - timers works,callbacks work, leds flash as they should,
but no chip update at end of file upload.
Inline image
I can connect to Kinetis BLE Toolbox - OTAP, I can upload a file to the MKW30Z.
Te phone confirms transfer complete.
Inline image
The code exit clean via ResetMCU (breakpoint on it), but that's all, the MKW30Z is not updated with new image !
(either bootloader does not kick in or  OTA_SetNewImageFlag does not work properly, or ...)
static void OtapClient_ContinueImageDownload (deviceId_t deviceId)
    case mOtapClientStateImageDownloadComplete_c:
        /*! If the image download is complete try to set the new image flag
         *  and reset the MCU for the bootloader ot kick in. */
        Gap_Disconnect (deviceId);
        OTA_SetNewImageFlag ();
        ResetMCU ();
Tags (1)
0 Kudos
2 Replies

Contributor V

some updates

it is very likely that the Flash Config registers are overwritten by bootloader bin own set-up.


if (gUseBootloaderLink_d)
  define symbol m_bootloader_start       = __region_ROM_start__;
  define symbol m_bootloader_end         = ((__region_ROM_end__ + 1) / 32) - 1;

  define symbol m_interrupts_start       = m_bootloader_end + 1;
  define symbol m_interrupts_end         = m_interrupts_start + __vector_table_size__ - 1;

  define symbol m_bootFlags_start        = m_interrupts_end + 1;
  define symbol m_bootFlags_end          = m_bootFlags_start + 7;

  define exported symbol __BootFlags_Start__ = m_bootFlags_start;
  define symbol m_interrupts_start       = __region_ROM_start__;
  define symbol m_interrupts_end         = m_interrupts_start + __vector_table_size__ - 1;
  define symbol m_flash_config_start     = 0x00000400;
  define symbol m_flash_config_end       = 0x0000040F;



        SECTION FlashConfig:CODE
          DCD    0xFFFFFFFF
          DCD    0xFFFFFFFF
          DCD    0xFFFFFFFF
          DCD    0xFFFFFBFE    ;0xFFFFFFFE
        B .

        PUBWEAK HardFault_Handler

the booloader has a build-in set of flash config's:


define symbol __size_cstack__ = 0x1000;
define symbol __IntVectTable_start__ = __region_BOOT_ROM_start__;
define symbol __IntVectTable_end__   = __region_BOOT_ROM_start__ + 0x3F;
define symbol __FlashConfig_start__   = 0x00000400;
define symbol __FlashConfig_end__     = 0x0000040f;
define exported symbol __BOOT_STACK_ADDRESS = __region_RAM_end__ - 7;    //0x20007FF8;
define symbol __code_start__          = __IntVectTable_end__+1;

from Linker set-up: gRomSize_c=0x28000


Bootloader ROM map seems to be:


(a strange thing is that bootloader table vectors are less than main application 63 vs 192)


 * Name: gFlashProtection_c
 * Description: The value for FPROT register. By default the Flash is not Protected
#define gFlashProtection_c 0xFFFFFFFF /* Flash is not write protected */
// #define gFlashProtection_c 0xFFFFFFFE /* The first Flash region is write protected */
#if defined(__IAR_SYSTEMS_ICC__)
#pragma location = "FlashConfig"
__root const FlashConfig_t gFlashConfig @ "FlashConfig" =


MKW40Z/30Z/20Z Reference Manual, Rev. 1.2, 10/2015

6.3.2 FOPT boot options
The Flash Option (FOPT) register in the Flash Memory module (FTFA_FOPT) allows the user to customize the operation of the MCU at boot time.

The register contains readonly bits that are loaded from the NVM's option byte in the flash configuration field. The default setting for all values in the FTFA_FOPT register is logic 1 since it is copied from the option byte residing in flash, which has all bits as logic 1 in the flash erased state. To
configure for alternate settings, program the appropriate bits in the NVM option byte. The new settings will take effect on subsequent POR, VLLSx recoveries, and any system reset.     

6.3.3 Boot sequence
When the system exits reset, the processor sets up the stack, program counter (PC), and link register (LR). The processor reads the start SP (SP_main) from vector-table offset 0. The core reads the start PC from vector-table offset 4. LR is set to 0xFFFF_FFFF. The next sequence of events depends on the NMI input and FTFA_FOPT[NMI_DIS] (See Table 6-2) :
• If the NMI input is high or the NMI function is disabled in FTFA_FOPT, the CPU begins execution at the PC location.
• If the NMI input is low and the NMI function is enabled in FTFA_FOPT, this results in an NMI interrupt. The processor executes an Exception Entry and
reads the NMI interrupt handler address from vector-table offset 8. The CPU begins execution at the NMI interrupt handler.


27.3.1 Flash Configuration Field Description
The program flash memory contains a 16-byte flash configuration field that stores default protection settings (loaded on reset) and security information that allows the MCU to restrict access to the flash memory module.

As in main application you wold like to disable the NMI interrupt by setting  NMI_DIS to 0 the bootloader must be rebuild with the flash zone updated corresponding to application. Or the linker application mechanism updated to not permit the change of flash config.

0 Kudos

Contributor V

second issue is that the new srec image must have a compliant format, it must contain at least a special flash zone between 0x000014C0 to 0x000014C7 used to interact between app and bootloader


(bootloader struct gpBootInfo  points as same address as app gBootFlags and has same format)


/*! *********************************************************************************

* \brief   This function will copy the User Application from the external memory
*          into the program Flash
********************************************************************************** */
void Boot_LoadImage (void)


                    /* Keep the boot flags set  until the all image is downloaded */
                    for( i=0; i<gEepromParams_WriteAlignment_c; i++ )
                        flags.newBootImageAvailable[i] = gBootValueForFALSE_c;
                        flags.bootProcessCompleted[i] = gBootValueForTRUE_c;


    /* Set the bBootProcessCompleted Flag */
    if( FLASH_OK != FLASH_Program((uint32_t)gBootImageFlagsAddress_c, (uint32_t)&flags, sizeof(flags)) )




int main(int argc, char **argv)


   gpBootInfo = (bootInfo_t*)gBootImageFlagsAddress_c;

    if ((gpBootInfo->newBootImageAvailable[0] != gBootValueForTRUE_c) &&
        (gpBootInfo->bootProcessCompleted[0] ==  gBootValueForTRUE_c))
        /* Set the start address of the interrupt vector*/
        SCB_VTOR = gUserFlashStart_d;
        /* Write the new image */


Also some concerns my raise:

- if new image have not the expected structure it can be spoiled by Boot_LoadImage in this ROM zone 0x000014C0 to 0x000014C7 (same as for bootloader zone)

- actual only one flag is absolute necessary flags.newBootImageAvailable ( the other one bootProcessCompleted can be used for debug)

- as the flash erase process starts, it should first erase these particular flag zones in case of accidental reset occurs.

0 Kudos