Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 5, 2012
Folks,

I have a bootloader for the STM32 working on a program that is run-to-complete. Another node in this project runs FreeRTOS and although it seems I can load the image using the bootloader, it just gets stuck in the SVC_Handler when I try and run it.

If I try and run FreeRTOS at 0x8003000 (which is where the bootloader sticks FreeRTOS rather than 0x8000000) it also doesn't run.

With my run-to-complete program I was simply able to recompile to be at 0x8003000 and it ran fine. Is the something else I have to do when recompiling for FreeRTOS to run further up in memory please?

Thanks!

Rob

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Dave on July 5, 2012
FreeRTOS needs three handlers to be installed in the Cortex vector table. When you jump from your bootloader code to the FreeRTOS code, are you remapping the vector table to where ever you have it in your memory map (probably at 0x8003000 as it is normally at 0x00000000).

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 5, 2012
Hi Dave,

I am, indeed, remapping the vector table as follows:


void JumpToNormalApplication(void)
{

volatile unsigned long JumpAddress;

SCB_VTOR = (unsigned long)0x8003000;
JumpAddress = *(volatile unsigned long*) (0x8003000 + 4);
Jump_To_Application = (pFunction) JumpAddress;
Jump_To_Application();

}

This is exactly how I do it with the bootloader that works fine with my run-to-complete program that runs on a different pieice of hardware but still with an almost identical STM32 (the one that works is a 64k part, the FreeRTOS one a 128k part). I am wondering whether there's something extra that is needed with FreeRTOS I'm not aware of.

Thanks for the help.

Rob

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 5, 2012
It is not something I have direct experience of, but this topic comes up from time to time. I recommend entering "bootloader" as a search term into the archive to see what turns up.

http://www.freertos.org/FreeRTOS_Support_Forum_Archive/freertos_support_forum_archive_index.html

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 6, 2012
Having ploughed through those I can see a lot of no-solves, one or two aha moments without actually explaining what it was and some talking about interrupts being left over from the bootloader being serviced when FreeRTOS starts. I only have one interrupt enabled in the bootloader and that is the UART. There are definitely no interrupts pending before I hit the OS.

When I tyy and run the version of FreeRTOS that is compiled to start at 0x8003000 I get stuck here:

void vPortStartFirstTask( void )
{
__asm volatile(
" ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
" ldr r0, [r0] \n"
" ldr r0, [r0] \n"
" msr msp, r0\n" /* Set the msp back to the start of the stack. */
" svc 0\n" /* System call to start first task. */
);
}

It's the last line:

svc 0

That jumps off to address 0x00020E which has this to keep jumping back to itself.

E7FE b 0x0800020E

I suspect that maybe there's something hardcoded in FreeRTOS that is jumping to where it thinks the vector table should be? If that's the case, it's probably nothing to do with the bootloader but somethign else in FreeRTOS needs changing when remapped?

svc seems to be something to do with supervisor mode. I must confess I don't understamd what supervisor mode is.

Thanks again.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
" msr msp, r0\n" /* Set the msp back to the start of the stack. */
" svc 0\n" /* System call to start first task. */


It looks like you are using quite an old version of FreeRTOS. The code sequence should be:

" msr msp, r0\n" /* Set the msp back to the start of the stack. */
"cpsie \n"
" svc 0\n" /* System call to start first task. */


The extra line is only required if interrupts are in the wrong state when the function is called - which would not normally happen with a standard reboot power up sequence, but in your case could well happen when you come through the boot loader.

“0x00020E”


This address looks like it is in your bootloader code, if the application code is starting at 0x8003000. As it is just jumping to itself it sounds like it is a default handler for something, but which handler?

If it is a hard fault handler, then the additional cpsie instruction as above will fix that, but even then it still seems to be using the boot loaders vector table.

If it is the SVC handler, and it is the boot loaders SVC handler, then it looks like the vector table is not remapped as you expect.

