app will run to hardfault if enable the preemption.
app with preemption enable can run ok if the programe without a bootloader.
I checked the pendsv and systick IRQ priority, they are both 3, which is the lowset in my chip. If I commet code *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; the program also run ok. So I think the hardfault is related to pendSV triggered in systick handler. But I don’t know how to deal with this problem.
It is not clear how the code you posted is meant to work. I cannot see that it remaps the vector table as you claim, and appears to call the application code from handler mode (that is, from inside an interrupt) so the C startup code of the main application (if that is what the pFun pointer is pointing to) will execute in an interrupt context.
There is too little information to be sure - but from just the code you post there seems to be quite a bit that could be wrong with the way you are exiting the bootloader.
Hi, because I’m using a M0 chip with a bootloader, so when PendSV happened, it goes to PendSV_handler in the bootloader first, and I use this code to call the PendSV_handler in the app to make the remap
Is ApplicationAddress the address of the vector table in your application?
Is 0x38 the offset of the PendSV handler address in the vector table?
Assuming the answers are yes – both deserve a double check – then I think I see what you are doing. First, check to see if your M0 happens to have a configurable vector table base address. If so, that’s the best solution. If not, you should probably write your redirect functions in assembly language and use BX for the branch (not BLX). The code written in C messes up the context expected by FreeRTOS’s PendSV handler.
The chip vendor ought to supply this kind of redirect function. I assume they are forcing this bootloader on you? They should know the trouble they are causing anyone who tries to run an OS, and they should provide the solution. What chip is it?
Is ApplicationAddress the address of the vector table in your application?
Yes
Is 0x38 the offset of the PendSV handler address in the vector table?
Yes
I got this boot code from our supplier. This boot worked well in our project without OS before.The chip is HT6037 kind of a soc for metering.
Maybe I should use a assembly redirect function.
Hi, Jeff, your suggestion works!! thank you very much!!
I solve the problem, but the method seems not so good. I modify the PendSV_Handler in startup.s file directly, and the app_addr is fixed at 0x4000.
I want to use the same asm code int a C file, but the IAR output an error: Error[Og006]: Syntax error in inline assembly: “Error[401]: Operand syntax error”
I do not know how do deal with it, do u have some good idea?
There’s a section in the IAR C/C++ development guide called “inline assembler” which should help. I noticed it says the shorthand syntax used in the first statement isn’t allowed. Here’s how it looks with the first statement not using shorthand.
Refer to IAR C/C++ Development Guide,I found a limitation with inline assembler, “The pseudo-instruction LDR Rd, =expr is not available from inline assembler” . I think that is why the error occured before. So I replace LDR with ADD instruction, and it also works. ApplicationAddress is a macro defined as 0x4000.
Letting the C compiler do anything outside of your __asm() statement is a little risky. In this special function, we need the C compiler to use only R0 through R3 so we maintain the state of the interrupted task. The compiler is likely to do that, but probably not guaranteed. May be best just to stick with native assembly.
I think you are right, my program run to hardfault again after runing for about 2 hours. You mean I should not use local variables to store vector and offset, right? I don’t know how to fill R0 with a 32bit value (0x00004000 + 0x38) in IAR inline assembler environment.
I found that hardfault is caused by optimization level. Before optimization level is medium, and program run ok with preemption disable. When I enable preemption, program can only run ok in none optimization level. Anyway I will use the native assembly way to do redirect.
Hard faults cause by optimization are often bugs in the code that get revealed by the optimization. (Proper optimization changes no promised observable behavior).
It can sometimes also cause issues with things like FPU usage, but that shouldn’t be the case here with an M0.
This is the sort of code that may behave differently depending on the optimisation level. The code appears (not sure) to say the function does not have a stack frame, but then allocates two variables on the (non existent) stack. Some optimisation levels will just use register values rather than a stack and others won’t.
I finally found the bug, it’s related to task priority and Concurrency. My app disabled the preemption before, so such bug will not happen. Once I enable preemption in app, this bug will happen soon or later.
Thank you all!!