1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-17 05:32:45 +01:00

Merge pull request #17949 from fjmolinas/pr_native_can_improovements

native/periph_can: usability improvements and documentation updates
This commit is contained in:
Alexandre Abadie 2022-04-25 17:52:16 +02:00 committed by GitHub
commit 9821e556ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 218 additions and 189 deletions

View File

@ -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

View File

@ -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 =

View File

@ -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

View File

@ -31,6 +31,7 @@ extern "C" {
#include <stdbool.h>
#include "can/device.h"
#include "can/candev.h"
#include "mutex.h"

View File

@ -1,65 +1,16 @@
# 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
@ -67,48 +18,29 @@ sudo ip link set vcan1 up
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.
```
receive <n>
```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
```
If more messages are requested than are available in the buffer, the receive function will block until new data is available.
## Native Setup
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
```
will send 5 can messages to vcan0 with verbose output.
Refer to [README.native.can.md](README.native.can.md).

View File

@ -0,0 +1,173 @@
# 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
```
___ ___ _______
| _ | | _ | | _ _ |
||A|| ||B|| ||A| |B||
|___| |___| |_______|
| | |
-----------(1)- CAN bus -(2)---------
```
### Through the same vcan interface (1)
First, make sure you've compiled the application by calling `make`.
Create a `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, repeat for the second native instance.
Since they are both connected to the same `vcan` they will seem like they are
on the same CAN-BUS and so will be able to receive messages from each other.
### Through different vcan interfaces with `can-gw` (2)
Alternatively you can connect two distinct `vcan` interfaces through the use of
the `can-gw` module,
First, make sure you've compiled the application by calling `make`.
Create two `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 them with can-gw
```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
```
## Enabling multiple vcan interfaces
By default a single can interface is enabled, a second one can be added
by setting `CAN_DLL_NUMOF=2`, e.g. `CFLAGS=-DCAN_DLL_NUMOF=2`. These two
interfaces will not be connected by default but look like if they where on
different Buses.
To configure which `vcan` interface each native CAN device should use then
`-n` or `--can` flags can be used (see [cpu/native/startup.c](../../cpu/native/startup.c))
```c
" -n <ifnum>:<ifname>, --can <ifnum>:<ifname>\n"
" specify CAN interface <ifname> to use for CAN device #<ifnum>\n"
```
These should be added to `PERIPH_CAN_FLAGS`, eg:
```shell
CFLAGS=-DCAN_DLL_NUMOF=2 BOARD=native PERIPH_CAN_FLAGS="--can 0:vcan1 --can 1:vcan2" make flash 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
```

View File

@ -1,72 +1,15 @@
tests/conn_can
================
# conn_can test application
Demo application for the CAN stack with conn_can interface.
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.11.tar.bz2
$ tar xvjf libsocketcan-0.0.11.tar.bz2
$ rm -rf libsocketcan-0.0.11.tar.bz2
$ cd libsocketcan-0.0.11
$ ./configure
compile in 32bits
./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAG
$ 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
```
Usage
=====
## Usage
Adapt pin configuration in Makefile to match the used CAN transceiver (e.g. TJA1042_STB_PIN)
Build, flash and start the application:
```
export BOARD=your_board
make
make flash
make term
BOARD=<board-name> make flash term
```
To initialize a CAN transceiver device (trx_id = 0)
@ -97,7 +40,6 @@ test_can sendrtr 0 100 7
A remote request frame has a NULL payload but can have a specific data length code (DLC).
Valid DLC val: 0..8
Two threads are launched to enable receiving frames. To receive raw CAN frames,
ids 0x100 and 0x500 with thread 0 on interface 1, with 10s timeout:
```
@ -109,7 +51,6 @@ A connection can be closed with its thread id, for instance:
test_can close 0
```
To send an ISO-TP datagram, first bind a connection with one of the threads,
source id 700, dest id 708, thread 1 and interface 0:
```
@ -138,35 +79,7 @@ sampling point 87.5%:
test_can set_bitrate 250000 875
```
Linux CAN basic commands
========================
## Native Setup
Once the interfaces are set up, can-utils commands provide a way to send and receive
raw CAN frames and ISO-TP datagrams.
For ISO-TP, an experimental module for linux can be found [here](https://github.com/hartkopp/can-isotp).
It needs to be loaded before trying to use ISO-TP protocol.
Here are some basics examples.
Send a raw CAN frame, id 0x100, data 00 11 22:
```
cansend vcan0 100#001122
```
Dump the traffic on a CAN interface:
```
candump vcan0
```
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 datagram:
```
isotprecv -s 708 -d 700 vcan0
```
Please read commands help for more details on usage.
For documentation on how to setup CAN on native and send/receive RAW CAN or ISO-TP
frames refer to [README.native.can.md](../candev/README.native.can.md).