Send and Receive CAN Frames

Sending and receiving CAN Frames can be implemented in many ways. The simplest way is to disable all upper layers and use the CAN Frames directly. When using an operating system (e.g. μC/OS-II or -III), the RX and TX communication could be performed within the same or separate tasks. The following example will demonstrate the reception of a CAN Frame, it will then modify the CAN Identifier (ID) and send the CAN Frame back on the same CAN Bus line. This example is the same as the 'ECHO' example found in the can_demo.c file for your given operating system.

Note:

  • Prior to running the 'ECHO' example, it is assumed that the proper steps to configure and initialize the CAN module were taken prior to this. For more information on the full CAN Startup sequence visit the App_CAN_Startup() section of the 'Using CAN Signal, Message, and Bus Protocols.

To select the 'ECHO' example make sure that the following is set in can_demo.c:

                                                                 /* CAN Demo Definitions.                                */
#define  APP_CAN_RX_TX_DEMO                 0u
#define  APP_CAN_ECHO_DEMO                  1u
                                                                /* --------------- uC/CAN DEMO SELECTION -------------- */
                                                                /* Select the CAN demo to run.                          */
#define  APP_CAN_DEMO_SELECT                APP_CAN_ECHO_DEMO

Echo Task

#include  "can_frm.h"
#include  "can_bus.h"

#if (APP_CAN_DEMO_SELECT == APP_CAN_ECHO_DEMO)
void  Echo_Task (void  *argp)                         [1]
{
    CANFRM      frm;
    CPU_INT08U  busId;
    CPU_INT16U  timeout;
   
    (void)&argp;                                                /* Suppress Compiler Warning.                           */
   
    busId   = 0u;                                     [2]       /* CAN Device Number/ CAN Controller Number.            */
    timeout = 0u;
    CanBusIoCtl( busId,                                         /* Rx Timeout is set to wait forever for a new Frame.   */
                 CANBUS_SET_RX_TIMEOUT,
                &timeout);                            [3]

    while (DEF_ON) {                                            /* Endless while loop.                                  */
        CanBusRead(         busId,                    [4]       /* Wait for new CAN Frame to Arrive.                    */
                   (void *)&frm,
                            sizeof(CANFRM));

        frm.Identifier = 0x100L;                      [5]       /* Change Frame ID.                                     */

        CanBusWrite(         busId,                   [6]       /* Echo back same data with updated Frame ID.           */
                    (void *)&frm,
                             sizeof(CANFRM));
    }
}
#endif

1] The 'ECHO' Task example is taken from µC/OS-II or -III can_demo.c files. Although the 'ECHO' Task example is the same when using No OS, the user must be aware of minor changes between No OS and µC/OS-II or -III.

2] CAN Bus ID based on the CAN Bus Channel desired to use.

3] Set the RX timeout to 0 to enable the blocking mode, e.g. the function CanBusRead() will wait for a CAN frame forever. Otherwise set a timeout and check returned error code of [4] if a timeout has occurred.

  • For µC/OS-II or -III demos, the 'ECHO' task has been configured to blocking mode.

4] Wait for the next received CAN Frame.

5] After reception, change the CAN Identifier in the Received Frame.

6] Transmit the Received CAN Frame with the changed CAN ID on the desired CAN Bus Channel.