If it is the SVC handler, but a default SVC handler for the application, then it looks like the FreeRTOS interrupt handler has not been installed into the applications vector table.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 6, 2012
The thing is, this is not the bootloader version that I have found this problem with. This is just normal FreeRTOS - no bootloader involved right now - with the start of code remapped in the linker to start from 0x8003000. I am having a go, not using the bootloader to try and suss out whether it's something to do with the bootloader or the remapping of FreeRTOS. The fact that is is falling over when I do this, suggests to my simple mind that with FreeRTOS, there's more to do than simply change the start of code inn the linker to the new address from 0x8000000.

I can do this with my run-to-complete program on the other STM32 based bit of hardware in the project.

That address should read 0x0800020E, not 0x00020E - sorry about that.

The port is around two years old by the way.




RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
Ok, I didn't realise that.

When a Cortex-M boots it expects to find the vector table at address 0. The first thing in the vector table is the address of its stack and the second the address of the program entry point. In your current experiment, without the bootloader, presumably you only have one vector table and you are not remapping it, so the second entry in the vector table should point somewhere above 0x8003000.

From previous posts, it looks like the entry point is being hit correctly, because you are getting as far as vPortStartFirstTask(). When the SVC instruction is hit, you say it then starts executing a handler at 0x0800020E, so it also appears to be the case that it is running a handler in the correct address range too - so the vector table at address 0 is causing a jump to an address above 0x8003000. All good so far. Do I have this right now?

So what happens then is the mystery.

Have you determined the function that is actually being executed when it is branching to itself? It is definitely not the FreeRTOS SVC call handler, so again it is either a default handler for the SVC call (in which case the FreeRTOS handler is not installed in the vector table correctly) or it is a fault handler. I think we need to determine which it is, and the map file produced by the linker should be able to tell you (if not just breaking in the debugger and attempting to look at the source code view).

How are you installing the FreeRTOS interrupt vectors into the vector table? There are two methods that can be used, either by modifying the vector table directly, or by mapping the FreeRTOS interrupts to their CMSIS equivalents if you are using a CMSIS compliant vector table.

Can you post the vector table?

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 6, 2012
I hope what is below is what you're after in regards the vector table.

All I am doing to normal FreeRTOS is going into the xml file that descibes the processor and changing the memory map for flash to start at 0x8003000 and change its length accordingly. I would stress that if I do this for a normal run-to-compete program then everything works fine, both as a standalone program and with the bootloader.

If I look into memory at address zero with the debugger it has:

0x200001A4
0x080001F1

I would have thought all addresses should be above 0x8003000 as that is where everything has been shifted to as a base address.

.vectors        0x08003000      0x130
0x08003000 __vectors_start__ = .
*(.vectors .vectors.*)
.vectors 0x08003000 0x130 THUMB Flash Debug/STM32F10x_Startup.o
0x08003000 _vectors
0x08003130 __vectors_end__ = (__vectors_start__ + SIZEOF (.vectors))
0x08003130 __vectors_load_end__ = __vectors_end__
0x00000001 . = ASSERT (((__vectors_end__ >= __FLASH_segment_start__) && (__vectors_end__ <= (__FLASH_segment_start__ + 0x1d000))), error: .vectors is too large to fit in FLASH memory segment)
0x08003130 __init_load_start__ = ALIGN (__vectors_end__, 0x4)

