Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This section will utilize previously mentioned CAN Signals, Messages, and Bus protocols and outline the 'Rx / Tx' example in can_demo.c.This demo will use multiple tasks to read, write, and update CAN Signals and Messages. It will also transmit messages and receive messages using the CAN Bus protocol. This section assumes that CAN Signals, Messages, and Bus configuration / initialization have already been donewill also outline the proper CAN Startup sequence required in an application.

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

...

Code Block
languagecpp
linenumberstrue
void  App_CAN_Startup (void)
{
    CPU_INT16S    can_err;
    CANMSG_PARA  *m;
#if (CANSIG_STATIC_CONFIG == 0u)
    CANSIG_PARA  *s;
#endif
#if ((APP_CAN_DEMO_SELECT == APP_CAN_RX_TX_DEMO) || \
     (APP_CAN_DEMO_SELECT == APP_CAN_ECHO_DEMO))
    CPU_INT08U    os_err;
#endif
                                                                /* ------------------ HARDWARE SETUP ------------------ */
    ...                                               [1]

                                                                /* ------------------- uC/CAN SETUP ------------------- */
    CanSigInit(0L);                                   [2]       /* Initialize CAN Signals.                              */
#if (CANSIG_STATIC_CONFIG == 0u)
    s = CanSig;
    while (s < &CanSig[S_MAX]) {                                /* Create CAN Signals                                   */
        can_err = CanSigCreate(s);
        if (can_err < 0) {
           while (1);                                           /* Failure Handling Here.                               */
        }
        s++;
    }
#endif
    CanMsgInit(0L);                                             /* Initialize CAN Messages.                             */
    m = (CANMSG_PARA *)CanMsg;
    while (m < &CanMsg[CANMSG_N]) {                             /* Create CAN Messages.                                 */
        can_err = CanMsgCreate(m);
        if (can_err < 0) {
           while (1);                                           /* Failure Handling Here.                               */
        }
        m++;
    }

    CanBusInit(0L);                                   [3]       /* Initialize CAN Objects & Bus Layer.                  */
    can_err = CanBusEnable((CANBUS_PARA *)&CanCfg);             /* Enable CAN Device according to Configuration.        */
    if (can_err != CAN_ERR_NONE) {
        while (1);                                              /* Failure Handling Here.                               */
    }
    
                                                                /* ----------------- uC/OS DEMO TASKs ----------------- */
#if (APP_CAN_DEMO_SELECT == APP_CAN_RX_TX_DEMO)
    ...                                               [4]
#endif
}

 

Rx_Task()

Once the Startup / Initialization of the CAN module is completed and without any errors, the Rx Task will Read the CAN Bus line and wait indefinitely (Set to blocking mode) until a CAN Frame with the appropriate Message ID arrives.


void Rx_Task (void *argp) { CANFRM
Code Block
languagecpp
linenumberstrue
Panel
bgColor#f0f0f0

1] In App_CAN_Startup()  any Hardware dependent functions calls that are required to run the CAN module should be initialized here. Usually it should just be the ISR handlers.

2] This is explained in detail in the following sections:

3] This is explained in detail in the following sections:

4] The proper API call will be used to create the tasks necessary for the 'Rx / Tx' Demo based on which OS is being used.


Rx_Task()

Once the Startup / Initialization of the CAN module is completed and without any errors, the Rx Task will Read the CAN Bus line and wait indefinitely (Set to blocking mode) until a CAN Frame with the appropriate Message ID arrives.

Code Block
languagecpp
linenumberstrue
void  Rx_Task (void  *argp)
{
    CANFRM      frm;
    CPU_INT16S  msg;
    CPU_INT08U  busId;
   
    (void)&argp;                                                /* Suppress Compiler Warning.                           */
   
    busId = 0u;                                                 /* CAN Device Number/ CAN Controller Number.            */
    CanBusIoCtl(busId,                                          /* Rx Timeout is set to wait forever for a new Frame.   */
                CANBUS_SET_RX_TIMEOUT,
                0);

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

        msg = CanMsgOpen(busId,                       [2]       /* Try to open the Received Frame on Message layer.     */
                         frm.Identifier,
                         0);
        if (msg >= 0) {                                         /* If it could be opened, write the Frame on Msg layer. */
            CanMsgWrite(         msg,                 [3]
                        (void *)&frm,
                                 sizeof(CANFRM));
        }
    }
}

 

Tx_Task() & Send_Status()

Concurrently, the Tx_Task will update a demo count variable and Transmit the CAN Signal it is configured to every 200ms. The transmission process will go as follows:

  • Write CAN Signal -> Open CAN Message (with Tx Message ID) -> Read Message -> Write CAN Bus

 


void Tx_Task (void *argp) {
Code Block
languagecpp
titleTx_Task()
linenumberstrue
Panel
bgColor#f0f0f0

1] As described above, the CAN bus Rx will be set to Blocking Mode and wait forever until a CAN Frame arrives.

2] Once a CAN Frame arrives, it will check if the Frame ID matches any initialized CAN Message.

3] If there is a match and the CAN module can open the appropriate CAN message, it will then write the updated Frame data onto the Message.


Tx_Task() & Send_Status()

Concurrently, the Tx_Task will update a demo count variable and Transmit the CAN Signal it is configured to every 200ms. The transmission process will go as follows:

  • Write CAN Signal -> Open CAN Message (with Tx Message ID) -> Read Message -> Write CAN Bus


Code Block
languagecpp
titleTx_Task()
linenumberstrue
void  Tx_Task (void  *argp)
{
    (void)&argp;                                                /* Suppress Compiler Warning.                           */

    while (DEF_ON) {                                            /* Endless while loop.                                  */
        DemoCnt++;
        CanSigWrite( S_CPULOAD,                       [1]       /* Set an Incrementing Counter.                         */
                    &DemoCnt,
                     1);
        
        if (DemoCnt >= DEF_OCTET_MASK) {
            DemoCnt = 0u;                                       /* Reset Demo Count to 0.                               */
        }
                   
        Send_Status();                                [2]       /* Send Signal Status on CAN bus                        */
        
        OSTimeDlyHMSM(0u, 0u, 0u, 200u);
    }
}


Code Blockpanel
languagebgColorcpptitleSend_Status(#f0f0f0

1] Write updated DemoCnt varialbe to the 'CPULOAD' CAN Signal.

2] Transmit the CAN Signal on the CAN Bus line.


Code Block
languagecpp
titleSend_Status()
linenumberstrue
void  Send_Status (void)
{
    CANFRM      frm;
    CPU_INT16S  msg;
    CPU_INT08U  busId;
    

    busId = 0u;                                                 /* CAN Device Number/ CAN Controller Number.            */
    msg   = CanMsgOpen(busId,                         [1]       /* Open frame with ID 0x123 on Message Layer.           */
                       0x123u,
                       0);
   if (msg >= 0) {
        CanMsgRead(         msg,                      [2]       /* Read frame from Message Layer.                       */
                   (void *)&frm,
                            sizeof(CANFRM));
                          
        CanBusWrite(         busId,                   [3]       /* Write Frame to CAN Bus Layer.                        */
                    (void *)&frm,
                             sizeof(CANFRM));
   }
}


Panel
bgColor#f0f0f0

1] Open the CAN Message with the Message Tx Identifier. This can be found in the Message Configuration section [3A] along with the Message Type [3B].

2] Read the updated CAN message to the local CAN Frame. This results in collecting all linked signals and writing all information to the local frame, thus collecting the updated data from the Signal tied to DemoCnt.

3] Transmit the local CAN Frame on the CAN Bus line.