2019-03-08 02:16 AM
I have FreeRTOS set up on an STM32F107 performing several tasks of different priority in "parallell".
There is one task of IDLE priority that blinks an LED and one task of Normal priority that receives communication over CAN (triggered by external interrupts). There are also some tasks that reads values off the ADC and uses DMA.
There is also a bootloader in place that can receive new firmware via CAN.
When the MCU is powered it starts in the bootloader, and a custom CAN message kicks it to the application, and everything works fine. The application can receive messages from CAN, blink the LED and execute calculations just fine.
Another custom message can bring it from the application back to the bootloader (via a call to NVIC_SystemReset()), which works. But it is when attempting to bring the MCU back to the application (after NVIC reset) that things start to behave weirdly:
Sometimes, roughly ~60% of the time, the MCU seems to not enable interrupts. The LED blinks just fine (indicating the RTOS is still running its most low-priority task) but the application is not responding to CAN messages. Which to me indicates that interrupts have not been set up correctly.
I have tried putting LED indications on hardware fault handlers and failure to initialize CAN without any success, so I am not sure what the MCU is doing.
I also tried disabling IRQ and all system clocks before calling the NVIC reset without any luck.
Do you have any ideas on how to troubleshoot this further?
Is there any recommended procedure to perform before calling NVIC_SystemReset?
Thanks in advance!
BR,
David
2019-03-08 02:58 AM
Sounds like a quite complex system ...
I'm not sure about the reset behavior of peripheral registers. A SW reset differs from a power-up.
> Sometimes, roughly ~60% of the time, ...
Which sounds like either a runtime issue, or dependence on another unknown state.
Perhaps CAN messages got stuck during the reset, or some error flags not reset ?
BTW:
> There is also a bootloader in place that can receive new firmware via CAN.
> When the MCU is powered it starts in the bootloader, and a custom CAN message kicks it to the application, and everything works fine.
This is not the approach in our company's controller firmware.
The BL starts the application if a valid one is detected, and a special "stay in BL" flag is not set.
The request for a firmware update must be initated in the application, and the controller power-cycled. Consecutively the firmware update is executed by the BL.
2019-03-08 05:15 AM
Do you have anything driving the pin externally.
2019-03-08 06:27 AM
Hi AvaTar, thanks for your reply!
What do you mean by "got stuck during the reset"? I thought NVIC_SystemReset would clear all buffers as well as restore all variable to their initial values?
I know there can be multiple ways to deal with flashing a new application with the bootloader. We also have the firmware upload executed by the BL, just that an overall host controller has the ability to toggle between bootloader and application.
Is there any special reason you have the requirement to power-cycle in order to get to the boot loader? Perhaps this is the way most platforms are built specifically due to issues like the one I am seeing (that software reset can't be fully trusted) ?
BR,
David
2019-03-08 06:28 AM
Hi Clive!
What pin do you mean exactly?
The NRST pin is connected via a 100 nF capacitor to GND.
And the boot0 pin is connected directly to GND.
BR,
David
2019-03-08 07:44 AM
Hi David,
The "NVIC_SystemReset" command is triggering the hard reset using the watchdog.
In this case, the MCU starts from scratch.
The RAM memory may stay the same.
Have you tried to clean the RAM?
Best Regards,
Alexey
2019-03-10 12:50 AM
Are You going from bootloader to application through NVIC_SystemReset() also? That is the safest way, because it removes unnecessary dependencies. I've described that approach in details here:
2019-03-11 07:09 AM
Hi Alexey, thanks for your reply!
What do you mean may stay the same?
I would hope that NVIC_SystemReset() would result in a predictable (deterministic) behaviour by the MCU.
Is there anywhere I can read what it actually does?
Both the ST manual and ARM documentation so far has not outlines in much detail what goes on and what differs from a power cycle.
BR,
David
2019-03-11 09:18 AM
Hi David,
You are right all the registers and peripherals will be in the default state.
I am not sure that there is hardware that clean a RAM memory.
So, some variables may have the same value from the last run.
mem_addr = 0x20000000;
Just run the - memset( mem_addr , 0 , mem_size );
before NVIC_SystemReset().
We can see if it helps.
Regards,
Alexey
2019-03-12 08:41 AM
Hi Alexey,
Thanks for the suggestion, I feel like it is a good idea.
I have tried
memset( (uint8_t *) 0x20000000, 0, 0x3fffffff - 0x20000000 );
With the address 0x3fffffff being the end of SRAM according to STM32 documentation, but so far the processor seems to be hanging on that write command. Presumably because I am writing to too high of an address.
Is there something obvious I am doing wrong?
BR,
David