.init 0x08003130 0x202
0x08003130 __init_start__ = .
*(.init .init.*)
.init 0x08003130 0x108 THUMB Flash Debug/thumb_crt0.o
0x08003130 _start
0x080031b2 exit
.init 0x08003238 0xfa THUMB Flash Debug/STM32F10x_Startup.o
0x08003238 reset_handler
0x0800323a NMIException
0x0800323c HardFaultException
0x0800323e MemManageException
0x08003240 BusFaultException
0x08003242 UsageFaultException
0x08003244 SVCHandler
0x08003246 DebugMonitor
0x08003248 PendSV
0x0800324a SysTickHandler
0x0800324c WWDG_IRQHandler
0x0800324e PVD_IRQHandler
0x08003250 TAMPER_IRQHandler
0x08003252 RTC_IRQHandler
0x08003254 FLASH_IRQHandler
0x08003256 RCC_IRQHandler
0x08003258 EXTI0_IRQHandler
0x0800325a EXTI1_IRQHandler
0x0800325c EXTI2_IRQHandler
0x0800325e EXTI3_IRQHandler
0x08003260 EXTI4_IRQHandler
0x08003262 DMAChannel1_IRQHandler
0x08003264 DMAChannel2_IRQHandler
0x08003268 DMAChannel4_IRQHandler
0x0800326c DMAChannel6_IRQHandler
0x08003270 ADC_IRQHandler
0x08003272 USB_HP_CAN_TX_IRQHandler
0x08003276 CAN_RX1_IRQHandler
0x08003278 CAN_SCE_IRQHandler
0x0800327a EXTI9_5_IRQHandler
0x0800327c TIM1_BRK_IRQHandler
0x0800327e TIM1_UP_IRQHandler
0x08003280 TIM1_TRG_COM_IRQHandler
0x08003282 TIM1_CC_IRQHandler
0x08003284 TIM2_IRQHandler
0x08003286 TIM3_IRQHandler
0x08003288 TIM4_IRQHandler
0x0800328a I2C1_EV_IRQHandler
0x0800328c I2C1_ER_IRQHandler
0x0800328e I2C2_EV_IRQHandler
0x08003290 I2C2_ER_IRQHandler
0x08003292 SPI1_IRQHandler
0x08003294 SPI2_IRQHandler
0x0800329a USART3_IRQHandler
0x0800329c EXTI15_10_IRQHandler
0x0800329e RTCAlarm_IRQHandler
0x080032a0 USBWakeUp_IRQHandler
0x080032a2 TIM8_BRK_IRQHandler
0x080032a4 TIM8_UP_IRQHandler
0x080032a6 TIM8_TRG_COM_IRQHandler
0x080032a8 TIM8_CC_IRQHandler
0x080032aa ADC3_IRQHandler
0x080032ac FSMC_IRQHandler
0x080032ae SDIO_IRQHandler
0x080032b0 TIM5_IRQHandler
0x080032b2 SPI3_IRQHandler
0x080032b4 UART4_IRQHandler
0x080032b6 UART5_IRQHandler
0x080032b8 TIM6_IRQHandler
0x080032ba TIM7_IRQHandler
0x080032bc DMA2_Channel1_IRQHandler
0x080032be DMA2_Channel2_IRQHandler
0x080032c0 DMA2_Channel3_IRQHandler
0x080032c2 DMA2_Channel4_5_IRQHandler
0x080032c4 __WFI
0x080032c8 __WFE
0x080032cc __SEV
0x080032d0 __ISB
0x080032d6 __DSB
0x080032dc __DMB
0x080032e2 __SVC
0x080032e6 __MRS_CONTROL
0x080032ec __MSR_CONTROL
0x080032f6 __MRS_PSP
0x080032fc __MSR_PSP
0x08003302 __MRS_MSP
0x08003308 __MSR_MSP
0x0800330e __SETPRIMASK
0x08003312 __RESETPRIMASK
0x08003316 __SETFAULTMASK
0x0800331a __RESETFAULTMASK
0x0800331e __BASEPRICONFIG
0x08003324 __GetBASEPRI
0x0800332a __REV_HalfWord
0x0800332e __REV_Word
0x08003332 __init_end__ = (__init_start__ + SIZEOF (.init))
0x08003332 __init_load_end__ = __init_end__
0x00000001 . = ASSERT (((__init_end__ >= __FLASH_segment_start__) && (__init_end__ <= (__FLASH_segment_start__ + 0x1d000))), error: .init is too large to fit in FLASH memory segment)
0x08003334 __text_load_start__ = ALIGN (__init_end__, 0x4)

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
I'm not sure how the linker will behave if you tell it there is no flash at address 0, because the CPU is hard coded to load the stack address from that address when it boots.

