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.
6 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
6 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