tonton81 / FlexCAN_T4

FlexCAN (CAN 2.0 / CANFD) Library for Teensy 3.x and 4.0
https://forum.pjrc.com/threads/56035-FlexCAN_T4-FlexCAN-for-Teensy-4
MIT License
196 stars 66 forks source link

calling write(MB,msg) from a function pointer function creates issue #67

Open equinox311 opened 1 year ago

equinox311 commented 1 year ago

Hey, not sure if this is the right mechanism to explain this issue, but I am trying to call the write(mb,msg) function from a function called by a pointer, and the entire program crashes and does not recover. I do get one CAN TX, that is not always packed correctly, but that is all.

I don't know enough about all of this to make a call what is wrong, or if I am out of line trying to call a write with a function pointer, but here is the relevant code snippets minus some of the CAN setup:

Setup:

FlexCAN_T4 <CAN1,RX_SIZE_16,TX_SIZE_16> can1;
typedef struct TxMsgObj_t{

    int tx_time;
    CAN_message_t msg;
    void (*txFcn)(int,CAN_message_t);

} TxMsgObj_t;

TxMsgObj_t txObj[NUM_TX_MSG];

txObj[num_fcns].msg = canPack();
txObj[num_fcns].txFcn = &canTx_TEST;
txObj[num_fcns].tx_time = 500;
num_fcns++;

Pointer call:

for(int j=0; j<num_fcns;j++){

        if(txObj[j].tx_time==500){

            if(txObj[j].txFcn != NULL){
                txObj[j].txFcn(10,txObj[j].msg);
            }else{
                //Handle later

            }
        }
    }

Function from pointer function:

void canTx_TEST(FLEXCAN_MAILBOX mb, CAN_message_t msg){

    can1.write(mb,msg);

}

Not sure if this is an library issue, or just my bad code. Function pointer calls work great with any other function though.

tonton81 commented 1 year ago

does the regular write(msg) work? if so, try to cast the 10 --> write((FLEXCAN_MAILBOX)10,msg)

equinox311 commented 1 year ago

I don’t recall if it worked or not, I believe it did not but I cannot remember the behavior when I tried the regular write.

I will confirm and try the cast though. Thanks :)

equinox311 commented 1 year ago

Same behavior as original issue.

equinox311 commented 1 year ago

Doing a malloc for the size of the message structure seemed to get the program to at least reset… however no change in behavior as far as proper functioning.

equinox311 commented 1 year ago

So I think I figured this out. Using your FlexCAN_T4 object as an extern in a different C file creates allll sorts of issues. I moved everything into one file and it seemed to work out.

Not sure if this is how this is supposed to work (C++ classes are still confusing to me), but that one threw me through a loop.

equinox311 commented 1 year ago

Should also note, using a pointer instead of extern also created the same issues.

noisymime commented 11 months ago

Can confirm this and am seeing hard lockups when the FlexCAN_T4 object is declared extern within .h/.cpp files. Lockups occur every time when calling .write() under these conditions, but probably can be triggered in other ways also.

Strangely this does not seem to be occurring if all files are using .ino extensions. I believe when using the arduino/PIO compile scripts with .ino files, the scope of the Can0 object will become global and the extern is ignored.

noisymime commented 11 months ago

FLEXCAN_T4_Issue.zip

Attached is a simple example showing this. It has been tested on a Teensy 3.5

This will send a msg every 500ms and report back over Serial the total number of msgs sent. By default the Can0 object is not declared extern and everything works fine.

If you uncomment the //#define USE_EXTERN line in FLEXCAN_T4_Issue.h however, Can0 will be declared extern and the msg will be (or should be) sent from a function in CAN_comms.cpp. This however causes the board to lockup as soon as .write() is called within the sendReply() function.