Modifying KBOOT1.2 to program an image from external SPI FLASH

cancel
Showing results for 
Search instead for 
Did you mean: 

Modifying KBOOT1.2 to program an image from external SPI FLASH

1,394 Views
F50SC
Contributor III

Hi All

I have application that requires FOTA updates, and currently uses the below software components....

KBOOT 1.2
KSDK 1.3 
MQX V5 RTOS

KDS3.2

all running on MK22FX512A MCU.

What I'm now up to, is modifying the bootloader to program a firmware image from external flash using DSPI peripheral.

I believe this should be possible, but isn't built-in functionality.

Currently this is what I think I know and or have discovered about the bootloader.

1. KBOOT1.2 has DSPI low-level driver, as this is one of the active peripherals supported for executing bootloader protocol.

2. The bootloader is designed to accept commands over a peripheral to execute the flash functions required to erase, read, write to internal FLASH, my application WILL NOT BE doing this, I simply wish to read out my image from external FLASH and write directly into the MCUs flash memory.
3. Can the bootloader write to internal flash while executing code, or is relocating to RAM while executing? Is this something I need to be concerned about or is it already taken care of by the bootloader.
4. I think I may have to create some pseduo-dspi driver, that will mimic the commands it would normally receive over the

peripheral and have some internal state machine, manage the erase,verify,write commands to the upper layers of the bootloader. There may be some overhead in doing it this way, but at least the bootloader isn't hacked to pieces to make it do what I want, I can keep it modular, and seperate to the other bootloader source??

5. I'm currently using the bootloader via custom desktop application to flash over USB. So I still need to maintain this functionality, with whatever solution I come up with.

6. As part of the debugging process, I absolutely need printfs working to a serial port, this currently is not enabled / does not work in KBOOT1.2. They're are some references to debug_printf but no code behind, seems it may have been removed from the source before being released, possibly to keep a low memory footprint?

That's all for now, I'll keep this post updated.

Any help would be appreciated!

11 Replies

924 Views
mjbcswitzerland
Specialist V


Hi Jerome

You can get the features that you need from the open source uTasker project on GitHub or by using its supported professional version.

1. Its "Bare-minimum" loader supports updating code (authenticated and optionally encrypted) from SPI Flash via DPSI (included drivers are for Atmel AT45D types, Macronix MX25L,  Spansion S25FL1-k, SST25, ST-Micro STM25P, Winbin W25Q) - http://www.utasker.com/docs/uTasker/uTasker_BM_Loader.pdf
This can be used to update a secondary loader and/or application.

2. If you find restrictions with using the KBOOT1.2 as secondary loader you can use the uTasker "KBOOT1.2 compatible loader" which is compatible on USB and/or UART but has more features (it can be used together with various other loading techniques and has debug message support on UART and/or USB without the usual high overhead which the standard libraries generate - plus has strong AES256 encryption option beyond the standard Kboot1.2 capabilities)
http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf
Video showing addition encryption: https://www.youtube.com/watch?v=MXsJvTdCcH4

The configuration that you need consumes about 16k of Flash on the K22 (for primary and secondary loaders with KBoot1.2 USB compatibility and debug output on UART and/or USB). It builds using KDS3.2 and has been used in various industrial MQX based products (although the application itself is not really relevant).

Regards

Mark

Complete Kinetis solutions, training and support: http://www.utasker.com/kinetis.html
Kinetis K22:
- http://www.utasker.com/kinetis/FRDM-K22F.html
- http://www.utasker.com/kinetis/TWR-K22F120M.html
- http://www.utasker.com/kinetis/BLAZE_K22.html
- http://www.utasker.com/kinetis/tinyK22.html

924 Views
F50SC
Contributor III

Hi Mark 

Thanks so much for your reply and recommendation on uTasker.

I'm following your video on how to build in KDS here uTasker SHORT Getting Started - From GIT to KDS build - YouTube , but I'm getting an error
to do with STM32_ports.cpp file, No such file or directory when locating config.h.

