cancel
Showing results for 
Search instead for 
Did you mean: 

Force hard fault

thealbertdev
Associate II

Hello,

I have a project where one of the requirements is to activate the iwdt in some defined circumstances, and refresh it in other circumstances also defined. I need to collect evidence of the correct implementation of iwdt in such a way that the acceptance criteria of these requirements are validated. (And the code can not be modified during the test to put some while(1) that makes iwdt to be triggered, or add some function pointer to a non valid address. The code must be validated as it will be flashed in the product).

I had thought to force a hard fault using the STM32CubeProgrammer. Is it possible? Is it possible for example to make the program jump to a not allowed address (e.g. set the PC register to 0x0000000000) to force a hard fault on request to test the iwdt? The idea is to automate the tests, so being able to do it using the cli commands of the STM32CubeProgrammer would be a great help.

Thank you very much in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
thealbertdev
Associate II

Thanks for your reply @Tesla DeLorean ! 🙏

I have come up with a possible solution which is to change the IDLE function execution by executing a pointer to the IDLE function. This way, my intention is to change that pointer to 0x0 whenever I want and thus force a Hard Fault.

The thing is that in STM32CubeProgrammer (I operate it with the CLI commands), when I write to the pointer memory location (in RAM) I get this error message:

Error: Failed to download data! If it's a Flash memory, it may be not erased or protected
Error: SCRIPT_ERROR_LEVEL = 1.

Sometimes I have been able to write (or no error message is received at least), but most of the time I have not. Maybe it is related to trying to write just when the microcontroller is in low power mode? If so, how could I manage this scenario (I connect to the device in HOTPLUG mode). If not, what could be the reason for the error?

Thank you very much again.

View solution in original post

10 REPLIES 10

Not sure about STM32 Cube Programmer, but an unaligned 64-bit read will fault all the Cortex-Mx parts ST uses.

Basically an LDRD on an unaligned pointer.

Say

uint8_t *ptr = (uint8_t *)(0x20002001); // Unaligned RAM address

uint64_t u64value = *((uint64_t *)ptr);

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

For STM32 Cube Programmer, try a read of an unmapped / undecoded address, 0x9FFFFF00 toward the end of the QSPI/OCTO 256 MB addressable memory window. Or some other unmapped memory in your implementation, say 0x6FFF0000

You could perhaps also use an External Loader, and taunt that by writing a magically value to a magical address.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
thealbertdev
Associate II

Thanks for your reply @Tesla DeLorean ! 🙏

I have come up with a possible solution which is to change the IDLE function execution by executing a pointer to the IDLE function. This way, my intention is to change that pointer to 0x0 whenever I want and thus force a Hard Fault.

The thing is that in STM32CubeProgrammer (I operate it with the CLI commands), when I write to the pointer memory location (in RAM) I get this error message:

Error: Failed to download data! If it's a Flash memory, it may be not erased or protected
Error: SCRIPT_ERROR_LEVEL = 1.

Sometimes I have been able to write (or no error message is received at least), but most of the time I have not. Maybe it is related to trying to write just when the microcontroller is in low power mode? If so, how could I manage this scenario (I connect to the device in HOTPLUG mode). If not, what could be the reason for the error?

Thank you very much again.

Andrew Neil
Evangelist

@thealbertdev wrote:

I need to collect evidence of the correct implementation of iwdt .


Not sure how forcing a Hard Fault achieves that? 

🤔

The point of the Watchdog is to fire when the code fails to "kick" it on time.

You can test that by simply having a loop which doesn't "kick" the watchdog; eg,

void watchdog_test(void)
{
   while(1)
   {
      /* Do nothing - Watchdog should fire! */
   }
}
thealbertdev
Associate II

Update:

I make use of scripts. If I use the macro #Write32(Address,data) I get the error described above. If I use directly the -w32 command I have no problems.

Thank you very much again @Tesla DeLorean .

Thank for your reply!

You are right and I use this approach (to have a while(1) in code) to test the IWDT during developing phase. But when it comes to test the production code, I can't edit the code to attend this acceptance criteria validation (it has to be validated with the code that is going to be flashed in the product (is a medical device)).

But I have found a way to test it without having two code versions (one for production and one for testing) and that I have share it in other reply of this thread.


@thealbertdev wrote:

I can't edit the code to attend this acceptance criteria validation (it has to be validated with the code that is going to be flashed in the product (is a medical device))


That doesn't make sense.

You incorporate this into the released code; it gets called whenever you do whatever you do to invoke the IWDG Test.

There is no need for a separate build.

I would venture to suggest that fording a HardFault isn't a great test, as that is rather a "special case" - you would also need to test that the IWDG works in "normal" code ...

I'm probably getting lost in translation, but how can I add the while(1) function in the code to test the IWDT and then, without modifying the code, release it in production and prevent the device from restarting all the time?

In the approach that I indicate, I can execute a Hard Fault at convenience to test it, or do nothing so that the application behaves correctly. In addition, I chose to test using a forced hard fault because the default hard fault handler is already a while(1), and because each of the requirements has a risk scenario that justify or argue its implementation, and in this case the risk scenario is that there is a hard fault and the device is stuck. From there the requirement to activate the IWDT is born, that is why I believe that to put as acceptance criterion to validate that the device resets when a hard fault is triggered is the most convenient. Obviously, there are more acceptance criteria such as if there is no hard fault, the device is not rebooting all the time. And I also understand that the IWDT would help to manage other risk scenarios due to infinite loops.

Having said this, I want to thank you very sincerely for taking the time to discuss this topic with me since, although I have experience in firmware development, it is the first time that I work in a device with such a high level of validation requirements (it is a medical device), so I am still learning. I look forward to your opinion on this matter.


@thealbertdev wrote:

I'm probably getting lost in translation, but how can I add the while(1) function in the code to test the IWDT and then, without modifying the code, release it in production and prevent the device from restarting all the time?


You have some sort of test command or button or whatever to activate this test.

AndrewNeil_0-1708634114363.png

Maybe not so prominent & user-accessible as that, but ...

Or, like your HardFault approach, have it controlled by a flag that's only accessible via the debugger.

 

Addendum

You could label the button 'Reset'.

Maybe also have it recessed, as is common for 'Reset' buttons.

Then the user knows that it will cause the device to reset.

And the test becomes simply, "does the 'Reset' button work?"

 

AndrewNeil_2-1708634514241.png