May 19, 2014
08:13 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 19, 2014
08:13 AM
Hello,
My questioon is: Is it possible to run a Bootloader from flash memory?
My goal is to seperate the flash into 2 parts. One for the application and one for the Bootloader.
The bootloader should be able to recieve a program via CAN and write it into the application part of the flash.
In the ASC Bootloader example, it says, that the bootloader can only run from PSRAM. But the PSRAM is volatile, so the bootloader program has to be downloaded via the ASC or CAN BSL mode. (is that correct?)
My problem is that the Boot pins are not accesible later. So my bootloader has to be on the device from the beginning.
If it is possible, can I use the given functions from the ASC example to program the flash?
Thanks for you help.
My questioon is: Is it possible to run a Bootloader from flash memory?
My goal is to seperate the flash into 2 parts. One for the application and one for the Bootloader.
The bootloader should be able to recieve a program via CAN and write it into the application part of the flash.
In the ASC Bootloader example, it says, that the bootloader can only run from PSRAM. But the PSRAM is volatile, so the bootloader program has to be downloaded via the ASC or CAN BSL mode. (is that correct?)
My problem is that the Boot pins are not accesible later. So my bootloader has to be on the device from the beginning.
If it is possible, can I use the given functions from the ASC example to program the flash?
Thanks for you help.
78 Replies
May 19, 2014
06:57 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 19, 2014
06:57 PM
Hi Oliver,
There is only 1 PMU (PMU0) which contain one PFLASH bank for XMC4500, thus it is not possible to program the flash at the same time while running the boot loader code.
Whereas for TriCore TC1798, there are 2 PMU (PMU0 and PMU1), so it is possible to locate the boot loader to PMU1 and flash program the PMU0.
Best Regards
Travis
There is only 1 PMU (PMU0) which contain one PFLASH bank for XMC4500, thus it is not possible to program the flash at the same time while running the boot loader code.
Whereas for TriCore TC1798, there are 2 PMU (PMU0 and PMU1), so it is possible to locate the boot loader to PMU1 and flash program the PMU0.
Best Regards
Travis
May 19, 2014
07:51 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 19, 2014
07:51 PM
oliver.blasius wrote:
Hello,
My questioon is: Is it possible to run a Bootloader from flash memory?
My goal is to seperate the flash into 2 parts. One for the application and one for the Bootloader.
The bootloader should be able to recieve a program via CAN and write it into the application part of the flash.
In the ASC Bootloader example, it says, that the bootloader can only run from PSRAM. But the PSRAM is volatile, so the bootloader program has to be downloaded via the ASC or CAN BSL mode. (is that correct?)
Travis: This is correct. The startup software which is factory programmed will detect boot pin status and transfer the boot loader code from the PC via ASC/CAN to the XMC PSRAM. After transfer the CPU will execute instruction from the PSRAM.
My problem is that the Boot pins are not accesible later. So my bootloader has to be on the device from the beginning.
Travis: It's OK. So you want to do flash programming at run time? eg. If you receive an instruction from CAN bus to start flash programming. You can embedded the bootloader into flash and copy to PSRAM. However you need a customize PC flash programming software to take care of the downloading of the hex code.
If it is possible, can I use the given functions from the ASC example to program the flash?
Travis: Maybe..
Thanks for you help.
Hi oliver,
Pls see my reply in red.
May 20, 2014
02:18 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 20, 2014
02:18 AM
Thanks for the reply. It already helped me a lot.
Are there any examples available for copying from flash to PSRAM? or something similar?
And how exactly can I store the Bootloader on the flash?
Edit: I am using an XMC4500. I forgot to mention that in my opening post.
Are there any examples available for copying from flash to PSRAM? or something similar?
And how exactly can I store the Bootloader on the flash?
Edit: I am using an XMC4500. I forgot to mention that in my opening post.
May 21, 2014
12:18 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 21, 2014
12:18 AM
This development is quite tricky, however I am not discouraging you from doing so.
First of all you need to build a loader which is able to communicate with your host PC for hex downloading and also execute flash command instruction. The loader needs to be mapped to PSRAM during development stage. Once the loader software is stable, which means you can flash program the XMC successfully. Then the next thing you need to do is to convert the loader software into a const array from the hex file.
So during XMC run time, you can copy the const array (loader software) into RAM and start executing the loader software.
First of all you need to build a loader which is able to communicate with your host PC for hex downloading and also execute flash command instruction. The loader needs to be mapped to PSRAM during development stage. Once the loader software is stable, which means you can flash program the XMC successfully. Then the next thing you need to do is to convert the loader software into a const array from the hex file.
So during XMC run time, you can copy the const array (loader software) into RAM and start executing the loader software.
May 21, 2014
12:27 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 21, 2014
12:27 AM
Please download this application note from the link below...
http://www.infineon.com/cms/en/product/microcontroller/32-bit-industrial-microcontroller-based-on-ar...
http://www.infineon.com/cms/en/product/microcontroller/32-bit-industrial-microcontroller-based-on-ar...
May 21, 2014
12:32 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 21, 2014
12:32 AM
You don't need to have your whole booter in PSRAM, only the Flash002_* routines needed for erase & program.
Use __attribute__ ((section (".text.fastcode"))) for the methods to be copied to RAM by the .startup code.
You can use a similar approach in your app, so that it can load a new booter.
We have had good experience with the ABM fallback mode in BMI boot mode, keeping 2 copies of the booter if the update of the primary boot image is interrupted.
We keep our primary booter @0x0C000000 (loaded by JTAG in production), fallback booter @0x0C010000 and the application @0x0C020000.
Loading is done via a proprietary CAN protocol.
Use __attribute__ ((section (".text.fastcode"))) for the methods to be copied to RAM by the .startup code.
You can use a similar approach in your app, so that it can load a new booter.
We have had good experience with the ABM fallback mode in BMI boot mode, keeping 2 copies of the booter if the update of the primary boot image is interrupted.
We keep our primary booter @0x0C000000 (loaded by JTAG in production), fallback booter @0x0C010000 and the application @0x0C020000.
Loading is done via a proprietary CAN protocol.
May 22, 2014
02:00 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 22, 2014
02:00 AM
Thanks for the replies.
I already started to build a loader which communicates with the host via CAN. I am trying to use functions from the ASC bootloader example as much as possible.
I already started to build a loader which communicates with the host via CAN. I am trying to use functions from the ASC bootloader example as much as possible.
May 22, 2014
07:32 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 22, 2014
07:32 PM
OMR wrote:
You don't need to have your whole booter in PSRAM, only the Flash002_* routines needed for erase & program.
Use __attribute__ ((section (".text.fastcode"))) for the methods to be copied to RAM by the .startup code.
You can use a similar approach in your app, so that it can load a new booter.
We have had good experience with the ABM fallback mode in BMI boot mode, keeping 2 copies of the booter if the update of the primary boot image is interrupted.
We keep our primary booter @0x0C000000 (loaded by JTAG in production), fallback booter @0x0C010000 and the application @0x0C020000.
Loading is done via a proprietary CAN protocol.
Hi OMR,
Can you share how did you actually mapped the ABM header 0 to address 0x0C00FFE0?
I created a ABM header table as shown below below
const uint32_t ABM0[5] = { .............};
Best Regards
Travis
May 26, 2014
03:24 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 26, 2014
03:24 AM
I just flashed it after generating it:
const uint32_t ABM0_HEADER_ADDRESS = 0x0c00ffe0;
unsigned int abm0[ABM_HEAD_WORDS];
if (sanityCheck(BOOT_START_ADDRESS)) {
unsigned char tmpBuf[FLASH002_PAGE_SIZE]; // minimum number of bytes to FLASH
Flash *flash = Flash::getInstance();
memcpy(tmpBuf, (unsigned char *)ABM0_BUFFER_ADDRESS, FLASH002_PAGE_SIZE); // copy flash contents into buffer
abm0[0] = ABM_MAGIC_KEY; // magic key
abm0[1] = BOOT_START_ADDRESS; // start address of code
abm0[2] = ABM_DEFAULT_SIZE; // Application length
abm0[3] = crc32Gen((unsigned int *)BOOT_START_ADDRESS, ABM_DEFAULT_SIZE); // CRC32 for application length
abm0[4] = crc32Gen(abm0, ABM_HEAD_SIZE-4); // CRC32 for above 4
memcpy(tmpBuf+0xe0, abm0, ABM_HEAD_SIZE); // copy ABM data into tmpBuf
// Program header in FLASH
if (flash->write((unsigned int)ABM0_BUFFER_ADDRESS, (unsigned char *)&tmpBuf, FLASH002_PAGE_SIZE) != 0) {
printf("\nFLASH write failed!\n");
return;
}
else {
if (flash->writeEnd() != 0) { // make sure last block is written to FLASH
printf("FLASH end write failed\n");
return;
}
else {
printf("\nABM0 header FLASHed OK\n");
setBMIWord();
}
}
return; // never copy freshly loaded primary booter as fallback, without at least one reset in between (in effect do a test run of the new booter!)
}
const uint32_t ABM0_HEADER_ADDRESS = 0x0c00ffe0;
unsigned int abm0[ABM_HEAD_WORDS];
if (sanityCheck(BOOT_START_ADDRESS)) {
unsigned char tmpBuf[FLASH002_PAGE_SIZE]; // minimum number of bytes to FLASH
Flash *flash = Flash::getInstance();
memcpy(tmpBuf, (unsigned char *)ABM0_BUFFER_ADDRESS, FLASH002_PAGE_SIZE); // copy flash contents into buffer
abm0[0] = ABM_MAGIC_KEY; // magic key
abm0[1] = BOOT_START_ADDRESS; // start address of code
abm0[2] = ABM_DEFAULT_SIZE; // Application length
abm0[3] = crc32Gen((unsigned int *)BOOT_START_ADDRESS, ABM_DEFAULT_SIZE); // CRC32 for application length
abm0[4] = crc32Gen(abm0, ABM_HEAD_SIZE-4); // CRC32 for above 4
memcpy(tmpBuf+0xe0, abm0, ABM_HEAD_SIZE); // copy ABM data into tmpBuf
// Program header in FLASH
if (flash->write((unsigned int)ABM0_BUFFER_ADDRESS, (unsigned char *)&tmpBuf, FLASH002_PAGE_SIZE) != 0) {
printf("\nFLASH write failed!\n");
return;
}
else {
if (flash->writeEnd() != 0) { // make sure last block is written to FLASH
printf("FLASH end write failed\n");
return;
}
else {
printf("\nABM0 header FLASHed OK\n");
setBMIWord();
}
}
return; // never copy freshly loaded primary booter as fallback, without at least one reset in between (in effect do a test run of the new booter!)
}
May 26, 2014
07:10 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 26, 2014
07:10 PM
Hi OMR,
Thanks for the sharing. Do you run these code in the RAM?
Best Regards
Travis
Thanks for the sharing. Do you run these code in the RAM?
Best Regards
Travis
May 27, 2014
12:45 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 27, 2014
12:45 AM
The code I posted runs in FLASH, but the following functions in the FLASH0002.c app has the __attribute__ ((section (".text.fastcode"))) applied so that those FLASH routines runs from RAM:
status_t Flash002_EraseSector (uint32_t Address)
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
status_t Flash002_EraseUCB(uint32_t UserLevel)
status_t Flash002_DisableGlobalReadProtection(uint32_t PW0, uint32_t PW1)
status_t Flash002_DisableSectorWriteProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1)
status_t Flash002_ResumeProtection()
status_t Flash002_ConfigureProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_VerifyProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_ConfigureBMI (const FLASH002BMIString_Type *BMIString)
status_t Flash002_ConfirmProtection (uint32_t UserLevel)
That is all of them I think 🙂
The .cstartup code copies all functions with fastcode attribute to RAM during startup.
status_t Flash002_EraseSector (uint32_t Address)
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
status_t Flash002_EraseUCB(uint32_t UserLevel)
status_t Flash002_DisableGlobalReadProtection(uint32_t PW0, uint32_t PW1)
status_t Flash002_DisableSectorWriteProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1)
status_t Flash002_ResumeProtection()
status_t Flash002_ConfigureProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_VerifyProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_ConfigureBMI (const FLASH002BMIString_Type *BMIString)
status_t Flash002_ConfirmProtection (uint32_t UserLevel)
That is all of them I think 🙂
The .cstartup code copies all functions with fastcode attribute to RAM during startup.
Jun 02, 2014
06:56 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jun 02, 2014
06:56 AM
Hi,
I successfully modified the ASC Bootloader example and it now programs the flash via a CAN protocol. (it still needs a lot of improvements, but works for now).
Now I have another question: Is it possible to have 2 programs in two separate parts of the flash?
I always want to make sure that I have a valid program. So if I have a valid program on the first part of the flash, I would program the second part of the flash with new code, validate the code and then start running the new code. In the next flashing process I would do the same with the first part of the flash.
Thanks,
Oliver
I successfully modified the ASC Bootloader example and it now programs the flash via a CAN protocol. (it still needs a lot of improvements, but works for now).
Now I have another question: Is it possible to have 2 programs in two separate parts of the flash?
I always want to make sure that I have a valid program. So if I have a valid program on the first part of the flash, I would program the second part of the flash with new code, validate the code and then start running the new code. In the next flashing process I would do the same with the first part of the flash.
Thanks,
Oliver
Jun 03, 2014
05:18 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jun 03, 2014
05:18 AM
As I said in post #7:
So yes, it is possible 🙂
Using the ABM fallback mode will let the ROM loader verify the crc32 of the first booter, and if it fails, it will automatically try the second one.
The boot code can jump to any code in the flash using code like this:
The code at APP_START_ADDRESS is 100% self contained, its memory layout starting with its own vector table. Of cause, any HW already set up will maintain its settings as the CPU is not reset.
It is also a good idea to disable any interrupts before making the switch.
We have had good experience with the ABM fallback mode in BMI boot mode, keeping 2 copies of the booter if the update of the primary boot image is interrupted.
We keep our primary booter @0x0C000000 (loaded by JTAG in production), fallback booter @0x0C010000 and the application @0x0C020000.
So yes, it is possible 🙂
Using the ABM fallback mode will let the ROM loader verify the crc32 of the first booter, and if it fails, it will automatically try the second one.
The boot code can jump to any code in the flash using code like this:
PPB->VTOR = APP_START_ADDRESS;
asm(
"ldr sp, [%0]\n\t"
"ldr r0, [%0, #4]\n\t"
"bx r0"
:
: "r" (APP_START_ADDRESS)
:);
The code at APP_START_ADDRESS is 100% self contained, its memory layout starting with its own vector table. Of cause, any HW already set up will maintain its settings as the CPU is not reset.
It is also a good idea to disable any interrupts before making the switch.
Jun 05, 2014
01:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jun 05, 2014
01:15 AM
Just a word of caution, that you don't overwrite the ABM header when you flash program your software into the flash.
Aug 18, 2014
06:46 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aug 18, 2014
06:46 AM
Hi again,
So my bootloader is ready. In Dave I mapped it into the PSRAM.
How can I now exactly store the bootloader code in the flash and how can I copy it to RAM during runtime?
What do I need to do with the hex file of the bootloder code?
Do I only need the Data ? without the addresses?
Can you maybe give me a short example? Thanks in advance
Oliver
So my bootloader is ready. In Dave I mapped it into the PSRAM.
How can I now exactly store the bootloader code in the flash and how can I copy it to RAM during runtime?
What do I need to do with the hex file of the bootloder code?
Do I only need the Data ? without the addresses?
Can you maybe give me a short example? Thanks in advance
Oliver
Aug 19, 2014
12:35 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aug 19, 2014
12:35 AM
I would suggest at this stage to maybe stop using the IDE for building and set up a make system?
You will need a makefile and a .ld file (also called a scatter file I think)
In your makefile, you can generate all sorts of output formats where a binary format is a 1:1 mapping of what you need to put in FLASH.
obj/%.bin: obj/%.elf
@echo "########## Creating BIN file $@ from $<"
@$(OBJCOPY) --output-target=binary $< $@
Setting up a make system is not trivial though. We had a consultant working on it for more than a week
Travis might have a simpler solution 🙂
You will need a makefile and a .ld file (also called a scatter file I think)
In your makefile, you can generate all sorts of output formats where a binary format is a 1:1 mapping of what you need to put in FLASH.
obj/%.bin: obj/%.elf
@echo "########## Creating BIN file $@ from $<"
@$(OBJCOPY) --output-target=binary $< $@
Setting up a make system is not trivial though. We had a consultant working on it for more than a week
Travis might have a simpler solution 🙂
Aug 25, 2014
11:41 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aug 25, 2014
11:41 PM
OMR wrote:
I just flashed it after generating it:
const uint32_t ABM0_HEADER_ADDRESS = 0x0c00ffe0;
unsigned int abm0[ABM_HEAD_WORDS];
if (sanityCheck(BOOT_START_ADDRESS)) {
unsigned char tmpBuf[FLASH002_PAGE_SIZE]; // minimum number of bytes to FLASH
Flash *flash = Flash::getInstance();
memcpy(tmpBuf, (unsigned char *)ABM0_BUFFER_ADDRESS, FLASH002_PAGE_SIZE); // copy flash contents into buffer
abm0[0] = ABM_MAGIC_KEY; // magic key
abm0[1] = BOOT_START_ADDRESS; // start address of code
abm0[2] = ABM_DEFAULT_SIZE; // Application length
abm0[3] = crc32Gen((unsigned int *)BOOT_START_ADDRESS, ABM_DEFAULT_SIZE); // CRC32 for application length
abm0[4] = crc32Gen(abm0, ABM_HEAD_SIZE-4); // CRC32 for above 4
memcpy(tmpBuf+0xe0, abm0, ABM_HEAD_SIZE); // copy ABM data into tmpBuf
// Program header in FLASH
if (flash->write((unsigned int)ABM0_BUFFER_ADDRESS, (unsigned char *)&tmpBuf, FLASH002_PAGE_SIZE) != 0) {
printf("\nFLASH write failed!\n");
return;
}
else {
if (flash->writeEnd() != 0) { // make sure last block is written to FLASH
printf("FLASH end write failed\n");
return;
}
else {
printf("\nABM0 header FLASHed OK\n");
setBMIWord();
}
}
return; // never copy freshly loaded primary booter as fallback, without at least one reset in between (in effect do a test run of the new booter!)
}
Hi,
I am working on a similar project - I am trying to execute a Bootloader from PSRAM. I am able to copy the bootloader to the PSRAM but i cannot start it with the Alternative Boot Mode. I think I have a problem with the header Generation - the manual of the XMC4500 doesn't say anything about the CRC32 settings, besides the polynom. Could you please tell me the CRC settings (seed value, Reflection of the Input/Output data?, XOR of the ouput?)? Do you also use the CRC (FCE) Engine of the XMC?
Thanks,
Best regards,
Gerald
Aug 26, 2014
12:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aug 26, 2014
12:15 AM
Hi Obelix,
My previous TriCore TC1767 Alternate Boot mode Example use this software CRC which is similar to the hardware CRC. Please take care of the word size as one missing byte is good to make this CRC mismatch.
My previous TriCore TC1767 Alternate Boot mode Example use this software CRC which is similar to the hardware CRC. Please take care of the word size as one missing byte is good to make this CRC mismatch.
/***********************************************************
* Coding supply by verification team
*
***********************************************************/
uword crc_gen (uword *data, uword size)
{
uword crc = 0xFFFFFFFF;
for(uword i=0; iuword word = *(data+i);
uword feedback =
((crc & (1 << 31)) ? 1 : 0) ^
((crc & (1 << 30)) ? 1 : 0) ^
((crc & (1 << 29)) ? 1 : 0) ^
((crc & (1 << 27)) ? 1 : 0) ^
((crc & (1 << 26)) ? 1 : 0) ^
((crc & (1 << 24)) ? 1 : 0) ^
((crc & (1 << 23)) ? 1 : 0) ^
((crc & (1 << 21)) ? 1 : 0) ^
((crc & (1 << 20)) ? 1 : 0) ^
((crc & (1 << 19)) ? 1 : 0) ^
((crc & (1 << 15)) ? 1 : 0) ^
((crc & (1 << 9)) ? 1 : 0) ^
((crc & (1 << 8)) ? 1 : 0) ^
((crc & (1 << 5)) ? 1 : 0);
crc = ((word ^ ((crc & 0x7fffffff) << 1)) & 0xfffffffe) | (feedback ^ ((word & 1) ? 1 : 0));
}
return crc;
}
uword Calculate_WordSize (uword start, uword end)
{
uword size;
size = (end-start);
size = size >> 2;
return size;
}
Aug 27, 2014
12:27 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Aug 27, 2014
12:27 AM
We ended up generating the CRC32 on the chip, as Infineon was unable to provide us with a SW CRC32 routine producing the same result as the HW CRC32 generator in XMC4500.
Our first idea was to have the make system generating the ABM headers, but we ended up doing it all in our application.
Here are some snippets to get you started if you decide to take this route: (ref #18 as well)
When copying the orignal booter to the fallback address, the following vectors need to be tweaked:
Our first idea was to have the make system generating the ABM headers, but we ended up doing it all in our application.
Here are some snippets to get you started if you decide to take this route: (ref #18 as well)
unsigned int Booter::crc32Gen(unsigned int *memPtr, unsigned int size)
{
unsigned int result = 0;
#if (!IS_BOOTER)
crc32Init();
crc32Chunk(memPtr, size);
result = crc32Res();
#endif
return result;
}
void Booter::crc32Init(void) // HW CRC generator, init for chunk
{
#if (!IS_BOOTER)
SCU_RESET->PRCLR2 = SCU_RESET_PRCLR2_FCERS_Msk;
while((SCU_RESET->PRSTAT2 & SCU_RESET_PRSTAT2_FCERS_Msk))
;
FCE->CLC = 0;
while((FCE->CLC & FCE_CLC_DISS_Msk))
;
FCE_KE0->CFG = 0;
FCE_KE0->CRC = 0;
#endif
}
void Booter::crc32Chunk(unsigned int *memPtr, unsigned int size) // HW CRC generator, chunk data
{
#if (!IS_BOOTER)
size >>=2; // /4 since memPtr is a word pointer
for (uint32_t i=0; iFCE_KE0->IR = *memPtr++;
}
#endif
}
unsigned int Booter::crc32Res(void) // HW CRC generator, final chunk result
{
unsigned int result = 0;
#if (!IS_BOOTER)
result = FCE_KE0->RES;
result = FCE_KE0->RES; // must be read twice, or else the result is wrong!
#endif
return result;
}
When copying the orignal booter to the fallback address, the following vectors need to be tweaked:
// adjust 0x0800xxxx vectors to 0x0801xxxx
for (unsigned int *i=(unsigned int *)tmpBuf; i<(unsigned int *)(tmpBuf+FLASH_BUFFER_SIZE); i++)
if ((*i >= BOOT_START_ADDRESS) && (*i < (BOOT_START_ADDRESS+BOOT_MAX_SIZE))) {
*i |= 0x00010000;
mods08++;
}
// adjust 0x0c00xxxx vectors to 0x0c01xxxx
for (unsigned int *i=(unsigned int *)tmpBuf; i<(unsigned int *)(tmpBuf+FLASH_BUFFER_SIZE); i++)
if ((*i >= BOOT_LOAD_ADDRESS) && (*i < (BOOT_LOAD_ADDRESS+BOOT_MAX_SIZE))) {
*i |= 0x00010000;
mods0c++;
}
Sep 09, 2014
06:54 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
06:54 AM
Hi,
I have found a problem with my Bootloader. Programs that use no Interrupts work fine.
But interrupts never occure in programs that have interrupts enabeled. How can I fix that? I read the ASC bootloader example pdf, but there it never says anything about interrupts.
Can someone help me?
I have found a problem with my Bootloader. Programs that use no Interrupts work fine.
But interrupts never occure in programs that have interrupts enabeled. How can I fix that? I read the ASC bootloader example pdf, but there it never says anything about interrupts.
Can someone help me?
Sep 09, 2014
11:50 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 09, 2014
11:50 PM
Have a look at post #14 in this thread 🙂
Sep 16, 2014
12:50 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 16, 2014
12:50 AM
Thanks to OMR, we now found the solution! 🙂
If there are interrupts used in the bootloader, it is not possible to use them in the application.
So we just rewrote the bootloader without any interrupts and it worked with the jump descriped by OMR in post #14.
If there are interrupts used in the bootloader, it is not possible to use them in the application.
So we just rewrote the bootloader without any interrupts and it worked with the jump descriped by OMR in post #14.
Sep 22, 2014
12:24 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 22, 2014
12:24 AM
Just for completeness I want to add this information.
NAR's statement about interrupts in the bootloader is not 100% accurate.
We have 3 programs loaded at all times. Two booters, one primary and one fallback and our App.
We have a CLI command for jumping to the fallback booter, and I find that I can jump from our primary booter to the fallback booter and then jump to the fallback booter from the fallback booter itself many times with no errors.
But, when starting our App and then jumping to our fallback booter, it seems that it dies after a while, or interrupts are not served, so this must be what you are seeing too.
This is normally no problem for us since the jump from booter to App is OK, and jump the other way is normally done through a reset.
So, what is the difference between our booter and App?
This is what I can think of:
1. The App start kicking the HW watchdog.
2. The App uses SPI
3. The App uses POSQE
4. The App sets up NMI from our power monitor
5. The App sets up PWM
6. The App sets up much more GPIO (polled)
They both use:
1. UART (interrupt driven)
2. CAN (interrupt driven)
3. I2C (polled)
4. HW timer slice for our us timetick (interrupt driven)
So, my guess is that one of the resources used by the App is preventing the jump to be successful, so look in the reference manual if it possible to issue peripheral reset or disable commands just prior to doing the jump after disabling the global interrupt flag.
NAR's statement about interrupts in the bootloader is not 100% accurate.
We have 3 programs loaded at all times. Two booters, one primary and one fallback and our App.
We have a CLI command for jumping to the fallback booter, and I find that I can jump from our primary booter to the fallback booter and then jump to the fallback booter from the fallback booter itself many times with no errors.
But, when starting our App and then jumping to our fallback booter, it seems that it dies after a while, or interrupts are not served, so this must be what you are seeing too.
This is normally no problem for us since the jump from booter to App is OK, and jump the other way is normally done through a reset.
So, what is the difference between our booter and App?
This is what I can think of:
1. The App start kicking the HW watchdog.
2. The App uses SPI
3. The App uses POSQE
4. The App sets up NMI from our power monitor
5. The App sets up PWM
6. The App sets up much more GPIO (polled)
They both use:
1. UART (interrupt driven)
2. CAN (interrupt driven)
3. I2C (polled)
4. HW timer slice for our us timetick (interrupt driven)
So, my guess is that one of the resources used by the App is preventing the jump to be successful, so look in the reference manual if it possible to issue peripheral reset or disable commands just prior to doing the jump after disabling the global interrupt flag.
Not applicable
Dec 11, 2014
10:17 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 11, 2014
10:17 PM
Hi ,
I am working similar project now. I try to separate Bootcode & appcode to two hex files. In Bootcode, just only have communication with Host(PC) to transmit updated appcode.hex.
When I transmit a small appcode that only have Can communication function code, it's can work now. But when I transmit a bigger one, it can't execute downloaded appcode.
Do you have some idea or suggestion??
Thanks,
Best regards,
Peter.K
I am working similar project now. I try to separate Bootcode & appcode to two hex files. In Bootcode, just only have communication with Host(PC) to transmit updated appcode.hex.
When I transmit a small appcode that only have Can communication function code, it's can work now. But when I transmit a bigger one, it can't execute downloaded appcode.
Do you have some idea or suggestion??
Thanks,
Best regards,
Peter.K
Not applicable
Dec 11, 2014
11:05 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 11, 2014
11:05 PM
Did you read back and check if the downloaded hex code are correct?
Are they place at the correct address?
Are they place at the correct address?
Not applicable
Dec 12, 2014
12:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dec 12, 2014
12:15 AM
Hi Jackson,
Yes, I have used debugger tool to check my hex code are correct and no data lose.
I think maybe appcode need to modify something.
Yes, I have used debugger tool to check my hex code are correct and no data lose.
I think maybe appcode need to modify something.
Not applicable
May 22, 2015
06:05 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 22, 2015
06:05 AM
OMR wrote:
The code I posted runs in FLASH, but the following functions in the FLASH0002.c app has the __attribute__ ((section (".text.fastcode"))) applied so that those FLASH routines runs from RAM:
status_t Flash002_EraseSector (uint32_t Address)
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
status_t Flash002_EraseUCB(uint32_t UserLevel)
status_t Flash002_DisableGlobalReadProtection(uint32_t PW0, uint32_t PW1)
status_t Flash002_DisableSectorWriteProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1)
status_t Flash002_ResumeProtection()
status_t Flash002_ConfigureProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_VerifyProtection(uint32_t UserLevel, uint32_t PW0, uint32_t PW1, FLASH002ProtectionFlags_Type ProtectionFlags)
status_t Flash002_ConfigureBMI (const FLASH002BMIString_Type *BMIString)
status_t Flash002_ConfirmProtection (uint32_t UserLevel)
That is all of them I think 🙂
The .cstartup code copies all functions with fastcode attribute to RAM during startup.
Where do you specify this attribute? is there any help file which shows how to handle this attribute? I do not want a fallback bootloader.. Can I make the program to jump to my bootloader location after startup? If yes how? Also like you I want to execute the flash routines from RAM. Please help me on this.
May 22, 2015
06:42 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 22, 2015
06:42 AM
The attribute is specified in the scatterfile xxxx.ld as supplied to the linker.
At startup it is copied from FLASH to RAM by the startup_XMC4500.s assembly routine:
In the C files, just add this attribute for every function you want to run from RAM:
No help file, as we use the GNU tool chain. Google is your friend.
If you don't want a fallback booter, updating the booter itself is a risky business.
The mentioned assembly file startup_XMC4500.s contains the vector tables. This would normally point to code that ultimately calls main() in your booter C code:
As you see, not entirely trivial, but at least I hope you can benefit somewhat from my comments 🙂
MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08020000, LENGTH = 0xa0000-0x20000
FLASH_1_uncached(RX) : ORIGIN = 0x0C020000, LENGTH = 0xa0000-0x20000
PSRAM_1_FASTCODE(!RX): ORIGIN = 0x10000000, LENGTH = 0x1000
PSRAM_1_HEAP(!RX) : ORIGIN = 0x10001000, LENGTH = 0xf000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000-32-256
DSRAM_2_bdat(!RX) : ORIGIN = 0x30000000+0x8000-32-256, LENGTH = 32
DSRAM_2_panic(!RX) : ORIGIN = 0x30000000+0x8000-256, LENGTH = 256
}
.fastcode : AT(LOADADDR(.startup) + SIZEOF(.startup))
{
__fastcode_start = .;
/* functions with __attribute__ ((section (".text.fastcode")))*/
*(.text.fastcode)
__fastcode_end = .;
} >PSRAM_1_FASTCODE
__fastcode_load = LOADADDR (.fastcode);
__fastcode_size = __fastcode_end - __fastcode_start;
At startup it is copied from FLASH to RAM by the startup_XMC4500.s assembly routine:
__Xmc4500_Program_Loader:
.fnstart
/* Memories are accessible now*/
/* DATA COPY */
/* R0 = Start address, R1 = Destination address, R2 = Size */
LDR R0, =__fastcode_load
LDR R1, =__fastcode_start
LDR R2, =__fastcode_size
BL __COPY_FLASH2RAM
In the C files, just add this attribute for every function you want to run from RAM:
__attribute__ ((section (".text.fastcode")))
status_t Flash002_EraseSector (uint32_t Address)
{
.
.
}
__attribute__ ((section (".text.fastcode")))
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
{
.
.
}
No help file, as we use the GNU tool chain. Google is your friend.
If you don't want a fallback booter, updating the booter itself is a risky business.
The mentioned assembly file startup_XMC4500.s contains the vector tables. This would normally point to code that ultimately calls main() in your booter C code:
__Xmc4500_interrupt_vector_cortex_m:
.long __Xmc4500_stack /* Top of Stack */
.long __Xmc4500_reset_cortex_m /* Reset Handler */
.
.
/* Reset Handler */
.thumb_func
.globl __Xmc4500_reset_cortex_m
.type __Xmc4500_reset_cortex_m, %function
__Xmc4500_reset_cortex_m:
.fnstart
/* C routines are likely to be called. Setup the stack now */
/* This is already setup by BootROM,hence this step is optional */
LDR SP,=__Xmc4500_stack
/* Clock tree, External memory setup etc may be done here */
LDR R0, =SystemInit
BLX R0
/*
SystemInit_DAVE3() is provided by DAVE3 code generation engine. It is
weakly defined here though for a potential override.
*/
LDR R0, =SystemInit_DAVE3
BLX R0
B __Xmc4500_Program_Loader
.
.
.
ending up calling your main() in C:
/* Reset stack pointer before zipping off to user application, Optional */
LDR SP,=__Xmc4500_stack
MOV R0,#0
MOV R1,#0
LDR PC, =main
.pool
.cantunwind
.fnend
.size __Xmc4500_Program_Loader,.-__Xmc4500_Program_Loader
As you see, not entirely trivial, but at least I hope you can benefit somewhat from my comments 🙂
Not applicable
May 26, 2015
01:24 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 26, 2015
01:24 AM
OMR wrote:
The attribute is specified in the scatterfile xxxx.ld as supplied to the linker.
MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08020000, LENGTH = 0xa0000-0x20000
FLASH_1_uncached(RX) : ORIGIN = 0x0C020000, LENGTH = 0xa0000-0x20000
PSRAM_1_FASTCODE(!RX): ORIGIN = 0x10000000, LENGTH = 0x1000
PSRAM_1_HEAP(!RX) : ORIGIN = 0x10001000, LENGTH = 0xf000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000-32-256
DSRAM_2_bdat(!RX) : ORIGIN = 0x30000000+0x8000-32-256, LENGTH = 32
DSRAM_2_panic(!RX) : ORIGIN = 0x30000000+0x8000-256, LENGTH = 256
}
.fastcode : AT(LOADADDR(.startup) + SIZEOF(.startup))
{
__fastcode_start = .;
/* functions with __attribute__ ((section (".text.fastcode")))*/
*(.text.fastcode)
__fastcode_end = .;
} >PSRAM_1_FASTCODE
__fastcode_load = LOADADDR (.fastcode);
__fastcode_size = __fastcode_end - __fastcode_start;
At startup it is copied from FLASH to RAM by the startup_XMC4500.s assembly routine:
__Xmc4500_Program_Loader:
.fnstart
/* Memories are accessible now*/
/* DATA COPY */
/* R0 = Start address, R1 = Destination address, R2 = Size */
LDR R0, =__fastcode_load
LDR R1, =__fastcode_start
LDR R2, =__fastcode_size
BL __COPY_FLASH2RAM
In the C files, just add this attribute for every function you want to run from RAM:
__attribute__ ((section (".text.fastcode")))
status_t Flash002_EraseSector (uint32_t Address)
{
.
.
}
__attribute__ ((section (".text.fastcode")))
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
{
.
.
}
No help file, as we use the GNU tool chain. Google is your friend.
If you don't want a fallback booter, updating the booter itself is a risky business.
The mentioned assembly file startup_XMC4500.s contains the vector tables. This would normally point to code that ultimately calls main() in your booter C code:
__Xmc4500_interrupt_vector_cortex_m:
.long __Xmc4500_stack /* Top of Stack */
.long __Xmc4500_reset_cortex_m /* Reset Handler */
.
.
/* Reset Handler */
.thumb_func
.globl __Xmc4500_reset_cortex_m
.type __Xmc4500_reset_cortex_m, %function
__Xmc4500_reset_cortex_m:
.fnstart
/* C routines are likely to be called. Setup the stack now */
/* This is already setup by BootROM,hence this step is optional */
LDR SP,=__Xmc4500_stack
/* Clock tree, External memory setup etc may be done here */
LDR R0, =SystemInit
BLX R0
/*
SystemInit_DAVE3() is provided by DAVE3 code generation engine. It is
weakly defined here though for a potential override.
*/
LDR R0, =SystemInit_DAVE3
BLX R0
B __Xmc4500_Program_Loader
.
.
.
ending up calling your main() in C:
/* Reset stack pointer before zipping off to user application, Optional */
LDR SP,=__Xmc4500_stack
MOV R0,#0
MOV R1,#0
LDR PC, =main
.pool
.cantunwind
.fnend
.size __Xmc4500_Program_Loader,.-__Xmc4500_Program_Loader
As you see, not entirely trivial, but at least I hope you can benefit somewhat from my comments 🙂
Hey OMR
Thank you for the reply. I think I understand what your trying to say. But few more questions:
1) I only have a .sct file and no LD file in my project. What are your views on that. I tried changing the extension to LD but i think sct and ld are the same. Can you share your XMC4500 sct or LD file with me please?
2) Can you explain a bit more in detail about your fallback boot mode strategy.
3) Can you share your flash library with me. I feel i do not have the latest one as some routines described by you are not defined in my library.
my emails ID is c_sgopak@qti.qualcomm.com Please share if possible. Will be of great help 😉
Thanks
Not applicable
May 26, 2015
10:43 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 26, 2015
10:43 AM
OMR wrote:
The attribute is specified in the scatterfile xxxx.ld as supplied to the linker.
MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08020000, LENGTH = 0xa0000-0x20000
FLASH_1_uncached(RX) : ORIGIN = 0x0C020000, LENGTH = 0xa0000-0x20000
PSRAM_1_FASTCODE(!RX): ORIGIN = 0x10000000, LENGTH = 0x1000
PSRAM_1_HEAP(!RX) : ORIGIN = 0x10001000, LENGTH = 0xf000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000-32-256
DSRAM_2_bdat(!RX) : ORIGIN = 0x30000000+0x8000-32-256, LENGTH = 32
DSRAM_2_panic(!RX) : ORIGIN = 0x30000000+0x8000-256, LENGTH = 256
}
.fastcode : AT(LOADADDR(.startup) + SIZEOF(.startup))
{
__fastcode_start = .;
/* functions with __attribute__ ((section (".text.fastcode")))*/
*(.text.fastcode)
__fastcode_end = .;
} >PSRAM_1_FASTCODE
__fastcode_load = LOADADDR (.fastcode);
__fastcode_size = __fastcode_end - __fastcode_start;
At startup it is copied from FLASH to RAM by the startup_XMC4500.s assembly routine:
__Xmc4500_Program_Loader:
.fnstart
/* Memories are accessible now*/
/* DATA COPY */
/* R0 = Start address, R1 = Destination address, R2 = Size */
LDR R0, =__fastcode_load
LDR R1, =__fastcode_start
LDR R2, =__fastcode_size
BL __COPY_FLASH2RAM
In the C files, just add this attribute for every function you want to run from RAM:
__attribute__ ((section (".text.fastcode")))
status_t Flash002_EraseSector (uint32_t Address)
{
.
.
}
__attribute__ ((section (".text.fastcode")))
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
{
.
.
}
No help file, as we use the GNU tool chain. Google is your friend.
If you don't want a fallback booter, updating the booter itself is a risky business.
The mentioned assembly file startup_XMC4500.s contains the vector tables. This would normally point to code that ultimately calls main() in your booter C code:
__Xmc4500_interrupt_vector_cortex_m:
.long __Xmc4500_stack /* Top of Stack */
.long __Xmc4500_reset_cortex_m /* Reset Handler */
.
.
/* Reset Handler */
.thumb_func
.globl __Xmc4500_reset_cortex_m
.type __Xmc4500_reset_cortex_m, %function
__Xmc4500_reset_cortex_m:
.fnstart
/* C routines are likely to be called. Setup the stack now */
/* This is already setup by BootROM,hence this step is optional */
LDR SP,=__Xmc4500_stack
/* Clock tree, External memory setup etc may be done here */
LDR R0, =SystemInit
BLX R0
/*
SystemInit_DAVE3() is provided by DAVE3 code generation engine. It is
weakly defined here though for a potential override.
*/
LDR R0, =SystemInit_DAVE3
BLX R0
B __Xmc4500_Program_Loader
.
.
.
ending up calling your main() in C:
/* Reset stack pointer before zipping off to user application, Optional */
LDR SP,=__Xmc4500_stack
MOV R0,#0
MOV R1,#0
LDR PC, =main
.pool
.cantunwind
.fnend
.size __Xmc4500_Program_Loader,.-__Xmc4500_Program_Loader
As you see, not entirely trivial, but at least I hope you can benefit somewhat from my comments 🙂
Hi OMR,
I am using the flash routines and not executing it from RAM. the address which program block is executing is 0x08000ECC and it is able to program the sector beginning from 0x8010000. How is this possible. I am able tto read the data which i am programming. Please tell how is this happening. I am totally confused.
Sarath
Not applicable
May 26, 2015
10:45 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 26, 2015
10:45 AM
OMR wrote:
The attribute is specified in the scatterfile xxxx.ld as supplied to the linker.
MEMORY
{
FLASH_1_cached(RX) : ORIGIN = 0x08020000, LENGTH = 0xa0000-0x20000
FLASH_1_uncached(RX) : ORIGIN = 0x0C020000, LENGTH = 0xa0000-0x20000
PSRAM_1_FASTCODE(!RX): ORIGIN = 0x10000000, LENGTH = 0x1000
PSRAM_1_HEAP(!RX) : ORIGIN = 0x10001000, LENGTH = 0xf000
DSRAM_1_system(!RX) : ORIGIN = 0x20000000, LENGTH = 0x10000
DSRAM_2_comm(!RX) : ORIGIN = 0x30000000, LENGTH = 0x8000-32-256
DSRAM_2_bdat(!RX) : ORIGIN = 0x30000000+0x8000-32-256, LENGTH = 32
DSRAM_2_panic(!RX) : ORIGIN = 0x30000000+0x8000-256, LENGTH = 256
}
.fastcode : AT(LOADADDR(.startup) + SIZEOF(.startup))
{
__fastcode_start = .;
/* functions with __attribute__ ((section (".text.fastcode")))*/
*(.text.fastcode)
__fastcode_end = .;
} >PSRAM_1_FASTCODE
__fastcode_load = LOADADDR (.fastcode);
__fastcode_size = __fastcode_end - __fastcode_start;
At startup it is copied from FLASH to RAM by the startup_XMC4500.s assembly routine:
__Xmc4500_Program_Loader:
.fnstart
/* Memories are accessible now*/
/* DATA COPY */
/* R0 = Start address, R1 = Destination address, R2 = Size */
LDR R0, =__fastcode_load
LDR R1, =__fastcode_start
LDR R2, =__fastcode_size
BL __COPY_FLASH2RAM
In the C files, just add this attribute for every function you want to run from RAM:
__attribute__ ((section (".text.fastcode")))
status_t Flash002_EraseSector (uint32_t Address)
{
.
.
}
__attribute__ ((section (".text.fastcode")))
status_t Flash002_WritePage (uint32_t Address, const uint32_t pBuf[])
{
.
.
}
No help file, as we use the GNU tool chain. Google is your friend.
If you don't want a fallback booter, updating the booter itself is a risky business.
The mentioned assembly file startup_XMC4500.s contains the vector tables. This would normally point to code that ultimately calls main() in your booter C code:
__Xmc4500_interrupt_vector_cortex_m:
.long __Xmc4500_stack /* Top of Stack */
.long __Xmc4500_reset_cortex_m /* Reset Handler */
.
.
/* Reset Handler */
.thumb_func
.globl __Xmc4500_reset_cortex_m
.type __Xmc4500_reset_cortex_m, %function
__Xmc4500_reset_cortex_m:
.fnstart
/* C routines are likely to be called. Setup the stack now */
/* This is already setup by BootROM,hence this step is optional */
LDR SP,=__Xmc4500_stack
/* Clock tree, External memory setup etc may be done here */
LDR R0, =SystemInit
BLX R0
/*
SystemInit_DAVE3() is provided by DAVE3 code generation engine. It is
weakly defined here though for a potential override.
*/
LDR R0, =SystemInit_DAVE3
BLX R0
B __Xmc4500_Program_Loader
.
.
.
ending up calling your main() in C:
/* Reset stack pointer before zipping off to user application, Optional */
LDR SP,=__Xmc4500_stack
MOV R0,#0
MOV R1,#0
LDR PC, =main
.pool
.cantunwind
.fnend
.size __Xmc4500_Program_Loader,.-__Xmc4500_Program_Loader
As you see, not entirely trivial, but at least I hope you can benefit somewhat from my comments 🙂
Also i do not have a ld file. I have .sct scatter file. the above syntax throws in an error. Any idea how to handle this.
Sarath
May 27, 2015
01:01 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 27, 2015
01:01 AM
What tool chain do you use?
I just Googled 'scatterfile' and found this: http://infocenter.arm.com/help/topic/com.arm.doc.kui0101a/armlink_babddhbf.htm
Might help you out.
I just Googled 'scatterfile' and found this: http://infocenter.arm.com/help/topic/com.arm.doc.kui0101a/armlink_babddhbf.htm
Might help you out.
Not applicable
May 27, 2015
02:35 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 27, 2015
02:35 AM
OMR wrote:
What tool chain do you use?
I just Googled 'scatterfile' and found this: http://infocenter.arm.com/help/topic/com.arm.doc.kui0101a/armlink_babddhbf.htm
Might help you out.
Hi OMR
Thanks for your reply!!
I am using Keil Microvision toolchain version 5.
Anyways, Do you have any comments on my earlier question ? I am able to program the flash while executing code from flash. is it possible to program/erase a page from another sector while executing code from other sector? I am confused. Can you please give me your thoughts?
Sarath
Not applicable
May 27, 2015
02:36 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 27, 2015
02:36 AM
OMR wrote:
What tool chain do you use?
I just Googled 'scatterfile' and found this: http://infocenter.arm.com/help/topic/com.arm.doc.kui0101a/armlink_babddhbf.htm
Might help you out.
If possible can you please share your email ID. will be of great help. thanks 🙂
Not applicable
May 28, 2015
01:38 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 28, 2015
01:38 AM
Hey OMR
Thanks! I am able to write to flash without any speciall commands. I do not know why. But I am not able to jump to the code location. Can you please advice me on this?
Sarath
Thanks! I am able to write to flash without any speciall commands. I do not know why. But I am not able to jump to the code location. Can you please advice me on this?
Sarath
Not applicable
May 28, 2015
01:40 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 28, 2015
01:40 AM
Also i am totally confused by the behavior of flash. I am just using the flash library to program and erase and it does it ..without running it from RAM. Can you please try it. I also ran the code without debugger connected and yet it flashed. Can you come up with any explanation for such a behavior?
Sarath
Sarath
Not applicable
May 28, 2015
04:41 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 28, 2015
04:41 AM
Hi OMR
here are some more details:
Booter start address: 0x08000000
App start address: 0x08004000
APP sw hex has been generated using a different Keil Project with the standard Startup sftware provided . But when I try to make the jump from booter to app at the end the program counter does not mae the jump but stays in the booter section. I have build the app sw using 0x08004000 start address in the app scatter file. what other precautions should I take. I am not using any special boot modes.
Sarath
here are some more details:
Booter start address: 0x08000000
App start address: 0x08004000
APP sw hex has been generated using a different Keil Project with the standard Startup sftware provided . But when I try to make the jump from booter to app at the end the program counter does not mae the jump but stays in the booter section. I have build the app sw using 0x08004000 start address in the app scatter file. what other precautions should I take. I am not using any special boot modes.
Sarath
Not applicable
May 28, 2015
05:15 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 28, 2015
05:15 AM
Obelix wrote:
Hi,
I am working on a similar project - I am trying to execute a Bootloader from PSRAM. I am able to copy the bootloader to the PSRAM but i cannot start it with the Alternative Boot Mode. I think I have a problem with the header Generation - the manual of the XMC4500 doesn't say anything about the CRC32 settings, besides the polynom. Could you please tell me the CRC settings (seed value, Reflection of the Input/Output data?, XOR of the ouput?)? Do you also use the CRC (FCE) Engine of the XMC?
Thanks,
Best regards,
Gerald
How did you write to flash just those 5 bytes?? Which flash API did you use?
Sarath
May 29, 2015
01:29 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
May 29, 2015
01:29 AM
I have no experience with the Kiel tool chain, but if you look in the ,map file produced by the linker, you might find that the flash routines have RAM addresses?
It could also be that the newer FLASH library works some magic behind the scenes, or that it worked by chance because you where executing code from a different sector?
I don't have the time to dig into this, but maybe someone from Infineon could chime in?
How do you jump from your booter to the application?
I have included the code needed to make the jump in a previous post.
If you want to write just 5 bytes, you must read the whole contents of the target sector into RAM, modify the 5 bytes in RAM, erase the sector, and write it back.
It could also be that the newer FLASH library works some magic behind the scenes, or that it worked by chance because you where executing code from a different sector?
I don't have the time to dig into this, but maybe someone from Infineon could chime in?
How do you jump from your booter to the application?
I have included the code needed to make the jump in a previous post.
If you want to write just 5 bytes, you must read the whole contents of the target sector into RAM, modify the 5 bytes in RAM, erase the sector, and write it back.