Freedom bootloader

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Freedom bootloader

4,470 Views
akimata
Contributor IV

Hello,

I'm looking for some help, i downloaded kinetis bootloader from your website (NXP_Kinetis_Bootloader_2_2_0) and i can see  MK22FN128 in target folder which is my microcontroller used on custom board. The problem is that i can't find any files to import to mcuxpresso to change application start adress, timeout  settings and pin to enter the bootloader. Last time i played with bootloader somehow i found import files to mcuxpresso, but they are not useful anymore because i changed microcontroller.

What i'm actually looking for: bootloader(HID should be good) to flash my application without using external debugger(multiple times). It would be great if you could help me importing and setting up bootloader for my MK22FN128 mcu :smileyhappy:, it shouldn't be a problem because i can already see that it's supported target, just a little help how to flash this bootloader or import to mcuxpresso.

Maybe uTasker bootloader would be a good solution in this case but not sure if mk22fn128 is supported.

17 Replies

3,844 Views
mjbcswitzerland
Specialist V


Hi Grzegorz

The uTasker serial loader supports all Kinetis parts (including the K22FN128) and contains compatible USB HID Kboot and UART loading, as well as various other methods: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf which can be used instead or in parallel with KBOOT.


It has less restrictions (can be used with GCC, KDS, CW10, MCUXpresso, IAR, Keil, Atollic, Rowley, Green Hills, Coo Cox- and even Platform IO for Ardunino lovers) and doesn't need porting as the standard one does when its target is not supported. This makes it especially suitable for professional usage where fast and guaranteed operation is more important that an exercise in porting from one chip to another.

Regards

Mark

3,844 Views
akimata
Contributor IV

So i cloned git repesitory, and now i'm stuck at finding correct target in config.h file because there is no MK22FN128 there and i'm not familiar with all freedoms to choose the closest one to modify. I think the best bootloader for my application would be MSD so i choosed uTaskerSerialLoader. My custom board got only one crystal connected to extal32,xtal32 (32kHz)

As far as i understand when using MSD bootloader it's just drag and drop update but how do i prepare main application code for flashing? Do i need to change some starting addresses?What's the ending point of bootloader and starting point of application?

3,843 Views
mjbcswitzerland
Specialist V

Hi

for the K22FN128 you can use the FRDM_K22F target. You will however need to adjust a few settings:
1. In app_hw_kinetis.h
- make sure the IRC48M clock is used with
#define RUN_FROM_HIRC                                                // clock directly from internal 48MHz RC clock
2. In app_hw_kinetis.h
- make sure that crystal-less USB device mode is used with
#define USB_CRYSTAL_LESS                                             // use 48MHz IRC as USB source (according to Freescale AN4905 - only possible in device mode)
3. In app_hw_kinetis.h
- set the flash and ram size for the chip to
    #define PIN_COUNT           PIN_COUNT_64_PIN                     // 64 LQFP pin package
    #define PACKAGE_TYPE        PACKAGE_LQFP
    #define SIZE_OF_FLASH       (128 * 1024)                         // 128k FLASH
    #define SIZE_OF_RAM         (24 * 1024)                          // 24k SRAM
4. In config.h (in the FRDM_K22F section) change
#define KINETIS_MAX_SPEED    120000000
to
#define KINETIS_MAX_SPEED    100000000
since it is a 100MHz part.
5. In config.h
set the heap size to
#define OUR_HEAP_SIZE   (HEAP_REQUIREMENTS)((10 * 1024) * MEM_FACTOR)
since the original size for the K22FN512 is too big for the smaller part (in fact about 2.5k is needed by the serial loader operation but some reserve is OK)
6. When the liker script file is defined it must be
K_128_24.ld (for GCC) instead of the K_512_128.ld as used by the FRDM_K22F.

Generally:
For USB loader enabled (in config.h)
USB_INTERFACE
and for USB-MSD type enable
USB_MSD_DEVICE_LOADER
If you want both USB-MSD and KBOOT at the same time enable also HID_LOADER and KBOOT_HID_LOADER

