cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f072 can not remap memory: SYSCFG CFGR1 has no effect

Florian Delizy
Associate II
Posted on November 01, 2017 at 18:44

Hi,

I am trying to write a generic bootloader for STM32F072, I read countless reports on this forum (and other on the Internet), that basically states the following procedure:

  1. disable interrupts
  2. Install the partition ISR (first 48 words) into SRAM base (0x2000000)
  3. use SYSCFG CFGR1 to remap 0x0 to point to SRAM base (0x20000000)
  4. read the 2nd word of the ISR and jump to it (application will have to re-enable interrupts

So that is basically what I am doing, but after checking using a debug probe (JLink), it seems that even if I remap the 0x0 to point to SRAM, in fact, the setting has no effect. Here is the content of a quick debug session (using gdb):

gdb$ x /1xw 0x40010000
0x40010000:0x00000003
gdb$ x /48xw 0x0
0x0:0x200040000x08000e290x080005090x0800050b
0x10:0x000000000x000000000x000000000x00000000
0x20:0x000000000x000000000x000000000x08000e75
0x30:0x000000000x000000000x08000e750x0800050f
0x40:0x08000e750x08000e750x08000e750x08000e75
0x50:0x08000e750x08000e750x08000e750x08000e75
0x60:0x08000e750x08000e750x08000e750x08000e75
0x70:0x08000e750x08000e750x08000e750x08000e75
0x80:0x08000e750x08000e750x08000e750x08000e75
0x90:0x08000e750x08000e750x08000e750x08000e75
0xa0:0x08000e750x08000e750x08000e750x08000e75
0xb0:0x08000e750x08000e750x08000e750x08000e75
gdb$ x /48xw 0x20000000
0x20000000:0x200040000x08018d290x0800c2510x0800c25b
0x20000010:0x000000000x000000000x000000000x00000000
0x20000020:0x000000000x000000000x000000000x080020c1
0x20000030:0x000000000x000000000x080021370x08002143
0x20000040:0x08018d750x08018d750x08018d750x08018d75
0x20000050:0x08018d750x080031f50x080031d50x080031a9
0x20000060:0x08018d750x08018d750x08018d750x08018d75
0x20000070:0x08018d750x08018d750x08018d750x08018d75
0x20000080:0x08018d750x08018d750x08018d750x08018d75
0x20000090:0x08018d750x08018d750x08018d750x08018d75
0x200000a0:0x08018d750x08018d750x08018d750x08018d75
0x200000b0:0x08018d750x08018d750x55aa55aa0x55aa55aa�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

So basically as you can see in this copy/paste the SYSCFG CFGR1 two LSB bits are 1 (so 0x0 should point to SRAM), but the content of 0x0 and 0x20000000 addresses are different ?? How could that be?

Here is the relevant part of the code that set the CFGR1 bits:

 __disable_irq();
 *sramISR = *isr; // copy isr to sram ISR (0x20000000)
 __HAL_RCC_AHB_FORCE_RESET();
 __HAL_RCC_SYSCFG_CLK_ENABLE();
 __HAL_RCC_AHB_RELEASE_RESET();
 __HAL_SYSCFG_REMAPMEMORY_SRAM();
 // Breakpoint right here to check in gdb.
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

What am I doing wrong? any insight would be greatly appreciated.

#remap #memory-remap #stm32f7-hal #embedded-bootloader #stm32f07
12 REPLIES 12
Posted on November 02, 2017 at 20:25

Seems I have to uphill ski this...

The LR contains a special value EXC_RETURN, part of that value indicates which stack is being used, thus you must inspect it to determine where to look, not hard code PSP.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/Babefdjc.html

 

What value is in LR at the SVC_Handler entry?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on November 03, 2017 at 02:33

ok, after reading this:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/Babefdjc.html

 

I understand what you told me, it gives you the stack type, not the return address. (sorry for my confusion).

and in that specific case, the exception should get the stack from MSP not PSP. (Also, I don't hardcode PSP in any way, this is standard cmsis RTX code that you see here.)

Anyway, to answer: stepping instruction by instruction, right after the SVC instruction, lr becomes 0xfffffff9 (thread info, stack on MSP).

The SVC_HANDLER code from RTX is trying to fetch the stack off PSP instead. Since I did not modify this, there must be a configuration somewhere that was changed to get this stack from the wrong place. How do you change this? (must be something I did not deinit or set wrong in the bootloader then). (I am checking where the control could have been set wrong in the begining).

Florian Delizy
Associate II
Posted on November 03, 2017 at 03:42

After some check, I found that I inverted by accident two calls so that I called an svc before callingosKernelInitialize() it was causing the control to be set wrong. It now crashes somewhere else (randomly) and it looks like an interrupt issue again.

To answer the initial question, since the svc call actually jumps to the right address (stored in RAM not on flash 0x8000000), it seems that really the interrupt vector had been remapped (at least the core takes it that way), but debugger and thread program still read 0x0 to be pointed at the flash.

My MCU seems to be in an intermediate state where the exception really reads 0x0 at the place it should be mapped to (RAM start), but the rest of the execution (and the debug probe memory reading) seems to ignore the mapping. This is very odd, I did not think it was possible…

Is there anything that could cause this?

My jump code now looks like this:

 __disable_irq();
 // Must reset al the EXTI* registers to 0
 NVIC_DisableIRQ(SysTick_IRQn);
 for (int i=0; i <32; i++) {
 NVIC_DisableIRQ(static_cast<IRQn_Type>(i));
 NVIC_ClearPendingIRQ(static_cast<IRQn_Type>(i));
 }
 // Prepare for flash remap depending on the address start
 __DSB();
 __ISB();
 __HAL_RCC_AHB_FORCE_RESET();
 __HAL_RCC_SYSCFG_CLK_ENABLE();
 __HAL_RCC_AHB_RELEASE_RESET();
 __DSB();
 switch (reinterpret_cast<uintptr_t >(isr)) {
 case FLASH_BASE:
 __HAL_SYSCFG_REMAPMEMORY_FLASH();
 break;
 case SYSTEM_FLASH_BASE:
 __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
 break;
 case SRAM_BASE:
 __HAL_SYSCFG_REMAPMEMORY_SRAM();
 break;
 default:
 *sramISR = *isr;
 __HAL_SYSCFG_REMAPMEMORY_SRAM();
 break;
 }
 __DSB();
 __ISB();
 HAL_DeInit();
 HAL_RCC_DeInit();

 __enable_irq();
 __set_MSP(isr->_estack);
 __DSB();
 __ISB();
 // Then perform the jump
 asm volatile ( 
 'bx %0'
 : /* no output */ 
 : 'r' (isr->Reset_Handler)
 : /* no clobber */
 );
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The bootloader does not use Rtx (so does not modify the control SysTick->CTRL register).

The code now fails on a Hard Fault in the application __svcKernelStart, but I can not reproduce it when stepping over with the debugger, (it fails somewhere else instead)…

Must still be something wrong in the bootloader, but not quite sure what just yet.