Discussion:
[nuttx] Issue SVCALL inside a posix timer handler
min.yang77@yahoo.com [nuttx]
2017-11-21 23:23:51 UTC
Permalink
Hello Nuttx,


I'm porting Nordic BLE into Nuttx. I would like to issue SVCALL inside a posix timer handler.
However, I came across a hardfault error when doing that. I have two questions.


1. Does Nuttx support this feature? If yes, could you please point me out what's the correct procedure?
2. Does "Issue SVCALL inside a posix timer handler" look like "nested interrupt" issue?


Thanks,
Min
spudarnia@yahoo.com [nuttx]
2017-11-21 23:38:58 UTC
Permalink
Yes, you cannot do nested interrupts. If you are within an interrupt handler, you cannot do a nested interrupt... a SYCALL is an interrupt so you cannot do that. If you try to perform a SYSCALL within an interrupt handler it will most certainly hardfault (or maybe worse).


If you have operations that need to be performed in response to an interrupt, you should signal a thread (via a signal, semaphore, or message). The thread should then do the whatever operations involve the SYSCALL.


But I am confused. Applications do not take interrupts. Only drivers and logic within the OS take interrupts. And logic within the OS will never perform SYSCALLs. If you are taking interrupts in an application, no are in non-standard, no-man's land and I have no advice for except for "good luck." You really must not do that.


And POSIX timers do not generate interrupts.. Then generate only signals. It should be perfectly acceptable to perform a SYSCALL from within a signal handler. So I really don't have a clue what you are doing.


Greg
spudarnia@yahoo.com [nuttx]
2017-11-21 23:53:27 UTC
Permalink
This post might be inappropriate. Click to display it.
Gregory Nutt spudarnia@yahoo.com [nuttx]
2017-11-22 11:51:06 UTC
Permalink
It seems to me that you must be handling interrupts in your application
code.  Of course that will work in the FLAT build only because there is
nothing to prevent you from doing that other than good architectural
principles (and certainly I would not want such behavior upstream).

But if you switch to the PROTECTED (or KERNEL) modes your code will be
completely broken.  If you try to take an interrupt in the user-space,
you will be unable to interact with the OS in any way because you would
have to use a SYSCALL to call back into the OS and that SYSCALL will
fail if called from an interrupt handler.

The correct solution is to modify the logic that is generating the
interrupt to the user program.  Instead of generating an interrupt, it
should send a signal to the user program.  The user program can then
either wait for the signal to occur (faster) or provide a signal handler
to catch the event (slower).

There are lots of examples in the code that do this.  Look for example
at how the button driver informs the application of a button press.  See
drivers/input/button_upper.c.  In particular look at handling of the
BTNIOC_REGISTER ioctl command and the call to nxsig_queue() when a
change in the button state is detected.

Also look at the example code at apps/examples/buttons for an example of
how this signal is used by an application.

There is more overhead in using signals (at least with signal
handlers... a task waking on a signal is awakened with neglible delay). 
If this is an issue, the other option is to move your driver interrupt
handler logic so the it is "inside" of the OS in supervisor space.  You
can do that by simply moving it to your confgs/<board>/src directory.

But that may only defer the issue of how you are going to communicate
with the driver from user apps.  Options are (1) register your logic as
a real device driver so that you can interact with it in the normals
ways:  open, close, read, write, ioctl, ..., or (2) enable 
CONFIG_BOARDCTL_IOCTL=y use boardctl() to interact directly with your
board-specific logic.

Greg
min.yang77@yahoo.com [nuttx]
2017-11-22 22:18:55 UTC
Permalink
Hi Greg/Alan,

Thank you so much for your reply. Right now my structure is flat and we plan to make it into user space and kernel space later. For this particular case, I actually did what you described. I use a posix timer. When timer is up, it generates a signal and go to the signal handler in application level. I issue SVCALL inside the signal handler and then I see a hard fault error. As you said it should be perfectly acceptable to perform a SYSCALL from within a signal handler, but instead I see a hardfault error.


On the other hand, I tried a RTC driver example. Inside the RTC signal handler, I can issue SVCALL. I'll trace the code again and see what might be wrong for posix timer case.


Regarding NIMBLE, we did a simple survey on it. We'll not implement it for our first version because we can't break Nordic controller part currently.


Best regards,
Min
spudarnia@yahoo.com [nuttx]
2017-11-22 22:51:07 UTC
Permalink
... For this particular case, I actually did what you described. I use a posix timer. When timer is up, it generates a signal and go to the signal handler in application level. I issue SVCALL inside the signal handler and then I see a hard fault error. As you said it should be perfectly acceptable to perform a SYSCALL from within a signal handler, but instead I see a hardfault error.
Then that sounds like a bug. Might be a stack size problem. The signal handler might run deep in the stack and the SVCALL on top might just be too much for the allocated stack. Have you tried increasing the stack size.


If you can give me a small test application, I can try to debug the problem. Perhaps you would modify apps/examples/hello to generate the error so that I could examine it.


Greg
min.yang77@yahoo.com [nuttx]
2017-11-22 23:05:14 UTC
Permalink
Hi Greg,

I found what causes the hardfault, it's sem_wait. I use default posix timer example to test. By default, there is sem_wait in a for loop. In this case, I see a hardfault. If I delete sem_wait, I don't see hardfault and everything is fine. I still don't understand why sem_wait will cause this issue. Do you have any clue?
I have posixtimer.c in the attachment. What I modified is to add a while(1) before sem_wait loop and add a SVCALL in timer_expiration


