Page 1 of 1

Debugging a unhandled_exception

Posted: Tue Dec 10, 2013 2:19 pm
by alan5
Hi guys,
I'm getting stuck in an unhandled_exception and was hoping for some pointers.

I'm using a STM32L152RCT6 and am using the following:

SPI Driver: SPID2
Serial Driver: SD1
Interrupt Driver: EXTD1

So the trace itself is:

Code: Select all

#0  _unhandled_exception () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/STM32L1xx/vectors.c:172
#1  <signal handler called>
#2  0x00000000 in ?? ()
#3  0x080009b0 in chSchGoSleepS (newstate=0 '\000') at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chschd.c:128
#4  0x080009b0 in chSchGoSleepS (newstate=32 ' ') at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chschd.c:128
#5  0x080003cc in _port_thread_start () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/chcore_v7m.c:262
#6  0x080003cc in _port_thread_start () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/chcore_v7m.c:262


which isn't too useful. It tried enabling a good few debug options in the makefile, and I get the following:

Code: Select all

#0  port_halt () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/chcore.c:50
#1  0x08000a66 in chDbgPanic (msg=0x80066a8 "SV#4") at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:274
#2  0x0800079a in dbg_check_lock () at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:117
#3  0x08002174 in spiSelect (spip=0x20000dc8) at /home/fyp/fyp/ChibiOS-RT/os/hal/src/spi.c:153
#4  0x0800479e in selectCC3000 () at ../CC3000_ChibiosRT/cc3000_spi.c:104
#5  0x08004a0a in cc3000ExtCb (extp=0x20000dc0, channel=11) at ../CC3000_ChibiosRT/cc3000_spi.c:243
#6  0x0800309c in VectorE0 () at /home/fyp/fyp/ChibiOS-RT/os/hal/platforms/STM32L1xx/ext_lld_isr.c:169
#7  <signal handler called>
#8  0x55555554 in ?? ()
#9  0x55555554 in ?? ()


