An error pin? Topic is solved

All technical discussions and projects around startKIT
User avatar
aclassifier
Respected Member
Posts: 329
Joined: Wed Apr 25, 2012 8:52 pm

An error pin?

Postby aclassifier » Wed Dec 21, 2016 7:58 am

Is there a possibility to give the compiler or linker a parameter to have a certain pin set when the runtime crashes on the startKIT?

And if so, is there a way for the application also to call any such crash handler?

Or is division by zero a good place to trigger an internal exception?

Or do I have to design my own exception handler?
View Solution
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Wed Dec 21, 2016 10:09 am

Hi,

We would need to define what a 'crashing run-time' is.

There are errors that may occur at run-time, for example an array-bound check may occur (if you have been naughty in XC), you may get a LOAD-STORE exception (because of a bad pointer in C), or a division by zero.

In all these cases, one of the processor threads will get an exception, causing that thread to be send to the exception handler. The default exception handler that is installed by the startup-code is __Exception or something like that. In turn, this will go to a CLRE;WAITEU that the debugger keeps an eye on. Hence, if you run the code with XRUN it prints a message that an exception has occurred, stopping all threads; if you run the code from FLASH, the thread will hang, and probably cause all other threads to grind to a halt.

You can install your own exception handler; easiest done through a call to the SETKEP (set kernel entry point) instruction. You will need a small piece of assembly that sets the kernel entry point to one of your functions, and in there you can pull a pin high.

Cheers,
Henk
User avatar
aclassifier
Respected Member
Posts: 329
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Dec 21, 2016 10:39 am

Thanks, Henk.

I only want this to happen in flashed code.

So some #ifdef flashed first?

Then, any suggestion of how that asm code would look?

If I install my own, will it take over all exception handling, so that I basically call it with a div 0?
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Wed Dec 21, 2016 11:48 am

Hi aclassifier,

This piece of code probably does the trick:

Code: Select all

int installExceptionHandler(void)
{
  asm(" ldap r11, exception");
  asm(" set kep, r11");
  asm(" retsp 0");
  asm(".align 128");
  asm("exception: bl myExceptionHandler");
}

int myExceptionHandler(void)
{
  // ... do whatever you like here
  asm(" clre");
  asm(" waiteu");  // This stops the thread in its tracks.
}


Rather than calling divide by zero, try this one to raise an exception:

Code: Select all

  asm(" ecallf %0" : "r" (0));


The compiler may catch a divide by zero, but leave this one in.

I don't know how to just do it on flashed code.

Cheers,
Henk
User avatar
aclassifier
Respected Member
Posts: 329
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Dec 21, 2016 12:08 pm

Thanks a lot, Henk! I will try it out as soon as I can and then come back here in any case.
User avatar
aclassifier
Respected Member
Posts: 329
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Dec 21, 2016 12:19 pm

Another thing. Will it then finally just hit a jmp $ and then stay there until powered off and on?

What is the available semantics around this? Is there a machine reset and restart instruction? I am used to letting a watchdog timer do restart in an exception. I am content with just stopping with the beeper on on this.
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Wed Dec 21, 2016 12:32 pm

You can reset the chip from there in software; (there are a few threads on this forum on that subject) but that may not always work (as it is done in software).

I believe that the start kit has a watchdog on it; so you can create something robust on it if you fancy. Have a look at the XS1-A16 data sheet and search for watchdog to find it.
User avatar
aclassifier
Respected Member
Posts: 329
Joined: Wed Apr 25, 2012 8:52 pm

Postby aclassifier » Wed Dec 21, 2016 11:09 pm

It works!

Disclaimer the morning after: I haven't tried the ecallf above, leaving this comment somewhat out of scope.

However, the asm retsp 0 doesn't satisfy the int return with
"warning: control reaches end of non-void function"
even if i move retsp 0 as the final instruction.
Tried to read https://www.xmos.com/support/tools/othe ... nent=14808
but then, this wasn't going to be an asm course.

When I just call myExceptionHandler it seems like the logical core stops, while the others run until it all deadlocks.

However, if I do like a div 0 then the system crashes (and myExceptionHandler is not envoked, I have a printf there that doesn't show up), all cores are suspended and the debugger comes up with a stack trace like this:

xCORE Debugger (22:53 21.12.16) (Suspended)
tile[0] core[0] (Suspended)
tile[0] core[1] (Suspended)
tile[0] core[2] (Suspended)
tile[0] core[3] (Suspended)
tile[0] core[4] (Suspended: Signal 'ET_ARITHMETIC' received. Description: Arithmetic exception.)
.. Full stack trace

Is there a user exception that I might invoke this mechanism with, and in case, how do I invoke it - to have myExceptionHandler becoming invoked?
henk
Respected Member
Posts: 346
Joined: Wed Jan 27, 2016 5:21 pm

Postby henk » Thu Dec 22, 2016 8:34 am

Ah yes - forgot to tell - you have to install the exception handler for each LogicalCore in your program - every time they are created. Then it should also work for your div 0.
User avatar
infiniteimprobability
XCore Legend
Posts: 1120
Joined: Thu May 27, 2010 10:08 am

Postby infiniteimprobability » Thu Dec 22, 2016 10:16 am

I only want this to happen in flashed code.


Try this..

Code: Select all

 int boot_from_jtag = ((getps(XS1_PS_BOOT_CONFIG) & 0x4) >> 2);
  if (!boot_from_jtag) { stuff that is only done when flashed }

Who is online

Users browsing this forum: No registered users and 0 guests