There is a check list of things that need to be done in the application to ensure compatibility (like its link address) in the serial loader document (see the appendix).
Applications built with uTasker automatically have full serial loader compatibility.

You can configure the application start/stop in Loader.h (see the instructions in the serial loader document) but it also depends on the physical size of the serial loader. As reference: the uTasker USB-MSD loader is around 14k in size. USB-MSD + KBOOT HID is around 15k. With only KBOOT HID it is about 11k.

Regards

Mark

P.S. With the above settings the complete library code will adapt itself to suit the chip in question without any application incompatibility (or any user porting requirements).
However, beware that the open source version is a few years behind the professional project version and so does not have as many features and may miss a few things for newer chips.
I see that the USB regulator will be (unnecessarily) configured in your case but I don't think it is of concern - the registers are there but they just don't do anything.
You can comment out
    SIM_SOPT1_SET(SIM_SOPT1_USBREGEN, SIM_SOPT1CFG_URWE);                // ensure USB regulator is enabled
    SIM_SOPT1_CLR(SIM_SOPT1_USBSTBY, SIM_SOPT1CFG_UVSWE);                // and not in standby
in the OTG driver in case of any issues with your chip.

3,843 Views
akimata
Contributor IV

So i managed to generate and flash it with K_128_16.ld file, seems like it can work, just SRAM lower is not used by bootloader. Led is blinking all the time(5Hz i guess), even when i power without bootpins asserted(probably missing application file)

When i plug my board UPLOAD_DISK appears with some random files in it (attached pictures) and i can't copy anything into it(not enough space)

pic8.PNG

Could u please tell me what i've done wrong? because at this point there is no way to move anything into that storage.

Back to my main application, i've read some posts and looked through Loader.h and it seems like it uses 32*1024 +80 which gives 0x8080 start point of my application.

I've made some changes ( correct me if they're wrong) . Added 2 lines in main code:

SCB -> VTOR = 0x20000000;
memcpy((uint32_t*)0x20000000,(uint32_t*)0x00008080,0x200);

And changed memory as shown on the picture below:

pic9.PNG

3,844 Views
mjbcswitzerland
Specialist V

Hi

K_128_16.ld will also work. If you want to use K_128_24.ld it is in \Applications\uTaskerV1.4\GNU_Kinetis (you can copy it to the serial loader linker script folder). It won't change operation though.

It looks to be all working but you have random data in the Flash - if you first do a mass erase of the chip it will start with an empty directory and you can then load an application (in the developer's project this case of not starting with empty flash causes a file "unknown.bin" or such to appear that can then be deleted but the Open Source projects doesn't have this yet).

