This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
I have the following problem related with the ROM Bootloader:
Firstly, my firmware works perfectly, if i load it up with a Debugger.
However i upload it using ROM Bootloader, right after the reset, it leads to imprecise exception. (NVIC_FAULT_STAT = 0x400)
If i do a power cycle after that, it works perfectly.
If i make a reset using the function SysCtlReset(), during any point of the firmwares life, it also always works perfectly, device always initializes without any problem.
I have read the https://www.ti.com/lit/an/spma043/spma043.pdf?ts=1658473901542 but i am still unable to tackle the problem.
I check the SP, R3 is there as expected, but r2-r1-r0 are not ok. Also the 3rd register in 2nd row leads me to a completely irrelevant position.
Can you please help to figure out what is wrong ?
Best regards,
Erman
The call of the bootloader is with the following function:
void SoftwareUpdateTivaBegin(void)
{
//
// Disable all processor interrupts. Instead of disabling them
// one at a time (and possibly missing an interrupt if new sources
// are added), a direct write to NVIC is done to disable all
// peripheral interrupts.
//
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
//
// Also disable the SysTick interrupt.
//
SysTickIntDisable();
SysTickDisable();
//
// Return control to the boot loader. This is a call to the SVC
// handler in the flashed-based boot loader, or to the ROM if configured.
//
ROM_UpdateEMAC( 120000000UL );
}
Hi,
Not sure what is the problem.
Can you answer a few questions?
- I suppose your application firmware is built to start at address 0x0, correct? Can you show your linker command file?
- Can you repeat the same problem on a different board?
- Can you try the TivaWare example C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_demo_emac_rom. This is a Ethernet application that will call ROM_UpdateEMAC. Will you have the same problem? If the example does not produce the same problem then please compare with your firmware. Perhaps there is some subtle difference.
Hi Charles,
it is %100 repeatable in different boards.
Linker command file content is below
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00100000 // 1 Mbyte
SRAM (RWX) : origin = 0x20000000, length = 0x00040000 // 1/4 Mbyte
XRAM (RWX) : origin = 0x60000000, length = 0x0003FFFF // 1/4 Mbyte reserviert für GUI
XRAM2 (RWX) : origin = 0x60040000, length = 0x005BFFFF // Bitmaps, Fonts, Daten
XRAM3 (RWX) : origin = 0x60600000, length = 0x00100000 // 1Mbyte reserviert für copy buffer SDRAM_COPY_ADDRESS
// Ende 0x606FFFFF
}
// Section allocation in memory
SECTIONS
{
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
.xram : > XRAM, TYPE = NOLOAD // ohne Initialisierung
.xram2 : > XRAM2, TYPE = NOLOAD // ohne Initialisierung
.xram3 : > XRAM3, TYPE = NOLOAD // ohne Initialisierung
}
The example works, also some older versions of my firmware is also working with the updater. I dont think there is any hardware issue.
How can i go after the exception and figure out where it is exactly coming from ?
Best regards,
Erman
Hi,
I don't really spot any issue with your linker file but neither do I know what the problem is. Can you answer a few questions.
- Is your fault handler a simple while(1)? Or your fault handler has some additional custom code you added. If you read the app note, you will need to adjust it. See below.
The stack frame is supposed to save R0-R3 starting from the SP. See below image. However, in your capture the first location is already R3, not R0. If you look at your capture, the value at address 0x2003737C is equal to 0x0007C43B. Could this be the offending PC instead? You will need to check the vicinity of it. To ease debug, perhaps you want to revert the fault handler to nothing but a while loop. It may be easier this way to view and debug the stack frame.
- A imprecise fault usually means it is due to a write operation. Faults from reads is always precise.
- Please review section 3.3 of the app note carefully. This section talks about debugging imprecise abort.
- Before the fault occurs, are you reading or writing to the external memory when the external is not fully initialized?
Hi,
I am using TIRTOS in my project. The problem is error starts at BIOS_start(). So i can not remove OS from the project and have a look at it, because the problem doesnt occur then.
My fault handler is Hwi_excHandler in tirtos. I put a breakpoint at the beginning of it and it SP is pointing to R4. Here is a screen shot:
The fault is occuring during BIOS_start() so no, i do not think i am reading or writing to external memory. I put breakpoints to all of my tasks and none of them gets until the breakpoint, exception occurs already.
Only things i have before BIOS_Start() is the basically board pin initializations and then i have construct 3 tasks like..
Task_construct(&BootTaskStruct, (Task_FuncPtr) BootTask, &taskParams, NULL);
I reviewed the section 3.3 of the app note but I dont know what to do now.
Please note that, I get this error ONLY after updating a firmware with bootloader. Power reset or softreset with SysCtlReset() never causes this, I wrote a script and tried it 100 times, always successful bootups normally.
Am i supposed to call ROM_UpdateEMAC() from task with a particular prio ?
Is the following really fully enough before calling the ROM_UpdateEMAC() ?
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
SysTickIntDisable();
SysTickDisable();
Best regards,
Erman
Hi Erman,
While I don't have a good answer to your problem, I find this post to be maybe helpful. This post seems to have similar issue although it is calling ROM_UpdateUART() instead of ROM_UpdateEMAC(). This post mentions that after loading the new firmware, they must do a manual reset to get it started properly. I think it is worth trying the suggested solution to see if it makes a difference to your project. Go to the end of the post where John replaced the HWREG(NVIC_DIS0) = 0xffffffff and HWREG(NVIC_DIS1) = 0xffffffff with individual peripheral interrupt disables.
Hi Charles,
I have tried the following based on the link you have sent and it didnt work
ROM_IntDisable(INT_GPIOA);
ROM_IntDisable(INT_GPIOB);
ROM_IntDisable(INT_GPIOC);
ROM_IntDisable(INT_GPIOD);
ROM_IntDisable(INT_GPIOE);
ROM_IntDisable(INT_GPIOF);
ROM_IntDisable(INT_UART0);
ROM_IntDisable(INT_UART1);
ROM_IntDisable(INT_TIMER0A);
ROM_IntDisable(INT_TIMER0B);
ROM_IntDisable(INT_TIMER1A);
ROM_IntDisable(INT_TIMER1B);
ROM_IntDisable(INT_TIMER2A);
ROM_IntDisable(INT_TIMER2B);
ROM_IntDisable(INT_TIMER3A);
ROM_IntDisable(INT_TIMER3B);
ROM_TimerIntDisable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerDisable(TIMER1_BASE, TIMER_A);
ROM_TimerIntDisable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerDisable(TIMER2_BASE, TIMER_A);
ROM_TimerIntDisable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerDisable(TIMER3_BASE, TIMER_A);
ROM_TimerIntDisable(TIMER7_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerIntClear(TIMER7_BASE, TIMER_TIMA_TIMEOUT);
ROM_TimerDisable(TIMER7_BASE, TIMER_A);
ROM_IntPendClear(INT_TIMER1A);
ROM_SysTickIntDisable();
HWREG(NVIC_INT_CTRL) |= NVIC_INT_CTRL_PENDSTCLR;
Also i have replaced the tirtos exception handler with a while(1) loop as you have asked before. Here is my registers afterwards. Still the SP doesnt show registers R0-R1-R2-R3, instead it shows R0-R1-R0-R1-R2-R3. Please see the pic below.
Which address might give me a clue now ?
Best regards,
Erman
Hi Charles,
i think i got it. Based on the clues about disabling more stuff, disabling my UART port seems to have solved the problem.
UARTDisable(UART1_BASE);
This port is not a debug port, it is connected to another IC and normally has continuous communication.
I will need to do an overnight test to make it sure its working very reliably but manual tests so far has been good.
Nevertheless, can you please tell me why
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
was not enough and i had to particularly call the UARTDisable function ?
Would it be safer if i literally use all the disable functions for all the peripherals ?
Best regards,
Erman
i think i got it. Based on the clues about disabling more stuff, disabling my UART port seems to have solved the problem.
UARTDisable(UART1_BASE);
Hi Erman,
Glad that you solve the problem. I'm not too sure if my theory is correct since I'm not a TI-RTOS expert. Although you have cleared the interrupt enables in the NVIC, what might have happened is that BIOS_start() somehow reenable the NVIC again. This is why in our non-RTOS example, we never see this issue. Once ROM_UpdateEMAC() is called, it jumps to the bootloader and the bootloader does not re-enable the interrupts since the bootloader itself is not written to use the interrupts. When you disable the peripheral as in UARTDisable, you ensure that no interrupts will ever be generated by the UART module regardless if the interrupt is enabled or not at the NVIC level.