This doesn't seem correct to compile STM source files as part of the build for Kinetis.

Any ideas, another configuration somewhere in the project settings or in the config file?

pastedImage_3.png

UPDATE SOLVED! I excluded STM folder from the project build.

pastedImage_6.png
And now I have...
pastedImage_7.png

0 Kudos

924 Views
mjbcswitzerland
Specialist V

Jerome

It is correct to exclude the STM32 directory - that is a bit of nuisance with KDS (and co.) because if one adds new files to the framwork every project sharing the framework then includes them as default. Although I updated the KDS projects I may have missed excluding something but, as you have seen, it is simple to fix: I'll update the KDS project asap.

Regards

Mark

924 Views
F50SC
Contributor III

Hi Mark

I've hit a bit of snag, it seems the MCU clock is not setup correctly for my target and is not getting past the below line (kinetis.c) in the debugger...

while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTERN_CLK) {       // wait until the new source is valid (move to FBI using IRC48M external source is complete)

These are my settings for


config.h

#define MY_HARDWARE_K22FX

#elif defined MY_HARDWARE_K22FX

#define TARGET_HW "K22FX512A-120M"
#define KINETIS_K_FPU // part with floating point unit
#define KINETIS_MAX_SPEED 120000000
#define KINETIS_K20 // specify the sub-family
#define KINETIS_K22 // extra sub-family type precision
#define KINETIS_REVISION_2
#define DEVICE_WITHOUT_ETHERNET // K20 doesn't have Ethernet controller
#define OUR_HEAP_SIZE (HEAP_REQUIREMENTS)((24 * 1024) * MEM_FACTOR) 

#elif defined MY_HARDWARE_K22FX

#define KINETIS_FLEX // X part with flex memory rather than N part with program Flash only
#define PIN_COUNT PIN_COUNT_100_PIN // 100 LQFP package
#define SIZE_OF_FLASH (512 * 1024) // 512k FLASH
#define SIZE_OF_RAM (128 * 1024) // 128k SRAM

app_hw_kinetis.h

 #define CRYSTAL_FREQUENCY    4000000                             // 4 MHz crystal

Not sure, what else there is to configure presuming everything in the uTasker is configured to work based on the above setting changes. I based my target on FRDM_K22F dev board.

Im hoping it's something very simple you can identify that I may have missed or haven't set up correctly.


Thanks in advance.

Regards
Jerome

0 Kudos

924 Views
mjbcswitzerland
Specialist V

Hi Jerome

The K22FX512 doesn't have an IRC48M (as the K22 on the FRDM-K22F board has) and so it won't be able to get past the line that it is hanging at.

For your chip you need to use a different clock configuration, and if using USB device you also can't use USB_CRYSTAL_LESS.

Eg.

Remove RUN_FROM_HIRC

With #define CRYSTAL_FREQUENCY    4000000

and #define CLOCK_DIV            2

you will get 80MHz operation (adjust CLOCK_MUL to a higher value to get more speed).

Note that can need to set the crystal oscillator gain to match your HW
#define OSC_LOW_GAIN_MODE
can be used when there is no circuit loading, or remove the define to get high gain configuration (when it is loaded). The FRDM-K22F, for example, uses low gain mode since it doesn't have loading caps or feedback resistor.

Regards

Mark

0 Kudos

926 Views
F50SC
Contributor III

Hi Mark

Thanks, those settings worked.

I've also enabled the serial_interface for debugging and to test the loader using SREC & Intel HEX file transfer modes.

I have configured the loader UART to match my hardware, and have the menu showing up in the console terminal.

The SD card functionality I have removed, but will look at this again later for SPI, once I confirm I can use my PC app and KinetisFlashTool to load an image using the Serial Loader.

Right now, USB is not enumerating, rather than a single "ding,dong" from Windows I get a double "ding,ding" and windows displays Unknown Device in Device Manager.

Could it be related to the clock settings?

Although I have a 4MHz crystal on my hardware, I'm not actually using it.

The current clock config I have is FEI MCG mode.....I remember now I had some issues getting USB to work.

However, the KBOOT 1.2 bootloader works just fine with USB on my hardware.

These are the clock settings I use in PE

pastedImage_2.jpg

pastedImage_3.jpg

I look forward to testing the rest of the loader once the USB is up and running.

Thanks again.
Regards


Jerome

0 Kudos

926 Views
mjbcswitzerland
Specialist V

Jerome

Your part needs the 4MHz crystal to correctly run from USB (it may work from the FLL but it will have high jitter and not pass any USB certification testing - although may work in the lab for quick tests).

The 80MHz setup is not suitable for USB because a 48MHz clock can't be generated (if you build and run the serial loader in the VS project the simulator will inform you of invalid clocks and show that USB can't work).