So it would seem with debug I am getting caught out for attempting to use SPI in an interrupt callback. So I'm probably going to have to re-jig this up with a semaphore and move the code itself into a thread...
But would this be the cause of the unhandled exception? For my understanding it seems that chSysLock disables interrupts (obviously a problem if I'm then trying to use one for SPI) but I'm trying to understand how it could lead to an unhandled_exception. Anyone have any good links referring to unhandled_exceptions in this case / how to debug them?

Cheers

Re: Debugging a unhandled_exception

Posted: Tue Dec 10, 2013 2:39 pm
by Giovanni
Hi,

You are using a normal API spiSelect() from an interrupt handler, this is why you are getting that "SV#4" (misplaced chSysLock()).

From interrupt handlers you can only use I-Class functions, see "kernel concepts" in the kernel documentation.

In you case you have to do:

Code: Select all

  chSysLockFromIsr();
  spiSelectI(...);
  chSysUnlockFromIsr();


In general, those "SV#x" error codes mean that there is a function called out of its proper context. The meaning of "n" is in the kernel documentation, debug section. Note that most functions are context-sensitive but there are general rules.

Giovanni

Re: Debugging a unhandled_exception

Posted: Tue Dec 10, 2013 4:29 pm
by alan5
Giovanni wrote:Hi,

You are using a normal API spiSelect() from an interrupt handler, this is why you are getting that "SV#4" (misplaced chSysLock()).

From interrupt handlers you can only use I-Class functions, see "kernel concepts" in the kernel documentation.

In you case you have to do:

Code: Select all

  chSysLockFromIsr();
  spiSelectI(...);
  chSysUnlockFromIsr();


In general, those "SV#x" error codes mean that there is a function called out of its proper context. The meaning of "n" is in the kernel documentation, debug section. Note that most functions are context-sensitive but there are general rules.

Giovanni


Thanks for your help, I found the API for the SV#x errors. Unfortunately I can't quite implement your suggestion as more or less my next call is to SpiExchange where I would run into the same issue again. From my understanding the other spixxxI functions are all asynchronous so then I would have to block until the callback is called. At that point I feel I am making the ISR somewhat too complex... So I feel the most sensible option is to thread the existing code in the ISR.

Re: Debugging a unhandled_exception

Posted: Tue Dec 10, 2013 5:36 pm
by Giovanni
Of course you cannot wait into an interrupt handler, spiExchange() is synchronous. You need to use the callback-based API available in the SPI driver, use spiStartExchangeI().

Giovanni

Re: Debugging a unhandled_exception

Posted: Tue Dec 10, 2013 10:34 pm
by alan5
I tried using the thread/semaphore option, basically because it seemed like the quickest test implementation - there is already a state machine in place for SPI communications with the device and its not particularity pretty.

I was wondering if there was any reason why a binary semaphore could not be called from an EXT callback?

If I use chBSemSignal in the EXT cb I get a SB#4 (No surprises there).

Code: Select all

#0  port_halt () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/chcore.c:50
#1  0x080009e6 in chDbgPanic (msg=0x80037b8 "SV#4") at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:274
#2  0x0800071a in dbg_check_lock () at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:117
#3  0x08003674 in extcb1 (extp=0x20000db8, channel=0) at main.c:35
#4  0x0800288e in Vector58 () at /home/fyp/fyp/ChibiOS-RT/os/hal/platforms/STM32L1xx/ext_lld_isr.c:62
#5  <signal handler called>
#6  0x55555554 in ?? ()
#7  0x55555554 in ?? ()



However if I use chBSemSignalI in the EXT cb I get a SV#10

Code: Select all

#0  port_halt () at /home/fyp/fyp/ChibiOS-RT/os/ports/GCC/ARMCMx/chcore.c:50
#1  0x080009e6 in chDbgPanic (msg=0x8003798 "SV#10") at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:274
#2  0x080008da in chDbgCheckClassI () at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chdebug.c:196
#3  0x0800146a in chSemSignalI (sp=0x20000f24) at /home/fyp/fyp/ChibiOS-RT/os/kernel/src/chsem.c:305
#4  0x08003652 in extcb1 (extp=0x20000db8, channel=0) at main.c:35
#5  0x0800285e in Vector58 () at /home/fyp/fyp/ChibiOS-RT/os/hal/platforms/STM32L1xx/ext_lld_isr.c:62
#6  <signal handler called>
#7  0x55555554 in ?? ()
#8  0x55555554 in ?? ()


The two variables being checked in chDbgCheckClassI are:
dbg_isr_cnt = 1
dbg_lock_cnt =0
so the check for dbg_lock_cnt <= 0 is causing the chDbgPanic

Interestingly without debug turned on both chBSemSignal and chBSemSignalI appear to behave correctly for this simple test.

heres my test case:

Code: Select all

/*
    ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

/* Test program:
 * Idea is a thread is always waiting on a semaphore to toggle GPIOB_LED4.
 * The sem is signalled in the ext callback.
*/

#include "ch.h"
#include "hal.h"
#include "board.h"

static EXTConfig extcfg;
static BinarySemaphore irqSem;

static WORKING_AREA(threadWorkingArea, 256);

static void extcb1(EXTDriver *extp, expchannel_t channel)
{
    (void)extp;
    (void)channel;
    chBSemSignalI(&irqSem);
}

static msg_t thread(void *arg)
{
    (void)arg;

    while (1)
    {
        chBSemWait(&irqSem);
        palTogglePad(GPIOB, GPIOB_LED4);
    }
}


int main(void)
{
    halInit();
    chSysInit();


    chBSemInit(&irqSem, FALSE);

    (void)chThdCreateStatic(threadWorkingArea,
                            sizeof(threadWorkingArea),
                            NORMALPRIO, thread , NULL);


    palSetPadMode(GPIOB, GPIOB_LED4, PAL_MODE_OUTPUT_PUSHPULL);
    palClearPad(GPIOB, GPIOB_LED4);

    palSetPadMode(GPIOA, GPIOA_BUTTON, PAL_MODE_INPUT);

    extcfg.channels[GPIOA_BUTTON].mode = EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA;
    extcfg.channels[GPIOA_BUTTON].cb = extcb1;
    extStart(&EXTD1, &extcfg);

    while(1);

  return 0;
}

Re: Debugging a unhandled_exception

Posted: Wed Dec 11, 2013 9:40 am
by Giovanni
Hi,

I advice you to read "kernel concepts" in the documentation where the matter is explained. I-class functions must be called in between a chSysLockFromIsr() and chSysUnlockFromIsr().

Giovanni

Re: Debugging a unhandled_exception

Posted: Thu Dec 12, 2013 2:00 am
by alan5
Giovanni wrote:Hi,

I advice you to read "kernel concepts" in the documentation where the matter is explained. I-class functions must be called in between a chSysLockFromIsr() and chSysUnlockFromIsr().

Giovanni


Sorry, I think I deleted the Lock/Unlock when changing the EXT CB from SPI to a semaphore. Thanks very much for the help! :D