Skip to content

Commit

Permalink
MERGECOMMIT: native/periph_can: usability improvements RIOT-OS#17949
Browse files Browse the repository at this point in the history
  • Loading branch information
fjmolinas committed Apr 14, 2022
1 parent 57d3280 commit dbcf433
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 189 deletions.
3 changes: 0 additions & 3 deletions boards/native/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ endif

ifneq (,$(filter periph_can,$(FEATURES_USED)))
USEPKG += libsocketcan
ifeq ($(OS),Linux)
CFLAGS += -DCAN_DLL_NUMOF=2
endif
endif

# default to using littlefs2 on the virtual flash
Expand Down
9 changes: 9 additions & 0 deletions boards/native/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ ifneq (,$(filter periph_eeprom,$(FEATURES_USED)))
TERMFLAGS += $(EEPROM_FILE_FLAGS)
endif

VCAN_IFNUM ?= 0
VCAN_IFNAME ?= vcan0
VCAN_IFACE ?= $(VCAN_IFNUM):$(VCAN_IFNAME)
# set the default vcan interface
ifneq (,$(filter periph_can,$(FEATURES_USED)))
PERIPH_CAN_FLAGS = --can $(VCAN_IFACE)
TERMFLAGS += $(PERIPH_CAN_FLAGS)
endif

TERMFLAGS += $(PORT)