To use USB try the following settings:

#define CLOCK_MUL            48                              // the PLL multiplication factor to achieve operating frequency of 96MHz (x24 to x55 possible)
#define FLASH_CLOCK_DIVIDE   4                               // 96/4 to give 24MHz
#define BUS_CLOCK_DIVIDE     2                               // 96/2 to give 48MHz

Also ensure that the USB is using the internal clock:

#define USB_CLOCK_GENERATED_INTERNALLY                               // use USB clock from internal source rather than external pin - 96MHz or 120MHz core clocks are suitable

This will allow USB device operation (as would 120MHz core speed if you want to run the processor faster).

Regards

Mark

0 Kudos

926 Views
F50SC
Contributor III

Hi Mark

Thanks for your assistance once again, those settings were correct and the USB is now enumerating.

Regarding our hardware, unfortunately I was not able to get the USB working using any of the other clock modes ie. PEE even with the correct clock divider / multiplier to achieve the 48MHz clock....its just would not work. At the time (this was over 2 years ago) I settled for FEI as the USB was working, and that was enough for me to continue development with our application. I planned to return to this later when I had more time.

I suppose, I did not bother to research enough of your project and plunged right in hoping it would do everything I wanted it to do without modification....That's my fault not yours.

Regarding your simulator. I had some issues trying to compile on my work machine...the make file was failing with a generic error and I tried a few different uTasker projects I had on file and they both had the same error. Although I can compile and run the project successfully on my home PC. See below error..

pastedImage_1.png

At this stage, I can now connect using the KinetisFlashTool AND also my device config app, these are the some of the issues / comment I have thus far.

1.   I discovered the uTasker project does not support all KBOOT commands, namely erase-all. there is also some properties that are not supported...no big deal, and are not critical for image loading, however the erase-all is.As a consequence I had to update my app, to use the erase-flash-region command which wasn't too much effort. After doing this I was able to load an image successfully with my app and the uTaskerSerialLoader running on my hardware. :smileyhappy:

2. I can also load an image using the KinetisFlashTool. Great :smileyhappy:

3. After flashing my board and using GO cmd from the serial loader menu to start my application, the USB no longer functions. It does not enumerate or doing anything. I can unplug/plug the cable nothing happens.
To configure the hardware from the app I use the USB-CDC driver not USB-HID, should that make a difference??

I suspect there is some issue with the clock configuration that affects USB after jumping to the application. The Freescale KBOOT performs some clean up operations before jumping to the users code, not sure if uTasker is doing something similar...but with KBOOT the USB works as expected after exiting the bootloader.

4. There is no timer that will exit the bootloader after a period of time and automatically jump to the users application?

The GO cmd must be entered from the menu or press a switch to exit the bootloader? With Freescale KBOOT it will exit after a set time if no command is detected on a peripheral. 

In summary, point 1 & 4 I would expect to be standard with the uTaskerSerialLoader to make it truly compatible with NXP\Freescale KBOOT.

Not taking anything away from uTasker, but it's worth pointing out for others that maybe considering your project in place of the Freescale\NXP Bootloader and expecting these features built-in.

