Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
5 years, 2 months ago.
CAN - attach callback for a specific IrqType [in OS 2]
I have an older project - running on mbed OS 2, and it needs [just] one more feature - tracking of CAN communications errors. I know about the GetRxErrorCounter() and GetTxErrorCounter(), but my needs are beyond those.
// Each ISR signature is like this - void BusMetrics::CANReceive_ISR(void); // Implementation BusMetrics::BusMetrics(CANPort * arg_can) { can = arg_can; // other initialization not shown (bit-rate, etc.) can->Attach(this, &BusMetrics::CANReceive_ISR); // This works, and my handler receives it - only RxIrq (the default) // I want the other events ... can->Attach(this, &BusMetrics::CANTransmit_ISR, CAN::TxIrq); // Compile fails with: //Error: No instance of overloaded function "CANPort::Attach" matches the argument list in "BusMetrics.cpp", Line: 127, Col: 11. can->Attach( callback(this, &BusMetrics::CANTransmit_ISR), CAN::TxIrq); // Fails in the same way //Error: No instance of overloaded function "CANPort::Attach" matches the argument list in "BusMetrics.cpp", Line: 127, Col: 11 // When I get TxIrq working, then I want EwIrq, DoIrq, WuIrq, EpIrq, AlIrq, and BeIrq ... } // Fragment from CAN.h, which also has information about the "callback( )" pattern. void attach(T *obj, void (T::*method)(), IrqType type = RxIrq) { ... }
What will fix this?
1 Answer
5 years, 2 months ago.
Hello David,
I think you have just a typo in the snippet above: can->attach
shall be lower case 'a'. The code below compiles fine for both LPC1768 and NUCLEO-F103RB with Mbed OS 2. However, I did not test it.
#include "mbed.h" class BusMetrics { CAN* _can; public: BusMetrics(CAN* arg_can) : _can(arg_can) { // other initialization not shown (bit-rate, etc.) _can->attach(callback(this, &BusMetrics::CANRx_ISR), CAN::RxIrq); _can->attach(callback(this, &BusMetrics::CANTx_ISR), CAN::TxIrq); _can->attach(callback(this, &BusMetrics::CANEw_ISR), CAN::EwIrq); _can->attach(callback(this, &BusMetrics::CANDo_ISR), CAN::DoIrq); _can->attach(callback(this, &BusMetrics::CANWu_ISR), CAN::WuIrq); _can->attach(callback(this, &BusMetrics::CANEp_ISR), CAN::EpIrq); _can->attach(callback(this, &BusMetrics::CANAl_ISR), CAN::AlIrq); _can->attach(callback(this, &BusMetrics::CANBe_ISR), CAN::BeIrq); _can->attach(callback(this, &BusMetrics::CANId_ISR), CAN::IdIrq); } void CANRx_ISR(void) { printf("'CANRx_ISR()' called\r\n"); } void CANTx_ISR(void) { printf("'CANTx_ISR()' called\r\n"); } void CANEw_ISR(void) { printf("'CANEw_ISR()' called\r\n"); } void CANDo_ISR(void) { printf("'CANDo_ISR()' called\r\n"); } void CANWu_ISR(void) { printf("'CANWu_ISR()' called\r\n"); } void CANEp_ISR(void) { printf("'CANEp_ISR()' called\r\n"); } void CANAl_ISR(void) { printf("'CANAl_ISR()' called\r\n"); } void CANBe_ISR(void) { printf("'CANBe_ISR()' called\r\n"); } void CANId_ISR(void) { printf("'CANId_ISR()' called\r\n"); } }; CAN can(p30, p29); // LPC1768 //CAN can(PB_8, PB_9); // NUCLEO-F103RB DigitalOut led(LED1); BusMetrics busMetrics(&can); // Creates an instance of BusMestrics (attaches ISRs) int main(void) { while (1) { led = !led; wait(1); } }
One of those moments - when I saw your reference to a lower-case 'a', I thought - I think my code-base has one more layer in the middle, between my code sample and the CAN api - and I was right (and it had only a single 'A'ttach method...
Thanks for the quick response - I can stop banging my head on the glass now.
I think I need to inherit CAN in my intermediate shim, and then I can call on-thru to the various 'a'ttach methods of interest.
posted by 19 Sep 2019