4 years, 7 months ago.

CAN attach() in OS 5 doesn't seem to work right?

When I follow past documentation to use `CAN.attach()` to attach an ISR to a` CAN:RxIrq` interrupt, it throws an error about Mutex (due to calling `CAN.read()`). If I rewrite things to not call `CAN.read()` in the ISR, I don't ever seem to be able to clear the interrupt and the whole thing locks up.

What is the correct way to use `CAN.attach()`?

I have tried the examples here: <https://github.com/ARMmbed/mbed-os/issues/5267> The minimal working example there does not work.

I've currently got this, where without attaching the ISR the `can_process` runs but never catches messages; and when I try to attach the ISR, the `can_process` locks, heartbeat off and no printing.

```C++

  1. include "mbed.h"
  2. include "rtos.h"

Serial pc(USBTX,USBRX); DigitalOut rxled(LED2); DigitalOut heartbeat(LED4); CAN can1(p9,p10); CAN can(p30,p29); CANMessage msg; volatile bool can_rx_irq=0; Thread can_thread;

void can_interrupt(){ can_rx_irq = 1; set flag can.attach(NULL,CAN::RxIrq); clear ISR } can_isr

void can_process(){ pc.printf("Starting can_process() in can_thread\r\n"); can.frequency(250000); can.attach(&can_interrupt, CAN::RxIrq);

while(1){ pc.printf("can_rx_irq is %d\r\n",can_rx_irq); if (can_rx_irq){ can_rx_irq = 0; clear flag

handle CAN message receipt if (can.read(msg)){ rxled = !rxled; pc.printf("got %d\r\n",msg.data[0]); }

can.attach(&can_interrupt,CAN::RxIrq); } if (can_rx_irq)

ThisThread::sleep_for(20); } while(1) } void can_process()

int main() { pc.printf("CAN attach test\r\n"); can_thread.start(can_process);

pc.printf("main() loop doing nothing much\r\n"); while(1){ ThisThread::sleep_for(1000); heartbeat =! heartbeat; } while(1) } main()

```

1 Answer

4 years, 7 months ago.

Hi there,

please use code formating from editing tips and repair your post.

<<code>> your code <</code>>

If I remember correctly the Can.attach was working until revision 5.10 of MbedOS came. So you can change the revision to 5.9 and probably it will working. That was probably caused by some changes about how mutex works in interrupts or something like that. Until these change came it was possible use Can. attach or also Can.write from a ticker but now it is not possible because that cause hard fault.

Some one wrote me "try this code" but was working only until revision 5.12 came.

class UnCan : public CAN {
public:
    UnCan(PinName rd, PinName td) : CAN(rd, td) { }
    virtual void lock() { }
    virtual void unlock() { }
};

Maybe someone with more experince or someone from Mbed team can explain us, how use can.attach correctly.

J.

depends on how many messages you have on bus, you can use EventQueue

EventQueue eQueue(32 * EVENTS_EVENT_SIZE);

void process(){
    // read message here
}

int main(){
    ...
    can.attach(eQueue.event(callback(process)));
}
posted by Pavel S 04 Sep 2019

Hi Pavel, thank you for the tip but when I implemented this in to a simple code with one Can msg per second the system still crushed but now with CMSIS-RTOS error: ISR Queue overflow.

posted by Jan Kamidra 05 Sep 2019