Hello !
I need to use the Boot Assist Module to boot an application from FlexCan bust to internal SRAM.
Now I'm using the TRK-MPC5604P demo for testing with CodeWarrior 10.5. I set the jumpers (FAB = 1, ABS2 = 1, ABS0 = 0) to set the boot mode to FlexCan autobaud to work above 200kbs (8MHz crystal frequency). But when you restart the MCU and try to send frames to calculate the baud, I can’t establish communication.
What I'm doing wrong? I guess initially prepare the MCU to use the BAM, but using the Reference Manual have not found the way.
Can help me with a example code? Just I have to modify the Linker Files?
Thank you very much for your time!
Solved! Go to Solution.
1. The problem is that SBC chip MC33905 must be initialized via SPI to enable the CAN transceiver. CAN transceiver is turned off by default. So, MC33905 is not the best choice if BAM bootloader is used. Here you can find example how to turn on the CAN transceiver:
https://community.freescale.com/docs/DOC-99946
2. How to create RAM image:
Create a project in CodeWarrior and select RAM target. Now it is necessary to move entry point (function __start() ) at the start of RAM image – at address 0x4000_0000.
You will get some warnings because we overloaded the __start function.
(This is example for MPC5566 but it is similar for other devices)
MEMORY
{
init: org = 0x40000000, len = 0x00001000
pseudo_rom: org = 0x40001000, len = 0x00011000
exception_handlers: org = 0x40012000, len = 0x00001000
internal_ram: org = 0x40013000, len = 0x0000A000
heap : org = 0x4001D000, len = 0x00001000 /* Heap starts */
stack : org = 0x4001E000, len = 0x00001000 /* Start location for Stack */
}
SECTIONS
{
GROUP : {
.init_vle (VLECODE) : {
*(.init)
*(.init_vle)
}
.init : {}
} > init
….
Then the entry point (function __start() ) will be at 0x4000_0000. You can check it in .map file.
As a next step, just for test purposes, you can write some code in this project – for example toggle a LED diode in endless loop.
Build the program, so you have RAM.mot file. This is our RAM image that will be downloaded to RAM.
Because the downloading of code via SCI/CAN is quite slow, make the image as small as possible – edit the linker file. For example, if you don’t need size of pseudo_rom to be 0x11000, change it to smaller size.
Notice that downloading of code also initializes ECC. Area that is not written by BAM will contain ECC errors. If your application wants to use uninitialized RAM, it must be explicitly initialized by your SW.
The RAM.mot cannot be downloaded by BAM directly. It must be continuous image without gaps. You can either write some program on PC that will create continuous binary file or you can download the project into RAM by debugger, then save the content of RAM memory to binary file.
Detailed procedure how to download the image for both SCI and CAN can be found in reference manual.
Be aware that erratum exists on some devices: the size of image must NOT be equal to size of RAM. Last 16 bytes in RAM should not be written by BAM. But as I already wrote, it is better to make the image as small as possible.
And there are also application note for Qorivva devices:
http://www.freescale.com/files/microcontrollers/doc/app_note/AN4674.pdf
And RAppID Bootloader utility:
https://www.freescale.com/webapp/Download?colCode=RAPPID_BOOTLOADER_UTILITY
1. The problem is that SBC chip MC33905 must be initialized via SPI to enable the CAN transceiver. CAN transceiver is turned off by default. So, MC33905 is not the best choice if BAM bootloader is used. Here you can find example how to turn on the CAN transceiver:
https://community.freescale.com/docs/DOC-99946
2. How to create RAM image:
Create a project in CodeWarrior and select RAM target. Now it is necessary to move entry point (function __start() ) at the start of RAM image – at address 0x4000_0000.
You will get some warnings because we overloaded the __start function.
(This is example for MPC5566 but it is similar for other devices)
MEMORY
{
init: org = 0x40000000, len = 0x00001000
pseudo_rom: org = 0x40001000, len = 0x00011000
exception_handlers: org = 0x40012000, len = 0x00001000
internal_ram: org = 0x40013000, len = 0x0000A000
heap : org = 0x4001D000, len = 0x00001000 /* Heap starts */
stack : org = 0x4001E000, len = 0x00001000 /* Start location for Stack */
}
SECTIONS
{
GROUP : {
.init_vle (VLECODE) : {
*(.init)
*(.init_vle)
}
.init : {}
} > init
….
Then the entry point (function __start() ) will be at 0x4000_0000. You can check it in .map file.
As a next step, just for test purposes, you can write some code in this project – for example toggle a LED diode in endless loop.
Build the program, so you have RAM.mot file. This is our RAM image that will be downloaded to RAM.
Because the downloading of code via SCI/CAN is quite slow, make the image as small as possible – edit the linker file. For example, if you don’t need size of pseudo_rom to be 0x11000, change it to smaller size.
Notice that downloading of code also initializes ECC. Area that is not written by BAM will contain ECC errors. If your application wants to use uninitialized RAM, it must be explicitly initialized by your SW.
The RAM.mot cannot be downloaded by BAM directly. It must be continuous image without gaps. You can either write some program on PC that will create continuous binary file or you can download the project into RAM by debugger, then save the content of RAM memory to binary file.
Detailed procedure how to download the image for both SCI and CAN can be found in reference manual.
Be aware that erratum exists on some devices: the size of image must NOT be equal to size of RAM. Last 16 bytes in RAM should not be written by BAM. But as I already wrote, it is better to make the image as small as possible.
And there are also application note for Qorivva devices:
http://www.freescale.com/files/microcontrollers/doc/app_note/AN4674.pdf
And RAppID Bootloader utility:
https://www.freescale.com/webapp/Download?colCode=RAPPID_BOOTLOADER_UTILITY
Thank you very much for your time Lukas. It has been a great help!
Since I was able to start the CAN transceiver and with your help I have created a RAM image, but now I only need to download boot code via the FlexCAN. I would like to use the autobaud scan mode to calculate the baud rate.
According to the reference manual, with (FAB=1, ABS[2]=1, ABS[0]=0) when a reset occurs, the MCU enters the BAM module. So is necessary a first message from the host (CAN ID = 0x0, DLC = 0) to calculate the baudrate and configure the FlexCAN.
But I have a question ... MCU should have a first program loaded?
Once restarted, if it enters BAM module the CAN communication can’t be established with host because the MCU seems not configured. What am I doing wrong?
Thanks,
Sergi
Hi Sergi,
MCU is initialized by BAM code. This is copied from reference manual:
***
BAM uses/initializes the following MCU resources:
• ME and CGM modules to initialize mode and clock sources
• CAN_0, LINFlex_0, and their pads when performing serial boot mode
• SSCM to check the boot mode and during password check (see Table 34-5 and Figure 34-5)
• External oscillator
The following hardware resources are used only when autobaud feature is selected:
• STM to measure the baud rate
• CMU to measure the external clock frequency related to the internal RC clock source
• FMPLL to work with system clock near the maximum allowed frequency (this to have higher
resolution during baud rate measurement).
As already mentioned, the initial configuration is restored before executing the downloaded code.
***
If you want to use BAM loader, it would be better to use CAN transceiver that doesn’t require initialization. Otherwise the code that is already programmed in the MCU should initialize the transceiver before executing the BAM. Then you can reset the MCU and start the BAM download procedure.
Regards,
Lukas
Hi Lukas,
I've got it! Thanks for your help!
Now, my final application takes over the 40Kb of RAM available on MPC5604P. It is possible to load the program directly into the FLASH with the BAM module? Otherwise, how could do it? In our project we need to have the program on FLASH, so I have to find a solution.
(In our hardware finally we'll use CAN transceiver TJA1041A, as it doesn't requires initialization)
I hope you can help me. Thanks again for everything.
Regards,
Sergi
Hi Sergi,
the BAM is not able to load the code to flash. The BAM is just responsible to load the code to RAM via UART or CAN and then execute this code. So, it must be done by downloaded code. It is usually done in this way: we can develop "secondary bootloader" that will be loaded to RAM by BAM. This secondary bootloader will be responsible to get new firmware from somewhere (probably from the same interface - UART/CAN) and the bootloader has to program this new firmware to flash.
Notice that you can't program the same code that is loaded by BAM to RAM also to flash - it's because it is compiled to be executed from RAM.
Lukas
Hi Lukas,
It's a perfect solution but I have been trying and I not been able to do.
I made a "secondary bootloader" to enable CAN communication and receive FLASH image (binary file) with my final application. Then, it should copy them to FLASH memory, from the position 0x0000_0008. Once loaded, I have to disable the BAM (FAB = 0) and restart the MCU to start the program loaded in FLASH. Is that correct?
But the problem is that I couldn't write to FLASH when running the program from RAM. I've tried the "memcpy()". What steps should follow my second bootloader to load the program in FLASH?
Thank you!
Sergi
Hi Sergi,
Yes, that's correct.
To program the flash, you have to follow the procedure that can be found in reference manual. See the chapter "17.3.8.1.1 Double word program". It is not possible to write the flash directly using memcpy.
Second option is to use SSD flash drivers:
Regards,
Lukas
Hi Lukas,
Thank you very much for your help. Finally I can program the flash through CAN Bus with my "secondary bootloader".
Thanks!
Sergi