“If I look into memory at address zero with the debugger it has:

0x200001A4
0x080001F1”


0x200001A4 is presumably a RAM address. Address 0 would be expected to hold a RAM address because it is the stack address. Either the linker is still putting the RAM address at address zero, even though you have told it there is no memory there, because the linker knows it has to. Or, the value you are seeing there is just left over from the last time you ran an application from address zero because the flash memory has not been overwritten or cleared.

Are you still remapping the vector table using the CPU vector base register? It is difficult to see how because it would have to boot through the vector before the code that remapped the vector could be set - unless you have a debugger macro that is doing that before the CPU is taken out of reset.

In any case, the vector table you have posted does not show the FreeRTOS interrupt handler having been installed. Looking just at the SVC handler, I would expect to see a function named vPortSVCHandler() being installed, but what is actually installed is SVCHandler(). That might be ok, if you are #define'ing one name to the other and SVCHandler() is declared as a weak symbol, but otherwise it is an error.

If you find the address of SVCHandler in the map file you will probably find it is the address you end up at branching to yourself when you execute the SVC instruction.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 6, 2012
As far as I know I'm not telling the processor there's no flash at address zero. I am not doing any sort of manual remapping at all. The linker is doing it all. I am sure that the issue is not there because with a run-to-complete program, this method works beautifully. I'm probably misunderstanding what you're saying though.

I have found this in the map file:


.text.vPortSVCHandler
0x08003394 0x20 THUMB Flash Debug/port.o
0x08003394 vPortSVCHandler


Which to me looks fine as it's above 0x8003000.

As far as I understand, you can map the start of code to be anywhere in the legitimate flash region and the linker just takes care of it. My suspicion is that something in FreeRTOS does some hard coding to point at an area below my new start address. I would stress that this is only a suspicion and I could be talking through my backside! :~)

I would also stress that if this technique didn't work for a run-to-complete program I would think it's a problem with my methodology.

Does that make sense or am I talking nonsense?

I am aware that this is taking your valuable time and I am quite happy to pay you to help fix this with some off-line help and then post the solution when we have fixed it. Thanks again.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
“As far as I know I'm not telling the processor there's no flash at address zero.”


Previously you said:

“All I am doing to normal FreeRTOS is going into the xml file that descibes the processor and changing the memory map for flash to start at 0x8003000 and change its length accordingly”


Presumably it used to start at address 0x8000000, and then again presumably that memory region is mirrored at address 0 when you boot (you would have to look at the memory map for the device you are using in its reference manual).


“I have found this in the map file:
.text.vPortSVCHandler
0x08003394 0x20 THUMB Flash Debug/port.o
0x08003394 vPortSVCHandler


Which confirms my suspicion that the vector table is not populated with the FreeRTOS interrupt handlers, because is shows that vPortSVCHandler and SVCHandler are not #defined to be the same thing. SVCHandler is the function that is in the vector table, and it shouldn't be.

“My suspicion is that something in FreeRTOS does some hard coding to point at an area below my new start address.”


You can be assured that is not the case.

“I would also stress that if this technique didn't work for a run-to-complete program I would think it's a problem with my methodology. ”


Is the run to complete code executing an SVC instruction that has its own bespoke handler though?

“I am aware that this is taking your valuable time and I am quite happy to pay you to help fix this with some off-line help and then post the solution when we have fixed it. ”


Thanks for the offer - but I prefer to keep these threads online so people with the same problems in the future can hopefully get prompts to sort their own issues without having to start their own threads. I think these support forums, over time (and this one has been here a long time!) are an invaluable developer resource. We all struggle with these low level issue from time to time.

