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:
commit
9821e556ac
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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
|
||||
|
@ -31,6 +31,7 @@ extern "C" {
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "can/device.h"
|
||||
#include "can/candev.h"
|
||||
#include "mutex.h"
|
||||
|
||||
|
@ -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).
|
||||
|
173
tests/candev/README.native.can.md
Normal file
173
tests/candev/README.native.can.md
Normal 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
|
||||
```
|
@ -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).
|
||||
|
Loading…
Reference in New Issue
Block a user