2021-06-18 12:29 AM
Hi,
I am using LED blink firmware generated using CUBE-MX by Disabling all the modes and Clearing the pinouts.
I flashed one firmware in the bank-1 (0x08000000) and
second firmware(with few changes the way the led blinks) flashed into the bank-2 (0x08018000) using the stm32 programmer.
First I writing the firmware-2 into bank-2 like this.
Next I am flashing the firmware-1 in the bank-1 and running .
I kept the bank switch logic in firmware-1.
My main() fun will look like this:
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
__HAL_RCC_SYSCFG_CLK_ENABLE();
int i = 9;
while (i > 0)
{
// printf("LED BLINK\n");
/* USER CODE END WHILE */
HAL_GPIO_WritePin(GPIOB, greenLed_Pin, GPIO_PIN_RESET);
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOB, greenLed_Pin, GPIO_PIN_SET);
HAL_Delay(1000);
i--;
}
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
FLASH_OB_BootConfig(OB_BOOT_BANK2);
if(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_MEM_MODE) == 0)
{
HAL_GPIO_WritePin(GPIOB, RedLed_Pin|BlueLed_Pin, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, RedLed_Pin| BlueLed_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB);
if(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB) == 1)
{
HAL_GPIO_WritePin(GPIOB, BlueLed_Pin, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, BlueLed_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, greenLed_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
}
else
{
HAL_GPIO_WritePin(GPIOB, RedLed_Pin, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, RedLed_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOB, greenLed_Pin, GPIO_PIN_RESET);
HAL_Delay(2000);
}
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
NVIC_SystemReset();
}
Leds I kept for the debug. The code is executing till the leds BLUE and RED glowing together and fading (line 36) after that I am not able to see the leds. So I am thinking it got stuck at
SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB);
Is this aporach is right? Anything else is required? Please suggest?
Thanks
Shabaz
2021-06-18 04:27 AM
Hello @shabaz704 ,
not all STM32 handle the dual bank configuration the same way. What particular product are you using?
Normally live code switching between the banks is not encouraged. You need to take care of the interrupts, make sure the next fetch is safely determined and so on. If you really need your code to perform such tricks, try reading our AN4767.
Rgds,
J.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2021-06-20 12:43 AM
Thank you @JHOUD,
I am using the B-L072z-LRWAN1 board. In stm32L0x2 MCU datasheet mentioned as it will have two banks.
Can you please suggest any example code for bank switch for booting?
I am actually trying to perform FUOTA over lorawan. For this purpose, I am trying this with a small application.
2021-06-20 11:50 PM
@shabaz704 the DBFU example includes a L073 code which should help you:
J.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2021-06-22 03:46 AM
We have refered the above suggested code and integrated same in our application as well.
But still we are unable to set UFB bit from SYSCFG_CFGR1 register. We have gone through datasheet and did not find anything regarding write protection of SYSCFG_CFGR1 register.
static uint32_t Bank_Swap( void )
{
__disable_irq();
/* disable buffer */
SET_BIT(FLASH->ACR, FLASH_ACR_DISAB_BUF);
/* branch based on the current bank setting */
if (READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB) == 0 )
{
// debug print
sprintf(uartBuf, "SYSCFG_CFGR1_UFB setting\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)uartBuf, strlen(uartBuf), 100);
SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB);
if (READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB) == 1 )
{
sprintf(uartBuf, "SYSCFG_CFGR1_UFB 1\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)uartBuf, strlen(uartBuf), 100);
}
}
else
{
CLEAR_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB);
}
/* enable buffers */
CLEAR_BIT(FLASH->ACR, FLASH_ACR_DISAB_BUF);
/* Note - this does not restore pre-read or prefetch */
if (READ_BIT(FLASH->ACR, FLASH_ACR_DISAB_BUF) == 0 )
{
// debug print
sprintf(uartBuf, "FLASH->ACR cleared\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)uartBuf, strlen(uartBuf), 100);
}
/* restore interrupt capability */
__enable_irq();
// debug print
sprintf(uartBuf, "bank swap end\r\n");
HAL_UART_Transmit(&huart2, (uint8_t *)uartBuf, strlen(uartBuf), 100);
return 0;
}
I am able to see the prints only till the line-13.
So, it again stuck at SET_BIT (line-15).
What can be the problem?
2021-06-23 08:49 PM
Hi,
The problem resolved for me by simply ignoring the UFB bit in SYSCFG register. I am not setting it.
By setting BFB2 to 1 itself done the boot form directly from bank2. It's seems the bank swap also done by BFB2 itself. Because when we read the data from the banks after the BFB2 bit set the data from BANK2 is present at the BANK1 address i.e., 0x08000000.
This worked for this board I didn't tested with any other board.
Thank you
2021-06-23 09:59 PM
Hi, be carefull to not write option bytes each boot! It is stored in flash. You can easily reach max write cycles of flash and also when power can be lost at anytime you can corrupt option bytes.
An other way is to have custom bootloader that chose beetwen two app (one in each flash bank). Part of code making dynamic bank swap and App launch MUST be located in RAM (so no printf an d no Irq during bank swap)
Tested Ok on stm32f429 from years.
2021-06-23 11:14 PM
Hi @GLASS ,
"Part of code making dynamic bank swap and App launch MUST be located in RAM"
Can you elaborate about this statement.
What I understood from "dynamic bank swap" is to use the UFB bit.Right?
If that the case we are unable to set the UFB bit. The code execution is getting stuck at that specific instruction.
SET_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_UFB);
2021-06-23 11:35 PM
If you execute code to swap bank flash from flash the next instruction fetch has à very large chance to crash... so the part of code that swap ths bank flash MUST be located in Ram. You MUST also consider that debugger is not aware of bank flash swap. So this difficult piece of code is also difficult to debug...
2021-06-24 04:32 AM
@shabaz704 ,
the BFB2 sets the device to actually swap the banks automatically using the same UFB bit. The fact that it works using BFB2 and not directly may suggest that there is a problem when fetching the next instruction from the other bank. Placing the switch code to SRAM as @GLASS suggested is a good idea how to avoid such problem. You can also check the addresses in the map file to see differences between linking of the two code versions. You should pay special attention to interrupt vectors too. But that's also part of the AN4767.
J.
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.