Could you please post the code that actually sets up the vector table - that is the source code rather than the linker output? It will be defined in one of the start up files, which could be either a C file or an asm file.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 6, 2012
“Presumably it used to start at address 0x8000000, and then again presumably that memory region is mirrored at address 0 when you boot (you would have to look at the memory map for the device you are using in its reference manual).”


Ah, yes. I didn't understand about the mirroring at address zero.

“Is the run to complete code executing an SVC instruction that has its own bespoke handler though?”


No, I have never come across an SVC instruction before this investigation.

I assume this source code is what you're after for setting up the vector table (this looks quite like a standard Crossworks file to me):

“_vectors:
.word __stack_end__
#ifdef STARTUP_FROM_RESET
.word reset_handler
#else
.word reset_wait
#endif /* STARTUP_FROM_RESET */
.word NMIException
.word HardFaultException
.word MemManageException
.word BusFaultException
.word UsageFaultException
.word 0 // Reserved
.word 0 // Reserved
.word 0 // Reserved
.word 0 // Reserved
.word vPortSVCHandler
.word DebugMonitor
.word 0 // Reserved
.word xPortPendSVHandler
.word xPortSysTickHandler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMAChannel1_IRQHandler
.word DMAChannel2_IRQHandler
.word DMAChannel3_IRQHandler
.word DMAChannel4_IRQHandler
.word DMAChannel5_IRQHandler
.word DMAChannel6_IRQHandler
.word DMAChannel7_IRQHandler
.word ADC_IRQHandler
.word USB_HP_CAN_TX_IRQHandler
.word USB_LP_CAN_RX0_IRQHandler
.word CAN_RX1_IRQHandler
.word CAN_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTCAlarm_IRQHandler
.word USBWakeUp_IRQHandler
.word TIM8_BRK_IRQHandler
.word TIM8_UP_IRQHandler
.word TIM8_TRG_COM_IRQHandler
.word TIM8_CC_IRQHandler
.word ADC3_IRQHandler
.word FSMC_IRQHandler
.word SDIO_IRQHandler
.word TIM5_IRQHandler
.word SPI3_IRQHandler
.word UART4_IRQHandler
.word UART5_IRQHandler
.word TIM6_IRQHandler
.word TIM7_IRQHandler
.word DMA2_Channel1_IRQHandler
.word DMA2_Channel2_IRQHandler
.word DMA2_Channel3_IRQHandler
.word DMA2_Channel4_5_IRQHandler

.section .init, "ax"
.thumb_func

reset_handler:
#ifndef __FLASH_BUILD
/* If this is a RAM build, configure vector table offset register to point
to the RAM vector table. */
ldr r0, =0xE000ED08
ldr r1, =_vectors
str r1, [r0]
#endif
b _start