ASFLAGS =
Expand Down
4 changes: 4 additions & 0 deletions cpu/native/include/can_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ extern "C" {
* @brief Default parameters (device names)
*/
static const candev_params_t candev_params[] = {
#if CAN_DLL_NUMOF >= 1
{ .name = "can0", },
#endif
#if CAN_DLL_NUMOF >= 2
{ .name = "can1", },
#endif
};

#ifdef __cplusplus
Expand Down
1 change: 1 addition & 0 deletions cpu/native/include/candev_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ extern "C" {

#include <stdbool.h>

#include "can/device.h"
#include "can/candev.h"
#include "mutex.h"

Expand Down
114 changes: 23 additions & 91 deletions tests/candev/README.md
Original file line number Diff line number Diff line change
@@ -1,114 +1,46 @@
# Candev abstraction test
# candev test application

## About

This application is a test for using the candev abstraction directly.
Use this if you want to use a single CAN driver and thus don't need the CAN-DLL layer.

You can select the driver you want to use by redefining the CAN_DRIVER variable in the Makefile. Alternatively you can pass it to the make command.
The application will automatically adapt its initialization procedure to the selected driver.
By default the mcp2515 driver is used.
NOTE: When building for native, use PERIPH_CAN.
The CAN_DRIVER variable is used to select the default CAN_DRIVER, supported
alternatives are:

Native prerequisites
============
For using the can stack on top of socketCAN, available for linux, you need:
- socketCAN (part of kernel starting from 2.6.25)
- install the 32bit version of libsocketcan:

if you're on a 64bit system:
```
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libsocketcan-dev:i386
```
On 32 bit you can just do the following:
```
sudo apt-get install libsocketcan-dev
```

Alternatively, you can compile from source:

```
wget http://www.pengutronix.de/software/libsocketcan/download/libsocketcan-0.0.10.tar.bz2
$ sudo tar xvjf libsocketcan-0.0.10.tar.bz2
$ sudo rm -rf libsocketcan-0.0.10.tar.bz2
$ sudo cd libsocketcan-0.0.10
$ sudo ./configure
compile in 32bits
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAG
$ sudo make
$ sudo make install
sudo ldconfig /usr/local/lib
```

The default native configuration defines two virtual can ifaces to be used.
Before running this test on native, you should create those:

```
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link add dev vcan1 type vcan
sudo ip link set vcan0 up
sudo ip link set vcan1 up
```
- MCP2515 to use `mcp2515` stand-alone CAN controller
- PERIPH_CAN to use `periph_can` controller, usually requires a CAN transceiver
as well: e.g. `tja1042` or `ncv7356` (except for native)

## Usage

### Sending

Messages can be sent over the CAN-bus through the `send` command. Optionally, up to 8 bytes can be passed as arguments (in decimal form). If no arguments are passed it will default to sending AB CD EF (hex).

```
send <bytes>
```

When running the app native on linux, the sent bytes can be seen by scanning the CANbus with candump:

```
$ candump vcan0
```shell
> send <bytes>
# e.g.: send AA BB CC
> send 170 187 204
send 170 187 204
```

### Receiving

The test-app is always listening for incoming CAN messages. They will be stored asynchronously in a buffer and can be requested by means of the `receive` command. Optionally, an argument n can be passed to receive n messages in a row.

```shell
> receive <n>
# e.g.:
> receive 2
Reading from Rxbuf...
id: 1 dlc: 3 Data:
0xAA 0xBB 0xCC
Reading from Rxbuf...
id: 1 dlc: 3 Data:
0xAA 0xBB 0xCC
```
receive <n>
```

If more messages are requested than are available in the buffer, the receive function will block until new data is available.

When running the app native on linux, data can be sent with `cansend`:

```
$ cansend <interface> <can_id>:<hexbytes>
```

e.g.:

```
$ cansend vcan0 001:1234ABCD
```

An alternative is to use `cangen` to generate a number of random can messages:

```
$ cangen <interface> -v -n <n>
```

e.g.:

```
$ cangen vcan0 -v -n 5
```
## Native Setup

will send 5 can messages to vcan0 with verbose output.
Refer to [README.native.can.md](README.native.can.md).
120 changes: 120 additions & 0 deletions tests/candev/README.native.can.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# CAN on `native`

## RIOT native Prerequisites

For using the can stack on top of socketCAN, available for linux, you need:
- socketCAN (part of kernel starting from 2.6.25)
- install the 32bit version of libsocketcan:
- install `can-utils` `sudo apt install can-utils`

By default `native` will use the `libsocketcan` package to download and compile
`libsocketcan` from source.

Alternatively, you can compile from source:

```shell
wget http://www.pengutronix.de/software/libsocketcan/download/libsocketcan-0.0.10.tar.bz2
sudo tar xvjf libsocketcan-0.0.10.tar.bz2
sudo rm -rf libsocketcan-0.0.10.tar.bz2
sudo cd libsocketcan-0.0.10
sudo ./configure
compile in 32bits
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAG
sudo make
sudo make install
sudo ldconfig /usr/local/lib
```
## Connecting RIOT native and Linux Host through socketCAN
The default native configuration defines two virtual can interfaces: `vcan0`
and `vcan1`. By default a single one is enabled, this can be changed through
the `CAN_DLL_NUMOFF` flag.
First, make sure you've compiled the application by calling `make`.
Create the default `vcan` interface
```shell
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set vcan0 up
```
Now start the application by invoking `make term`, this should automatically
connect to the `vcan0` interface.
## Connecting two RIOT native instances
First, make sure you've compiled the application by calling `make`.
Create both `vcan` interfaces:
```shell
sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link add dev vcan1 type vcan
sudo ip link set vcan0 up
sudo ip link set vcan1 up
```
Connect both vcan interfaces so they appear as if they where on the same bus
```shell
sudo modprobe can-gw
sudo cangw -A -s vcan0 -d vcan1 -e
sudo cangw -A -s vcan1 -d vcan0 -e
```
Now start the application by invoking `make term`, this should automatically
connect to the `vcan0` interface. For the second native interface specify the
vcan interface through:
```shell
# first instance
make term
# second instance
VCAN_IFNAME=vcan1 make term
```
## Linux CAN basic commands
To send or receive bytes from the interface `can-utils` can be used:
- send raw CAN frames: by using `cansend` or altenatively `cangen` to send random can messages:
```shell
$ cansend <interface> <can_id>:<hexbytes>
# e.g.:
$ cansend vcan0 001#1234ABCD
```
```shell
$ cangen <interface> -v -n <n>
# e.g.: to send 5 messages through vcan0 with verbose output
$ cangen vcan0 -v -n 5
```
- receive raw CAN frames: by scanning the CANbus with `candump`:
```shell
$ candump <interface>
# e.g.:
$ candump vcan0
```
- send ISO-TP datagrams: by using the `isotpsend` command to send hex bytes
```shell
echo XX XX XX XX | isotpsend -s <src-id> -d <dst-id> <interface>
# e.g.: Send an ISO-TP datagram, source id 700, dest id 708, data 00 11 22 33 aa bb cc dd:
echo 00 11 22 33 aa bb cc dd | isotpsend -s 700 -d 708 vcan0
```
- receive ISO-TP datagrams: by using `isotprecv` command
```shell
$ isotprecb -s <src-id> -d <dst-id> <interface>
# e.g.:
$ isotprecv -s 708 -d 700 vcan0
```
Loading

0 comments on commit dbcf433

Please sign in to comment.