Thanks,
Min
spudarnia@yahoo.com [nuttx]
2017-11-22 23:15:35 UTC
Permalink
sem_wait() should not cause a hardfault. Are you sure it is a hardfault and not an assertion? sem_wait() may assert() in certain circumstances.


I don't see any attachment. People do complain about Yahoo! consuming attachments. Maybe that is what happened here.


Greg
min.yang77@yahoo.com [nuttx]
2017-11-23 00:10:25 UTC
Permalink
Hi Greg,


I think it's hardfault. And inside hardfault, it calls assert()
I am not sure if sem_wait causes the hardfault. If I don't issue SVCALL inside a signal handler, I don't see a hardfault even I have sem_wait. The combination of "sem_wait" and "issue SVCALL inside a signal handler" cause this hardfault. Below is the data log.


user_main: POSIX timer test
timer_test: Initializing semaphore to 0
timer_test: Unmasking signal 17
timer_test: Registering signal handler
timer_test: oact.sigaction=0 oact.sa_flags=0 oact.sa_mask=0
timer_test: Creating timer
timer_test: Starting timer
timer_test: Waiting on semaphore
up_hardfault: PANIC!!! Hard fault: 40000000
up_assert: Assertion failed at file:armv7-m/up_hardfault.c line: 171
up_dumpstate: sp: 20002e60
up_dumpstate: IRQ stack:
up_dumpstate: base: 20002f00
up_dumpstate: size: 00000800
up_stackdump: 20002e60: 00000000 00000000 20002e70 00021eaf 00000800 20002f00 200055a0 00001fc4
up_stackdump: 20002e80: 200079e0 20002e60 20002e98 00021f8f 000000ab 20002ea8 000000ab 00032cd4
up_stackdump: 20002ea0: 20002ea8 000227e1 20002eb0 00000000 20007704 00000003 00000000 df790001
up_stackdump: 20002ec0: 0002b158 20007704 20002ed0 00022d33 20007704 00000003 00000000 0002277d
up_stackdump: 20002ee0: 20002ee8 00022761 20007704 00000003 00000000 00000000 200077d8 00021fcd
up_dumpstate: sp: 200077d8
up_dumpstate: User stack:
up_dumpstate: base: 200079e0
up_dumpstate: size: 00001fc4
up_stackdump: 200077c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
up_stackdump: 200077e0: 20003b2c 00000011 00000000 00000000 200055e0 20003b20 200055e8 20003b20
up_stackdump: 20007800: 20007808 00023deb 20004460 200055a0 00000000 00000021 00010001 00000000
up_stackdump: 20007820: 000156e4 00000000 00000004 20003b20 20007838 0002a4cf 20004460 20007928
up_stackdump: 20007840: 00000001 00000000 00000000 00000000 20007928 00000000 00000000 00000000
up_stackdump: 20007860: 00000000 ffffffe9 00000000 00000000 00000000 00000000 00000000 00000000
up_stackdump: 20007880: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
up_stackdump: 200078a0: 00000000 00000000 00000002 20005610 20002f70 20002f70 00989680 00031d4d
up_stackdump: 200078c0: 0002a604 01000000 00000000 00000000 00000000 00000000 00000000 00000000
up_stackdump: 200078e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
up_stackdump: 20007900: 00000000 00000000 00000000 20007928 00010000 00023d65 00000004 200055a0
up_stackdump: 20007920: 20007928 00031d4d 0502dca3 200055a0 00031331 20002f00 200055a0 010055a0
up_stackdump: 20007940: 20007948 0002d59b 2000795c 20003228 20007968 00000000 200055a0 ffffffff
up_stackdump: 20007960: 20007968 0002b465 061afa4b 20003250 00000002 00000000 00000002 00000000
up_stackdump: 20007980: 00031101 0000002a 00000000 00000000 00000000 0002b211 fffdffff 00000002
up_stackdump: 200079a0: 00020000 0002adf5 00000000 00000000 200079b8 0002adf9 200079e4 00000005
up_stackdump: 200079c0: 200079c8 000232ed 00000000 00000000 200055a0 00000005 00000000 00000000
up_registerdump: R0: 200077f6 20003b2c 00000000 200077f6 00000000 00000000 00000000 200077d8
up_registerdump: R8: 00000000 00000000 00000000 00000000 00989680 200077d8 0002b227 0002b15a
up_registerdump: xPSR: 41000000 PRIMASK: 00000001 CONTROL: 00000000
up_registerdump: EXC_RETURN: ffffffe9
spudarnia@yahoo.com [nuttx]
2017-11-25 12:26:03 UTC
Permalink
sem_wait() should not cause a hardfault. Are you sure it is a hardfault and and
not assertion? sem_wait() may assert() in certain circumstances.
I don't see any attachment. People do complain about Yahoo! consuming
attachments. Maybe that is what happened here.
If you resend the attachment, I will look at it. If I can duplicate the problem, I might be able to help you.

Greg

Alan Carvalho de Assis acassis@gmail.com [nuttx]
2017-11-21 23:43:41 UTC
Permalink
Hi Min,

Instead of porting the Nordic BLE into NuttX, why don't you try to
port the nimBLE for NuttX.

There are other companies here interested on it, maybe they could even
to contract you to do that.

BR,

Alan
Post by ***@yahoo.com [nuttx]
Hello Nuttx,
I'm porting Nordic BLE into Nuttx. I would like to issue SVCALL inside a
posix timer handler.
However, I came across a hardfault error when doing that. I have two questions.
1. Does Nuttx support this feature? If yes, could you please point me out
what's the correct procedure?
2. Does "Issue SVCALL inside a posix timer handler" look like "nested interrupt" issue?
Thanks,
Min
Loading...