The standard configuration is for the application to be linked to start at 0x8080. You can reduce this to 0x4080 etc. if you like (the 0x8080 allows various loaders to be used compatibly, even with Ethernet Webserver, Modbus and AES256 encryption, but you are free to change it to make the most use of the chip's resources).

The uTasker code is much more efficient than the example code and Kboot etc. so typically will be half the size and, if you study the source, much easier to understand and better commented (it can also be fully simulate in Visual Studio for code reviews and such).

What you have done with application linking and copying the vectors to the SRAM looks good but usually one locates it at 0x1fffe000 (and you need to ensure that this is not used by variables, which can be done by setting the linker script used by the application to starts its RAM at 0x1fffe200)

Regards

Mark

3,844 Views
akimata
Contributor IV

It seems like it was just a lucky shot that it worked... After erasing chip and flashing the bin again nothing happens(no led blinking, pc doesn't even see pc connection(no sound)). I confirmed that the board itself is still fully functional, just the bootloader can't run.

I'm still wondering if external crystal is not needed at all, because i can see some  defines for crystal so maybe it hangs somewhere in osc initialization?

#define OSC_LOW_GAIN_MODE
#define CRYSTAL_FREQUENCY 8000000 // 8 MHz crystal
#define _EXTERNAL_CLOCK CRYSTAL_FREQUENCY

I'm attaching 2 files, modified by me, could u please take a look at them and tell me if everything is ok?

Some more informations about my board:

LED is on  PTC2

Button to force bootloader is on PTA5

Only 32khz crystal connected to XTAL32,EXTAL32 is present, no oscillator on XTAL0,EXTAL0

3,844 Views
mjbcswitzerland
Specialist V

Hi Grzegorz

I don't believe in lucky chances or black magic when developing embedded firmware (although sometimes one indeed has the feeling that there is a mischievous gremlin corrupting things that you are convinced you are doing right, until you realise what are you doing wrong...).

If you open the project in Visual Studio and run the simulator it immediately shows you the problem:

pastedImage_9.png

#define UTASKER_APP_START     (32 * 1024)   // application starts at this address

#define UTASKER_APP_END       (unsigned char *)(UTASKER_APP_START + (128 * 1024))

Since your chip has 128k of flash the application range is too large. What is happening is that there is a check at startup to see whether this range is blank and that crashes when checking beyond the end of flash.

The reason why you didn't see this when you had non-blank flash is because the check already quit since it had already found non-blank content - meaning it don't have to check so far and find it crashed.

Since you have RUN_FROM_HIRC enabled it overwrites the crystal settings (if you look carefully you should find these defines are not active and are displayed grayed out by the editor).

Therefore it will be Ok if you change the application size to

#define UTASKER_APP_END           (unsigned char *)(UTASKER_APP_START + (96 * 1024))

for example.

Or

#define UTASKER_APP_END           (unsigned char *)(SIZE_OF_FLASH - UTASKER_APP_START)

will work if you automatically want to use all remaining flash (although often one keeps an area for saving parameters to that is preserved across firmware uploads).

I checked your LED setup and it is good.

Your force loader switch is not quite right yet and would cause the next crash:

#define SWITCH_4               (PORTA_BIT5)
#define FORCE_BOOT()       (!_READ_PORT_MASK(A, SWITCH_4))

There is however nothing configuring the port input before use so you need to also have:

_CONFIG_PORT_INPUT_FAST_LOW(A, (SWITCH_4), PORT_PS_UP_ENABLE);
somewhere.
You can add this to the INIT_WATCHDOG_DISABLE() macro, where the original switch input was being configured.

After this I expect full functionality. When I run it after these modification the simulation shows your chip giving correct USB operation, the LED on PTC2 blinking and the correct input configured:

pastedImage_11.png

Good luck

Regards

Mark

3,844 Views
akimata
Contributor IV

I'm not sure if you're looking at uTaskerSerialBoot because even if i got  #define RUN_FROM_HIRC , OSC defines are not grayed(blacked in dark theme) which is shown on the pic below.

pic11.PNG

I changed everything u suggested and still no success. Attaching new modified files.

Seems like gremlins are still fiddling with me.

3,844 Views
mjbcswitzerland
Specialist V

Hi

My mistake about the oscillator defines not being grayed out, they aren't. But they are NOT used since RUN_FROM_HIRC has priority.

Unfortunately I don't see any error in the configuration and the simulation also doesn't detect any problems.

Can you look with the debugger to see what is happening?

I built with your settings and my HW operates using it - attached is the binary file which you may be able to verify. Be sure that there is no old code at 0x8080 and/or hold your force loader switch to be sure that it doesn't try to execute the (rogue) application.

Regards

Mark

3,844 Views
akimata
Contributor IV

Okay seems like it's not working fully, when i try to load my application which uses FLL sourced from RTC, the application wont start at all. When i load my application running from FLL sourced by internal clock, the application starts but seems like clocks are off. Application which uses USB also fails(no enumartion).

So what's the procedure switching to desired clocks after leaving bootloader because that seems to be issue because it's working just fine without bootloader. What am i missing?

3,844 Views
mjbcswitzerland
Specialist V

Hi

That is interesting - I built with GCC (KDS V3 version) and IAR 8 and both worked so maybe there is an issue with the GCC version as used by MCUXpresso or you have an MCUXpresso configuration error (although one only needs to select Cortex-M4 and the linker script, so I doubt it). Please send the binary that you generate so that I can compare it (I'll also check this evening with the MCUXpresso tool chain).

There should be no issues using the debugger - the project is just code as any other project and doesn't magically not allow the debugger to be used.

The boot loader must use the IRC48M for USB operation and it will always configure this when it starts (before jumping to the application). Unfortunately the NXP library clock initialisations tends to have problems when the MCG configuration is not in its default (reset) state (as does MQX library code). One solution is to use the same clock configuration as needed in the serial loader and then you can skip further initialisation in the application (if possible due to USB requirements: there is a config RUN_FROM_RTC_FLL which may be suitable). Otherwise you may need to improve the application clock initialision code so that it can handle the initial state (by moving back to the original clock configuration out of reset).
In an emergency the macro RESET_PERIPHERALS(), which is called when the loader jumps to the application to power down peripherals that it had used, could be extended with the sequence (the inverse of the sequence controlled by RUN_FROM_HIRC in kinetis.c).

Regards

Mark

3,844 Views
akimata
Contributor IV

So i debugged bootloader and it hangs at irq_default causing hardfault. If u need more detailed photos i can provide them. Attached not working binary.

pic13.PNG

I'm not sure what clocks exactly bootloader uses(i only know that it uses IRC48MHz for usb). So i've done something "crazy" and i created new project, commented out any clock initialization, debugged it, took a piece of paper and write down every clock register value, check in datasheet what exactly is default. After this i added "resetting" at the beginning of the code and it seems that i helped.

3,844 Views
mjbcswitzerland
Specialist V

Hi

The debugger shows that the processor is crashing when it initialises its data (bss - i.e. variables initialised with the value 0, or initialised variables - ie. the ones initialised with non-zero values from const memory). Since the serial loader uses minimum error handling vectors (defined _MINIMUM_IRQ_INITIALISATION) all of the error interrupt (like hard fault) will lead to the irq_default() being called.

This hard fault is typically seen when the wrong linker script file is used - one which locates variables to start at an address that doesn't exist in SRAM. Then the gnu data initialistion hard faults when it tries to copy 0 to .bss or to initialise other variables.

I have attached the linker script that I used - it is however the same one that was in the GNU directory that is in the Github repository. Maybe you simply used the wrong one or you somehow lost the setting to the one that was working(?). You can also use the map fie to see whether the .bss and .data sections are location (these areas are defined by the linker script file) so that you can see that nothing is located either below 0x1fffe000 or above 0x20003fff. Post your (from MCUXpressor generated) map file if not sure.

By the way your, bin file does run on the FRDM-K22F board...

Regards

Mark

3,844 Views
akimata
Contributor IV

No idea how this happend but my linker script went back to default one, after changing it everything works fine.

3,844 Views
mjbcswitzerland
Specialist V

Hi

It is strange that a linker script setting got lost (???) but it is good that everything (all gremlins on the way) has been able to be explained and you have operation.

Don't forget to enable also the KBOOT mode to verify that you then have a composite USB loader which allows either KBOOT HID or the USB-MSD drag-and-drop method. It costs only about 1k or additional Flash and so is very efficient, and then gives additional flexibility. You could also test UART, and SD card loading since these are also operational on all processors too....(again in parallel with any other loaders, in instead of). Then only thing you can't do with your board/processor is memory stick loading because it can't do USB host without adding an external 48MHz oscillator.

Regards

Mark

3,844 Views
akimata
Contributor IV

Your bin does work, mine doesn't so there must be slight difference between mine and Yours configuration but can't find it. I got debugger so i can check where it hangs but i'm not sure how to debug it, because it doesn't seem like typical application and clicking debug is not going to work(MCUXpresso).

I tried to use bootloader to load my application and it works :smileyhappy:

3,844 Views
akimata
Contributor IV

Thanks Mark,

That's really detailed guide, i will try it this afternoon but i'm pretty sure there is no K_128_24.ld file in GNU_Kinetis folder. 15k  bootloader size is super good compared to my previous bootloader which took around 40k. I will try to make the bootloader work first and then will move to preparing my application.

Could u please tell me where i can get correct linker file?