# 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.

### 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.

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 #include #include #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.