Kinetis - Relocating vector table to ram memory

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

Kinetis - Relocating vector table to ram memory

Jump to solution
4,429 Views
edwardkäding
Contributor III

Hello Freescale community,

 

As usual I apologize if this question has been answered in a different discussion.

I am writing a Bootloader for the MKL02Z32VFM4 MCU using Code Warrior v10.5 and no PE.

The Bootloade for s.19 files using UART with 115200 Baud works great, but it can not handle continious receiving of the .s19 data (only in rows).

The reason for this is the short moment when the flash is written that no Rx-interrupt is allowed to be triggert causing a reading collison error.

 

For this reason:

I want to relocate or copy the vector-table (at least parts of it) into the RAM Memory in order to use interrupts when reading from / writing to Flash is forbidden.

 

For a long time I have searched the web and could not get any proper answers.

After reading a lot of manuals e.g." Relocating Code and Data Using the CW GCC Linker File(.ld) for Kinetis", relocating of functions to RAM Memory works fine now,

but I just do not understand how to relocate the vector-table without making problems.

I have compared the PE Version of puting the vector-table in RAM, but had similar problems than trying it manually. Do I have to copy the vector-table like in the example to an external RAM?

 

It would be great to have just one proper example how this is done!

 

I have written a smale example triggering a port interrupt when logic 0 is detected.

 

Please show me what I am doing wrong.

 

I thank everyone in advance for the great help,

Edward.

Original Attachment has been moved to: RelocateToRam_Example.zip

Labels (1)
0 Kudos
1 Solution
1,624 Views
mjbcswitzerland
Specialist V

Edward

You just need to set the NVIC VECTOR_TABLE_OFFSET_REG (0xe000ed08) to the area of RAM you want to use (the first address in SRAM is popular - address 0x1ffffcc0 in you device - 0xc0 size is adequate for all interrupts).

Then copy the vectors that you would normally have in Flash (at address 0x00000000) to that area.

That is all.

The KL02 will load SRECs at 57600 Baud without the need for handing interrupts in RAM. Above this speed it becomes unreliable due to RX overruns when the flash is being programmed.

Personally I prefer not to use relocated program code in SRAM since it is quite compiler dependent (not all can do it) so I use XON/XOFF protocol at speeds above 57600Baud. Collect the SREC data until a buffer (eg. 2k is filled), send XOFF to the host and wait for it to stop (usually immediate), program the complete 2k block to Flash, send XON and continue - repeating a few times until the code has been fully loaded. This is described in chapter 5 of http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.PDF

