Versions Compared

Key

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

Test

Application Signals and Messages

Below, we will show the use of CAN Signals and Messages using

Table of Contents
maxLevel4
minLevel2
indent20px

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. This demo It will also transmit messages and receive messages using the CAN Bus protocol. This section assumes that CAN Signals, Messages, and Bus configuration and / initialization have already been done. This example completes the information provided in the previous sections.

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

Code Block
languagecpp
linenumberstrue
                                                                 /* 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_RX_TX_DEMO

The following demo is taken from the µCOS-II or -III can_demo.c file found in $:\Micrium\Software\uC-CAN\Examples. Please note that when running µC/CAN with NO OS the following demo will slightly vary. Please refer to the can_demo.c file for No OS ('NONE') for further details.

App_CAN_Startup()

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.

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

 

Code Block
languagecpp
linenumberstrue
void  Tx_Task (void  *argp)
{
    (void)&argp;                                                /* Suppress Compiler Warning.                           */
    
    while (DEF_ON) {                                            /* Endless while loop.                                  */
        DemoCnt++;
        CanSigWrite( S_CPULOAD,                                 /* Set an Incrementing Counter.                         */
                    &DemoCnt,
                     1);
        
        if (DemoCnt >= DEF_OCTET_MASK) {
            DemoCnt = 0u;                                       /* Reset Demo Count to 0.                               */
        }
                   
        Send_Status();                                          /* Send Signal Status on CAN bus                        */
        
        OSTimeDlyHMSM(0u, 0u, 0u, 200u);
    }
}

 

 

The communication protocol uses in most cases only the CAN messages. The application is responsible for the values of the mapped CAN signals. The following source code completes the example, started in chapter 6.4 Defining CAN Signals and Messages:

...