DEFAULT_ISR_HANDLER NMIException
DEFAULT_ISR_HANDLER HardFaultException
DEFAULT_ISR_HANDLER MemManageException
DEFAULT_ISR_HANDLER BusFaultException
DEFAULT_ISR_HANDLER UsageFaultException
DEFAULT_ISR_HANDLER SVCHandler
DEFAULT_ISR_HANDLER DebugMonitor
DEFAULT_ISR_HANDLER PendSV
DEFAULT_ISR_HANDLER SysTickHandler
DEFAULT_ISR_HANDLER WWDG_IRQHandler
DEFAULT_ISR_HANDLER PVD_IRQHandler
DEFAULT_ISR_HANDLER TAMPER_IRQHandler
DEFAULT_ISR_HANDLER RTC_IRQHandler
DEFAULT_ISR_HANDLER FLASH_IRQHandler
DEFAULT_ISR_HANDLER RCC_IRQHandler
DEFAULT_ISR_HANDLER EXTI0_IRQHandler
DEFAULT_ISR_HANDLER EXTI1_IRQHandler
DEFAULT_ISR_HANDLER EXTI2_IRQHandler
DEFAULT_ISR_HANDLER EXTI3_IRQHandler
DEFAULT_ISR_HANDLER EXTI4_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel1_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel2_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel3_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel4_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel5_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel6_IRQHandler
DEFAULT_ISR_HANDLER DMAChannel7_IRQHandler
DEFAULT_ISR_HANDLER ADC_IRQHandler
DEFAULT_ISR_HANDLER USB_HP_CAN_TX_IRQHandler
DEFAULT_ISR_HANDLER USB_LP_CAN_RX0_IRQHandler
DEFAULT_ISR_HANDLER CAN_RX1_IRQHandler
DEFAULT_ISR_HANDLER CAN_SCE_IRQHandler
DEFAULT_ISR_HANDLER EXTI9_5_IRQHandler
DEFAULT_ISR_HANDLER TIM1_BRK_IRQHandler
DEFAULT_ISR_HANDLER TIM1_UP_IRQHandler
DEFAULT_ISR_HANDLER TIM1_TRG_COM_IRQHandler
DEFAULT_ISR_HANDLER TIM1_CC_IRQHandler
DEFAULT_ISR_HANDLER TIM2_IRQHandler
DEFAULT_ISR_HANDLER TIM3_IRQHandler
DEFAULT_ISR_HANDLER TIM4_IRQHandler
DEFAULT_ISR_HANDLER I2C1_EV_IRQHandler
DEFAULT_ISR_HANDLER I2C1_ER_IRQHandler
DEFAULT_ISR_HANDLER I2C2_EV_IRQHandler
DEFAULT_ISR_HANDLER I2C2_ER_IRQHandler
DEFAULT_ISR_HANDLER SPI1_IRQHandler
DEFAULT_ISR_HANDLER SPI2_IRQHandler
DEFAULT_ISR_HANDLER USART1_IRQHandler
DEFAULT_ISR_HANDLER USART2_IRQHandler
DEFAULT_ISR_HANDLER USART3_IRQHandler
DEFAULT_ISR_HANDLER EXTI15_10_IRQHandler
DEFAULT_ISR_HANDLER RTCAlarm_IRQHandler
DEFAULT_ISR_HANDLER USBWakeUp_IRQHandler
DEFAULT_ISR_HANDLER TIM8_BRK_IRQHandler
DEFAULT_ISR_HANDLER TIM8_UP_IRQHandler
DEFAULT_ISR_HANDLER TIM8_TRG_COM_IRQHandler
DEFAULT_ISR_HANDLER TIM8_CC_IRQHandler
DEFAULT_ISR_HANDLER ADC3_IRQHandler
DEFAULT_ISR_HANDLER FSMC_IRQHandler
DEFAULT_ISR_HANDLER SDIO_IRQHandler
DEFAULT_ISR_HANDLER TIM5_IRQHandler
DEFAULT_ISR_HANDLER SPI3_IRQHandler
DEFAULT_ISR_HANDLER UART4_IRQHandler
DEFAULT_ISR_HANDLER UART5_IRQHandler
DEFAULT_ISR_HANDLER TIM6_IRQHandler
DEFAULT_ISR_HANDLER TIM7_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel1_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel2_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel3_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel4_5_IRQHandler”




RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
Hmm. That is curious. The correct vectors do seem to be being installed, but the linker output from your previous post would seem to show the wrong vectors actually in the table.

