Skip to content

CANbus

There is one CAN port available on STEP2 arranged in one 9-pin connector with RS485/CAN port. That is a serial-to-can adapter based on RS485/CAN, and it is called SERCAN. The driver for this SERCAN does not work with SocketCAN software, instead we provide its own API functions.

SERCAN utilities

By default, there are several CAN utilities pre-installed on STEP2. User can check these utilities by command line:

1
$ ls -l /usr/bin/*SERCAN*


CAN utilities on STEP

1. SERCAN_setBitrate

It can be used to read the current bit rate or set a new one. In order to read current bit rate, simply call a command in terminal.

1
$ sudo SERCAN_setBitrate

The default bit rate of SERCAN module is 1000000 bps (1Mbps). For setting new bit rate, user should input rate pamameter, e.g.

1
$ sudo ERCAN_setBitrate 500K


Update new CAN bit rate

If the input parameter is valid and it is not the current bite rate value, it will be updated and printed. The list of valid bit rate parameter includes “1M, 500K, 250K, 125K, 50K, 20K, 10K, 5K”.

2. SERCAN_send

SERCAN_send is a CAN sending tool, which can be used to send a single CAN frame via SERCAN port.

In the following example, we send via SERCAN port a CAN frame with ID of 123 (decimal) and five bytes of data: 0x01, 0x23, 0x45, 0x67, and 0x89. It should be noted that the maximum number of bytes in one CAN frame is eight.

1
$ SERCAN_send sercan0 123#0123456789

3. SERCAN_dump

SERCAN_dump is a CAN reveiving tool. This utility waits for data to come in the SERCAN port and prints out to the terminal.

1
$ SERCAN_dump sercan0


Example or using SERCAN_dump to read CAN frame from SERCAN port

4. RTSERCAN_send, RTSERCAN_dump

RTSERCAN_send and RTSERCAN_dump have same functions as SERCAN_send, SERCAN_dump except they are using realtime driver.

SERCAN API

SERCAN API is used for programming control SERCAN module. The prototypes of all supported SERCAN API functions can be found in file NRMKsercan.h loacated in the subfolder neuromeka/NRMKFoundation/helper/include/hw/ which is NRMKFoundation installation folder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
//bit rate
int SERCAN_SetBitRate(int fd, char *strBitrate);
int32_t SERCAN_GetBitRate(int fd, uint32_t timeOut /* in ms */);

//normal driver
int  SERCAN_open(void);
int  SERCAN_write(int fd, CAN_FRAME TxFrame);
int  SERCAN_read(int fd, CAN_FRAME *lpRxFrame);
void print_CANFrame(CAN_FRAME Rx_Frame);
//----------------------------------------

//rt driver
int  RTSERCAN_open(void);
int  RTSERCAN_write(int fd, CAN_FRAME TxFrame);
int  RTSERCAN_read(int fd, CAN_FRAME *lpRxFrame);
void rt_print_CANFrame(CAN_FRAME Rx_Frame);

SERCAN API is categorized as three groups: setting bit rate, normal CAN driver, and real-time CAN driver.

Bit rate setting functions

These can be used to get/set bit rate of SERCAN Module.

  • SERCAN_SetBitRate(int fd, char *strBitrate)

    Update new bit rate for SERCAN module. In this function, fd is handler of SERCAN device which has been opened before. strBitrate is new bit rate value in string format. Possible value of strBitrate is 1M, 500K, 250K, 125K, 50K, 20K, 10K, 5K.

  • SERCAN_GetBitRate(int fd, uint32_t timeOut)

    Get current bit rate.

Normal CAN driver functions

Normal CAN driver functions use normal Linux driver to control SERCAN module, these functions are suggested to use in POSIX application.

  • SERCAN_open(void)

    Open SERCAN device and return its hanlder for future use. A negative or zero return handler is an invalid one.

  • SERCAN_write(int fd, CAN_FRAME TxFrame)

    Write a CAN frame to SERCAN port. Here, fd is SERCAN handler obtained by SERCAN_open function. A non-zero return value indicates that write operation was failed.

  • SERCAN_read(int fd, CAN_FRAME *lpRxFrame)

    Read a CAN frame from SERCAN port. The result is saved in lpRxFrame pointer. A non-zero return value indicates that read operation was failed.

Real-time CAN driver functions

All APIs in realtime driver group has same functions as their counterparts in normal driver groups. The only different is that they are implemented using xenomai rtdm driver and therefore are suitable for using in realtime applications.


SERCAN example

In setup packge for STEP2, there are two examples controlling wtih SERCAN module: sercan_test and rtsercan_test. They have same working principle but using different SERCAN driver. The former use normal CAN driver while the later use realtime CAN driver. Let’s take a look at the sercan_test example.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#include "NRMKsercan_tp.h"
#include "NRMKhw_tp.h"

int sercan_fd  = -1;
void * write_thread(void* arg);
void * read_thread(void* arg);

void catch_signal(int sig)
{
    if (sercan_fd>0)
    {
        close(sercan_fd);
    }
    exit(1);
}
//writing thread
void * write_thread(void* arg)
{
    int i;
    CAN_FRAME cfame;
    cfame.can_id=0;
    cfame.can_dlc=8;
    for (i=0; i<8; ++i) cfame.data[i]=0;
    cfame.can_id=0x080;
    cfame.can_dlc=0;

    while(1)
    {
        SERCAN_write(sercan_fd, cfame);
        usleep(1e6); //delay 1s
    }
}
//reading thread
void * read_thread(void* arg)
{
    CAN_FRAME RxFrame;
    while(1)
    {
        if (SERCAN_read(sercan_fd, &RxFrame)==0)
        {
            print_CANFrame(RxFrame);
        }
        usleep(1e4);
    }
}
int main(int argc, char* argv[])
{
    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);

    // open sercan*******************
    sercan_fd=SERCAN_open();
    if (sercan_fd <= 0) return 1;
    //********************************
    usleep(1e5);

    pthread_t tid1,tid2;
    pthread_create(&tid1, NULL, read_thread, NULL);
    pthread_create(&tid2, NULL, write_thread, NULL);
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    return 0;
}

The application structure of sercan_test example is quite similar to tpserial example.

  • In main function, the SERCAN port is opened with SERCAN_open() function at line 56.

  • Two thread are created to handle write and read CAN frame.

  • In write procedure, write_thread from line 21 to line 36, a CAN frame repeatedly written to SERCAN port at every 1s.

  • In read procude, read_thread from line 38 to line 49, SERCAN port is check for incoming data every 10 ms. If a CAN frame was received, it will be printed out the screen.