Timer assertion error when using interrupts in C


#1

I have some time critical code in my project that can’t be executed by python, so I am going for a C hybrid solution, but I am having trouble using the interrupts in C. I have written some very simple example code (unrelated to my actual project), which shows my problem:

Python:

import streams

streams.serial()

@c_native("show", ["test.c"], [])
def showC():
    pass

showC()

pinMode(D12, OUTPUT)
print('sleeping')
sleep(2000)
print('1')
digitalWrite(D12, HIGH)
print('did')

C:

#include "zerynth.h"

void rising(int a, int b) {
    vhalPinWrite(LED0, 1);
}

C_NATIVE (show) {
    vhalPinSetMode(D13, PINMODE_INPUT_PULLDOWN);
    vhalPinSetMode(LED0, PINMODE_OUTPUT_PUSHPULL);
    vhalPinAttachInterrupt(D13, PINMODE_EXT_RISING, &rising, 20);
    return ERR_OK;
}

D12 & D13 are connected over a 100Ohm resistor. After 2 seconds of sleeping, LED0 should activate. When using Python interrupt, this is exactly what happens. But with the above code, I am getting this output:

sleeping

1

did/tmp/tmp9ru3eqkc/r2.1.2/common/vos/esp32-rtos/esp-idf-v3.0-rc1/components/freertos/./timers.c:794 (prvProcessReceivedCommands)- assert failed!

abort() was called at PC 0x40087e28 on core 0

Backtrace: 0x4008939f:0x3ffdd860 0x400893cb:0x3ffdd880 0x40087e28:0x3ffdd8a0

Rebooting...

ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

configsip: 0, SPIWP:0xee

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00

mode:DIO, clock div:2

load:0x3fff0018,len:4

load:0x3fff001c,len:3064

load:0x40078000,len:0

ho 12 tail 0 room 4

load:0x40078000,len:11504

entry 0x40078d64

As you can see, the interrupt registers without a problem and does activate when it should, but executing the interrupt func throws an error in timer.c. This always happends when using C interrupts in any context. Again, just doing the same with the python interrupt implementation does work wonderfully. Any ideas?


#2

You have to include this line at the start of C function “show”

    C_NATIVE_UNWARN();              //must be included at the start of a called c function.

Perhaps it is easier to give you an example of working interrupt routine in C
This implementation calls the ISR without any error
This is the C file.

#define ZERYNTH_PRINTF //we define this macro to use “printf” function.
#include “zerynth.h” //this is mandatory

void ISR(int slot, int dir) //this header and the paramters of the function mmust be defined like that according to the docs.
{
printf(“interrupt triggered\n”); //just a print to know when the interrupt is triggered.
}

C_NATIVE(init_interrupt_c){
C_NATIVE_UNWARN(); //must be included at the start of a called c function.
vhalPinAttachInterrupt(BTN0,PINMODE_EXT_BOTH,ISR,TIME_U(0,MILLIS));
printf(“Interrupt initialized on BTN0\n”);
return ERR_OK; //<-- execution ok //the timeout is given as 0 millis.
}

and in the python script:

@c_native(“init_interrupt_c”,[“cdiv.c”],[]) #we use @c_native to tell the compiler that we are calling a c function in another file.
def init_interrupt():
pass

init_interrupt() #init. of the interrupt in the C function in “cdic.c” file

Then if you push BTN0 on your device, the interrupt would be triggered and print a statement.
Let me know if you need further help