Unfortunately this doesn't work on the Virtual COM port connection on boards with OpenSDA since the driver doesn't respect XON/XOFF protocol ;-(

Regards

Mark

View solution in original post

0 Kudos
6 Replies
1,624 Views
chris_brown
NXP Employee
NXP Employee

Hi Edward,

Freescale provides a bootloader that I believe supports the device you are targeting.  Have you tried this and does it meet your needs? 

Kinetis Bootloader

Best of luck,

Chris

0 Kudos
1,624 Views
mjbcswitzerland
Specialist V

Chris / Edward

The present Kboot V1.0.2 only contains support for the K64 and the loader can only be built using IAR.

The previous Kboot V1.0.1 did have K64, KL02 and KL25, although again only for building with IAR, however the KL02 didn't actually have a binary (as the other two did).

I did some testing with Kboot's UART loader and found the following points of note:

- it works at a fixed 57'600 Baud

- data packets are sent with fixed sizes of 38 bytes, of which 6 are overhead, including a CRC-16 field.

- The data content is binary (not ASCII like SREC)

- the protocol uses handshaking (NAK and ACK) and the processor has time to program the Flash without needing to handle UART interrupts during the process (due to this flow control)

The speed is therefore about the same as SREC at 115'200 Baud (since the data is binary and not ASCII) and each frame has a similar overhead in the two cases. It is a shame that the speed is not 115200 Baud but maybe it will be increased in the future since I don't see a reason for it to be slower.

The UART interface wraps the frames with a header specific to this interface while the frame content is in fact the same as that used by the HID loader mode (for devices with USB).

The uTasker project's serial loader already supports the KBoot HID mode - see Re: Kinetis Boot Loader for SREC UART, SD Card and USB-MSD loading and I added the UART wrapper to it there and did a few initial tests. It was possible to achieve operational compatibility for download operation (checked on KE02, KL02 and K64 to verify small and big parts in these families) - with the Kboot UART interface needing about 6k of code (a little less that SREC loading since the SREC handling and user interface has more overhead). With Kboot UART and HID enabled in parallel it is around 12k. This includes an OS (makes operation and maintenance much easier).

Basically this means that Kboot can be used with the KL02 (available in next uTasker release, if it can't already be built from the present Kboot package [for all popular IDEs]). The Kboot mode overcomes UART overrun risk at high Baud rates during flash programming and so allows some speed advantage when no HW flow control is possible in SREC mode, although it would be better if the Kboot utility would use a higher Baud rate too. When HW handshaking is available to control SREC mode there is presently no speed advantage in Kboot mode, but it does require slightly less code.

Regards

Mark

PS: If anyone wants to have a try with the FRDM-KL02Z and Kboot I have attached binary files:

- uTaskerSerialBoot_FRDM-KL02Z_KBOOT.bin is the KBOOT compatible UART loader

- uTaskerV1.4_BM_FRDM-KL02Z_2800.bin  can be loaded to the board using KBOOT's "winupdater.exe" application. The offset must be set to 0x00002800 when selectin the file so that it is programmed to the correct place.

Ths 16.5k application takes about 9s to load via the Vitual COM port, which is about 2.5x slower than expected but I think that this may be due to a degree that the "winupdater.exe" application doesn't respond very quickly afer each packet has been acked, and possibly the virtual COM has some delay when sending lots of small packets (depends on how well it is implemented in the OpenSDA device).

When the loader is running the green LED blinks with 5Hz and when teh application i soperating the RGB LED's colour is controlled the board tilt. There is also some ADC / accelerometer data on the UART (virtual COM at 115'200 Baud).

To force the serial loader again J8- pin 3 can be grounded at reset.

1,624 Views
edwardkäding
Contributor III

Hello Mark, David and Chris,

I thank you all for your great help, explanations and interesting ideas.

I was not very clear on what I want to achieve and what I have already tested.

My Bootloader does not have much space for variations. It must be very small (<3k), UART with a Baudrate of 115200 and as fast as possible.

The size is of most importance especially for the smallest of the KL02 series with just 8k Flash memory and most Freescale Bootloaders are just too big for that.

The idea is that a bigger main MCU is connected to the small KL02 MCUs using Rx/Tx PIN UART and programms them with a new application code if an update is needed. The two MCUs are only connected with RX and Tx.

We are still not sure which kind of data package we are going to use. At the moment I am using .s19 Files thanks to Code Warrior "Create Flash Image" option.

The protocol looks more or less like this:

Main MCU send change flash command -> KL02 write fixed byte a special value -> software reset -> enter Bootloader mode -> programm flash -> erase fixed byte -> software reset -> enter normal application code (normal run mode).

I am using the PC with various Terminal programms to simulate the main MCU.

Like Mark has mentioned, XON/XOFF is out of the question, but FLow Control with RTS/CTS could be emulated using a defined protocol. I am already sending an acknoledge byte to the Main MCU after every successful flashed line.

@Chris: Your fear of writing after each line of the S-Record transfer is like Mark has mentioned of no concern. The flash process stops if the CRC detects a faulty line. Than you can e.g. erase the total flash and reset the MCU to enter the Bootloader again. Or you could ask for the same line again (e.g. 3 times) and then stop the process as mentioned.

@Mark: Thank you very much. I am going to need some time to analyse all the information I have received from you, but I am sure I will find something useful. Thx.

               I am very interested in the binary data content and the KBOOT decoding methode. What kind of files are they (.elf, ...)? How can I generate them for testing?

            

Solution:

I have solved my problem of the Read Collison Errors while writing the flash when an Rx Interrupt is triggert due to a continious sending of the .s19 data of the terminal programs.

At the beginning I thought I need to place the complete vector table into the Ram memory, but it turns out that you only need to place the functions you are using into the Ram memory which are

connected with the receiving process during the time a Read Collision Error would be triggert.

For relocating  a function I followed the "Relocating Code and Data Using the CW GCC Linker File(.ld) for Kinetis", created my own Ram memory space and copied the functions using the

""void __attribute__((section(".myCodeInRAM"))) UART0_IRQHandler (void)"" command. As you can see it is very important that you copy the UART handler function.

We have analysed the writing process and triggering of the Rx-Interrupts using a scope and and can see now that both processes can work simultanious.

The flash process of a 44.618 Bytes .s19 File (44.618byte * 1/115200(1/s) * 10bits = 3.87s message transfere) now only takes 4 seconds of total flash time and it works every time.

It is now working even better than before when I wrote line by line and had to switch the interrupts of while writing to the flash.

There is just one problem which really really annoys me, but I might just open a new discussion for this.

Why is it possible to write one byte to the flash, but in order to override it you need to delete 1k of flash memory,

while PE can do this and the code next to the memory is not being erased, even though there is clearly an erase command visible

in PE when writing a new value to the flash adress!!!

I hope this helps,

Thanks again for your great support,

Edward.

0 Kudos
1,624 Views
DavidBLit
Contributor II

Writing Flash after each line of the S-Record transfer sounds more than a little risky.  What happens to your board when you get a corrupted S-Record after some number of good ones?  Flash now has only a partial new image...

If you're married to writing Flash after each S-Record line have you considered using flow control on the serial connection to pause the transmission while you scribble Flash?

How about buffering the entire image in external memory before ever touching Flash?

How about just porting U-Boot and then getting on with your real task?  :smileywink:

0 Kudos
1,624 Views
mjbcswitzerland
Specialist V

David Littell wrote:

Writing Flash after each line of the S-Record transfer sounds more than a little risky.  What happens to your board when you get a corrupted S-Record after some number of good ones?  Flash now has only a partial new image...

If you're married to writing Flash after each S-Record line have you considered using flow control on the serial connection to pause the transmission while you scribble Flash?

How about buffering the entire image in external memory before ever touching Flash?

How about just porting U-Boot and then getting on with your real task? 

U-Boot is a collection of loaders, which one do you recommend?

One of them is also an SREC download, which is equivalent. Porting other SREC loading sources will have the same Flash programming speed limitations so will need to be solved too.

SREC lines contain checksums and it is easy to detect an error and recover (start-over) - it is supported by most programming tools so makes a decent choice for small processors with limited communication capability. In many years of SREC UART loading I don't think that I experienced a loss of an SREC line under normal working conditions so the reliability is generally adequate for normal working/developing environments.

SREC has no flow control in its protocol so RTS/CTS or XON/XOFF can be used instead but this is not always possible; in the case of the Freedome boards (Virtual COM - if it needs to be used) there is no RTS/CTS flow control connection and its XON/XOFF doesn't respond.

The KL02 has 32k FLASH and 4k SRAM and no external memory so loading to external memory is not very convenient (needs extra HW just for the case and serial or bit-banged interfaces). The loader should be as small as possible since it takes away application space.

The advantage of SREC is that it can be used with any terminal emulator. If additional protocols with protocol-level flow-control are to be used instead (x-modem etc.) it is probably best to aim at Freescale's KBOOT compatibility.

Regards

Mark

1,625 Views
mjbcswitzerland
Specialist V

Edward

You just need to set the NVIC VECTOR_TABLE_OFFSET_REG (0xe000ed08) to the area of RAM you want to use (the first address in SRAM is popular - address 0x1ffffcc0 in you device - 0xc0 size is adequate for all interrupts).

Then copy the vectors that you would normally have in Flash (at address 0x00000000) to that area.

That is all.

The KL02 will load SRECs at 57600 Baud without the need for handing interrupts in RAM. Above this speed it becomes unreliable due to RX overruns when the flash is being programmed.

Personally I prefer not to use relocated program code in SRAM since it is quite compiler dependent (not all can do it) so I use XON/XOFF protocol at speeds above 57600Baud. Collect the SREC data until a buffer (eg. 2k is filled), send XOFF to the host and wait for it to stop (usually immediate), program the complete 2k block to Flash, send XON and continue - repeating a few times until the code has been fully loaded. This is described in chapter 5 of http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.PDF

Unfortunately this doesn't work on the Virtual COM port connection on boards with OpenSDA since the driver doesn't respect XON/XOFF protocol ;-(

Regards

Mark

0 Kudos