Could you zip up your entire project (all source files, and project files) in a way that allows me to build it easily (don't use any absolute paths to source files or include files) and send it to me? You can send it to r dot barry at freertos.org.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
I have not yet managed to program the board, but I have found that the code in post 9 is not what I thought it was. It is not the vector table at all. It seems the correct handler is being installed.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 6, 2012
Ok - running your code, now.

When the svc instruction is executed it jumps to address 0x8000100, which according to the map file is not in your program. Trying to execute instructions from that address results in a branch to 0x800018E, which then just branches to itself. Note that 0x800018E is not in the intended defined memory range either. Just to prove the point, I erased all the flash, and tried running it again and, sure enough now it just branches wildly off the planet as far as the CPU is concerned.

I think your problems start with the way you have attempted to move the program, and I believe the correct thing to do is leave the memory map file alone, and edit the section placement file (having first made a local copy in your project).

Look up flash_placement in the Rowley help system. I believe the thing to do is use the project properties section placement macros to move the start of the .text section to 0x8003000. Having said that, I have before just manually edited one. Below is an example (not correct for your application) I created some time ago to generate extra sections for specific placement when using the MPU. [note the privileged_functions sections I added in, and defined its size, there is also a start parameter you can use I think).



























Regards.



RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
Hi Richard,

I really don't think that is the answer I'm afraid. I've tried changing it and it makes no difference. I went back to an email I had from Michael at Rowley, describing what I'd done when I initially had issues with by run-to-complete program with the bootloader. He said:

You can use the section placement macro "FLASH_START=0x08003000" and this will have the same effect as the memory map change. So Michael was essentially saying said that my way is one method of doing it, the other is FLASH_START=0x08003000

I have searched high and wide and I cannot find anywhere that describes how to use FLASH_START=0x08003000. I've found places that say do this:



In the flash_placement.xml file, but that does nothing.

I've written to Rowley for clarification, but this:

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy.st.com%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F207IG%20w%20STM3220G%20eval%20bootloading%20issue&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B¤tviews=575

To me indicates I am doing the right thing. Hopefully, Michael will be able to shed some light on it.


RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 7, 2012
It seems Michael is making the same suggestion as me - to use the placement macros. Have you actually tried it though?

I just went back to the original, unmodified FreeRTOS demo (as downloaded in the official FreeRTOS zip file), then copied the section placement file into the project file (as per my post above) and made a single edit to move the start of the flash, as:



compiled and downloaded - and it appears to do exactly what you want. main() is above "0x8003000", and calling SVC jumps to the correct SVC handler, which is also above "0x8003000", the kernel starts and the tasks seem to be running.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 7, 2012
Slight correction - I didn't move the start of the flash, I moved the start of the .text section. The .vectors section is still at zero.

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
That does, indeed, load and execute from 0x8003000, thanks. The bootloader now seems to be corrupting something, so is not working. That''ll be a bug in my code I imagine. I'll report back once it's going.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
Actually, that's not right. Although the C code seems to start later that 0x8003000, all the assembler initialisation starts below there. That's why it was crashing once I tried the bootloader.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 7, 2012
What I did was get your experimental case working - when all that was done was move the .text section up to leave a gap for your boot loader. Now it is back to the start of the thread, which was originally about getting a boot loader to work.

Moving the .text section has left the .vectors where it was, so the CPU is booting normally from 0x00 and the vector table is telling it to run code that starts at 0x8003000. Now you have to have a second copy of the vector table for the application, and remap the vector table the CPU is used (using the vector base register). You can do that by either having the vector table in the flash image starting at 0x8003000, or copy the vector table to RAM. That is over to you ...

Regards.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
Would you email me that project back please? -The one you now have going I mean because I simply cannot get it going. I guess I am missing a step out or something; this is driving me absolutely nuts.

Thanks again.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
I have been playing endlessly today and the only way I can get the vectors to live at 0x8003000 is to change the ST_STM32F103RB_MemoryMap.xml with the line

I have tried a million different things now and nothing else will do it. I can get your method to shift the *code* start to 0x08003000, but it does not change the vectors. The only thing that shifts the vectors is my method, but once it gets to the

svc 0

Instruction it leaps off to somewhere before 0x8003000.

What on earth am I missing here? What do I not understand? What does this svc instruction *do* and who do non-FreeRTOS programs work just fine?

I must confess I just do not understand what this means:

“Moving the .text section has left the .vectors where it was, so the CPU is booting normally from 0x00 and the vector table is telling it to run code that starts at 0x8003000. Now you have to have a second copy of the vector table for the application, and remap the vector table the CPU is used (using the vector base register). ”


I'm on the verge of throwing the computer out of the window and/or having an embolism here.

RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 7, 2012
“I must confess I just do not understand what this means:

Moving the .text section has left the .vectors where it was, so the CPU is booting normally from 0x00 and the vector table is telling it to run code that starts at 0x8003000. Now you have to have a second copy of the vector table for the application, and remap the vector table the CPU is used (using the vector base register).


Knowing these things, I have to say, is a prerequisite for writing a boot loader. If you look at the section placement file, and the map file, you will see the vector table is in a section called .vectors that heads up the entire program. Your application code then sits in the .text section.

The SVC instruction is a software interrupt. It causes the CPU to act just like a hardware interrupt or exception has been accepted, and branch to an address stored in the exception table. Again, this is really detailed information that is required to write a boot loader.

If you have a boot loader running, and the (non-FreeRTOS) application it is loading and running from 0x8003000 is using interrupts, and the interrupts it is using are different to those used by your bootloader, then the same bootloader should work for an application that uses FreeRTOS.

As per my previous posts - the first thing the CM3 is going to do when it comes out of reset is load its stack and execution start point from address zero (or whatever memory is mapped to address 0 by whatever configuration methods there are). There is nothing you can do about that - you must have these values, and any other interrupt vectors used by the boot loader in a vector table that starts at a logical address 0.

If you want to load another program than has a separate vector table, like a FreeRTOS application, or in fact any application, then you need to have another vector table loaded too - and set the vector base address to point to the right one at the right time (the bootloader one when the bootloader is running, and the application one when the application is running). How you do that is up to you. A very common way of doing it is to copy the hard coded vector table from the flash image into RAM, where you can then simply write in the handler addresses as part of your start up code.

Regards.


RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 7, 2012
First of all I want to say, I really appreciate your patience with me, so thank you ever so much for that. I appreciate I have gaps in my knowledge and I am doing my best to fill these gaps. :~)