Regards

Jerome

0 Kudos

926 Views
mjbcswitzerland
Specialist V

Hi Jerome

The simulator failure is a post build bat file that can't be execute - the simulator is still OK and operational.
There are two possible explanations:
1. You are using the "Kinetis" target on one machine and the "Kinetis plus GCC build" target on the other. The one not trying to do a post build step is then not showing the error message.
2. On one machine the post build step is working and on the other it is not (check the bat file called to see that it knows the path of your GCC toolchain).
If you don't want the post build step select the target without it, and in each case the simulator will still run since teh post build step is needed only to generate an object for the HW target.


1. Only the commands that are used by KBOOT loading tool are implemented. All other commands are caught by:

        case KBOOT_COMMAND_TAG_ERASE_ALL:                                // the following are not yet used by KBOOT
..
        case KBOOT_COMMAND_TAG_MASS_ERASE:
            _EXCEPTION("Use detected - investigate....");
            break;
        }

If you need the erase all command to operate (you are probably using this on a command line since I have never seen KBOOT loader tool use it, and it would also delete the installed loader and require programing with the debugger afterwards)
you can add

case KBOOT_COMMAND_TAG_ERASE_ALL:
    fnMassEraseFlash();
    break;

2. This is the compatibility that is aimed at.

3. Before starting the application there is a macro called
#define RESET_PERIPHERALS()
which resets the USB and can be extended by the user if needed.
I never heard of a problem with USB operating in the application after the loader has been used but one can never exclude a special case in which some extra de-initialisation may been required.
MXQ libraries ( main clock initialision) are however known to be sensitive to anything that is not in its default state.

4. The uTasker serial loader has many modes and includes timer based method of starting the application which can be configured by the user
            #define KBOOT_HID_ENUMERATION_LIMIT  (DELAY_LIMIT)(5 * SEC)  // if there is no USB enumeration we start the application after this delay
            #define KBOOT_COMMAND_LIMIT          (DELAY_LIMIT)(10 * SEC) // if there is no valid KBOOT command received after this delay the application will be started

If you are using the open source version you will have a project that is generally 2..3 years behind the professional version.
As with all open source code it is there to be used as long as you accept a certain responsibility to working out details and extending it yourself when needed.
In comparison, the professional version has more advanced features (including things like strong authentication/encryption capabilities in addition to the KBOOT basic operation). It also has professional support so that any deviations detected in a certain situation or specific to a project/HW can be looked into and solved without the user needing to invest or lose any time. It contains methods that can be used to allows controlling SPI Flash read/write/erase via the KBOOT (or other)  interface, which I though was the main aim of you using it (?)


Note also that the uTasker project is not just a KBOOT compatible project since the KBOOT mode represents a small part of its overall functionality [in fact much more popular for product developments is the USB-MSD mode] and is thus just one of a great number of features that are included and supported so that product developments can be made more flexible with the assurance that it is professionally maintained and supported.

Regards

Mark

0 Kudos

923 Views
F50SC
Contributor III

Hi Mark

Are the options below included in the uTaskerOpenSource project?

#define KBOOT_HID_ENUMERATION_LIMIT 

#define KBOOT_COMMAND_LIMIT      

Regards

Jerome

0 Kudos

923 Views
mjbcswitzerland
Specialist V

Jerome

Normally not but I have just checked it in for you.

Or you can use the attached files and add these configurations to config.h

                #define KBOOT_HID_ENUMERATION_LIMIT  (DELAY_LIMIT)(5 * SEC)  // if there is no USB enumeration we start the application after this delay
                #define KBOOT_COMMAND_LIMIT          (DELAY_LIMIT)(10 * SEC) // if there is no valid KBOOT command received after this delay the application will be started

Note that in most practical cases I know the KBOOT loading mode is used as a fall-back for this compatibility, but the main loading technique is a different one. This is why the control of the loader is not exclusively by KBOOT activity, but with these defines it then is.

Regards

Mark