I totally understand what you are saying about having to have two vector tables, this completely makes sense. However, if I use my method of remapping everything (which works with the run-to-complete program), this does not work with FreeRTOS. I can see in the map file that *everything* starts at 0x8003000, including all the vectors.

Now, one thing I have just stumbled across is this line in the prvSetupHardware() routine:

“/* Set the Vector Table base address at 0x08000000. */
NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );”


Now, is this not hardcoding the Vector table away from 0x8003000 and therefore screwing things up when the svc instruction is called?

Thanks again.




RE: STM32 Bootloader loading FreeRTOS problems

Posted by Richard on July 7, 2012
Yes - that makes sense, and that will definitely mess you up - but it is also outside the FreeRTOS kernel code (i.e. it is in the demo app code).

It looks like an STM32 driver library function and should not be needed anyway. I suspect it originated from a demo that copied vectors to RAM and then remapped the vector table, them when the code was executed from Flash the line was adjusted rather than removed. You should definitely remove it.

Regards.


RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 8, 2012
That was a red herring. Makes no difference at all.

I am now suspecting there's something else amiss because I went back to my run-to-complete program starting at 8003000, so I could look at the SCB registers and try to make sense of it. After erasing all flash, that [the run-to-complete program] jumped off into the middle of nowhere. If I then first program from 8000000, don't erase and then program from 8003000 it works again without jumping into the middle of nowhere. So, now I'm even further away from having things working and understanding what's going on.

That line:

NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );

Is in the demo you sent too.



RE: STM32 Bootloader loading FreeRTOS problems

Posted by DiBosco on July 8, 2012
Well, I think it was all down to the flash not being locked after the self programming was finished. I finally tracked it down after having a friend sit with me and we went through FreeRTOS vs run-to-complete versions line -by-line. What seemed to happen was for some reason the vector table, even though it was being programmed correctly, was getting corrupted somehow once the last line had come in over RS485. Locking the flash seems to have solved it.

Thanks again for your patience in deal with such a dullard.


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner