mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #13360 from wosym/tests/candev_native4
Tests/candev: Initial version with native support
This commit is contained in:
commit
bb025e46ac
@ -125,6 +125,7 @@
|
|||||||
/sys/ztimer/ @kaspar030 @bergzand
|
/sys/ztimer/ @kaspar030 @bergzand
|
||||||
|
|
||||||
/tests/ @smlng @leandrolanzieri @aabadie @MichelRottleuthner @fjmolinas
|
/tests/ @smlng @leandrolanzieri @aabadie @MichelRottleuthner @fjmolinas
|
||||||
|
/tests/candev/ @wosym
|
||||||
/tests/emb6* @miri64
|
/tests/emb6* @miri64
|
||||||
/tests/gnrc* @miri64
|
/tests/gnrc* @miri64
|
||||||
/tests/lwip* @miri64
|
/tests/lwip* @miri64
|
||||||
|
@ -726,7 +726,6 @@ ifneq (,$(filter can_linux,$(USEMODULE)))
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter can,$(USEMODULE)))
|
ifneq (,$(filter can,$(USEMODULE)))
|
||||||
DEFAULT_MODULE += auto_init_can
|
|
||||||
USEMODULE += can_raw
|
USEMODULE += can_raw
|
||||||
ifneq (,$(filter can_mbox,$(USEMODULE)))
|
ifneq (,$(filter can_mbox,$(USEMODULE)))
|
||||||
USEMODULE += core_mbox
|
USEMODULE += core_mbox
|
||||||
|
20
tests/candev/Makefile
Normal file
20
tests/candev/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
USEMODULE += shell
|
||||||
|
USEMODULE += can
|
||||||
|
USEMODULE += isrpipe
|
||||||
|
|
||||||
|
# define the CAN driver you want to use here
|
||||||
|
CAN_DRIVER ?= native
|
||||||
|
|
||||||
|
ifeq ($(CAN_DRIVER), PERIPH_CAN)
|
||||||
|
# periph_can modules/variables go here
|
||||||
|
|
||||||
|
else ifeq ($(CAN_DRIVER), CAN_NATIVE)
|
||||||
|
# can_native modules/variables go here
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -DCAN_DRIVER_$(CAN_DRIVER)
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
1
tests/candev/Makefile.ci
Normal file
1
tests/candev/Makefile.ci
Normal file
@ -0,0 +1 @@
|
|||||||
|
FEATURES_BLACKLIST += arch_msp430
|
109
tests/candev/README.md
Normal file
109
tests/candev/README.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# Candev abstraction test
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
will send 5 can messages to vcan0 with verbose output.
|
214
tests/candev/main.c
Normal file
214
tests/candev/main.c
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Nalys
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup tests
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Test application for the candev abstraction
|
||||||
|
*
|
||||||
|
* @author Toon Stegen <tstegen@nalys-group.com>
|
||||||
|
* @author Wouter Symons <wsymons@nalys-group.com>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <isrpipe.h>
|
||||||
|
#include "shell.h"
|
||||||
|
#include "can/device.h"
|
||||||
|
|
||||||
|
#ifdef BOARD_NATIVE
|
||||||
|
|
||||||
|
#include <candev_linux.h>
|
||||||
|
|
||||||
|
static candev_linux_t linux_dev;
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* add other candev drivers here */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RX_RINGBUFFER_SIZE 128 /* Needs to be a power of 2! */
|
||||||
|
static isrpipe_t rxbuf;
|
||||||
|
static uint8_t rx_ringbuf[RX_RINGBUFFER_SIZE];
|
||||||
|
|
||||||
|
static candev_t *candev = NULL;
|
||||||
|
|
||||||
|
static int _send(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
struct can_frame frame = {
|
||||||
|
.can_id = 1,
|
||||||
|
.can_dlc = 3,
|
||||||
|
.data[0] = 0xAB,
|
||||||
|
.data[1] = 0xCD,
|
||||||
|
.data[2] = 0xEF,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
if (argc > 1 + CAN_MAX_DLEN) {
|
||||||
|
printf("Could not send. Maximum CAN-bytes: %d\n", CAN_MAX_DLEN);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
frame.data[i - 1] = atoi(argv[i]);
|
||||||
|
}
|
||||||
|
frame.can_dlc = argc - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = candev->driver->send(candev, &frame);
|
||||||
|
if (ret < 0) {
|
||||||
|
puts("Failed to send CAN-message!");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("sent using mailbox: %d\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _receive(int argc, char **argv)
|
||||||
|
{
|
||||||
|
uint8_t buf[CAN_MAX_DLEN];
|
||||||
|
int n = 1;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
n = strtol(argv[1], NULL, 10);
|
||||||
|
if (n < 1) {
|
||||||
|
puts("Usage: receive <number>");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
uint32_t can_id = 0;
|
||||||
|
uint8_t can_dlc = 0;
|
||||||
|
|
||||||
|
puts("Reading from Rxbuf...");
|
||||||
|
isrpipe_read(&rxbuf, buf, 4); /* can-id */
|
||||||
|
can_id = ((uint32_t)buf[0] << 24) |
|
||||||
|
((uint32_t)buf[1] << 16) |
|
||||||
|
((uint32_t)buf[2] << 8) |
|
||||||
|
((uint32_t)buf[3]);
|
||||||
|
isrpipe_read(&rxbuf, buf, 1); /* can-dlc */
|
||||||
|
can_dlc = buf[0];
|
||||||
|
isrpipe_read(&rxbuf, buf, can_dlc); /* data */
|
||||||
|
|
||||||
|
printf("id: %" PRIx32 " dlc: %" PRIx8 " Data: \n", can_id, can_dlc);
|
||||||
|
for (int i = 0; i < can_dlc; i++) {
|
||||||
|
printf("0x%X ", buf[i]);
|
||||||
|
}
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const shell_command_t shell_commands[] = {
|
||||||
|
{ "send", "send some data", _send },
|
||||||
|
{ "receive", "receive some data", _receive },
|
||||||
|
{ NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void _can_event_callback(candev_t *dev, candev_event_t event, void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
struct can_frame *frame;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case CANDEV_EVENT_ISR:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_ISR\n");
|
||||||
|
dev->driver->isr(candev);
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_WAKE_UP:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_WAKE_UP\n");
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_TX_CONFIRMATION:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_TX_CONFIRMATION\n");
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_TX_ERROR:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_TX_ERROR\n");
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_RX_INDICATION:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_RX_INDICATION\n");
|
||||||
|
|
||||||
|
frame = (struct can_frame *)arg;
|
||||||
|
|
||||||
|
DEBUG("\tid: %" PRIx32 " dlc: %" PRIx8 " Data: \n\t", frame->can_id,
|
||||||
|
frame->can_dlc);
|
||||||
|
for (uint8_t i = 0; i < frame->can_dlc; i++) {
|
||||||
|
DEBUG("0x%X ", frame->data[i]);
|
||||||
|
}
|
||||||
|
DEBUG(" ");
|
||||||
|
|
||||||
|
/* Store in buffer until user requests the data */
|
||||||
|
isrpipe_write_one(&rxbuf,
|
||||||
|
(uint8_t)((frame->can_id & 0x1FFFFFFF) >> 24));
|
||||||
|
isrpipe_write_one(&rxbuf,
|
||||||
|
(uint8_t)((frame->can_id & 0xFF0000) >> 16));
|
||||||
|
isrpipe_write_one(&rxbuf, (uint8_t)((frame->can_id & 0xFF00) >> 8));
|
||||||
|
isrpipe_write_one(&rxbuf, (uint8_t)((frame->can_id & 0xFF)));
|
||||||
|
|
||||||
|
isrpipe_write_one(&rxbuf, frame->can_dlc);
|
||||||
|
for (uint8_t i = 0; i < frame->can_dlc; i++) {
|
||||||
|
isrpipe_write_one(&rxbuf, frame->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_RX_ERROR:
|
||||||
|
DEBUG("_can_event: CANDEV_EVENT_RX_ERROR\n");
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_BUS_OFF:
|
||||||
|
dev->state = CAN_STATE_BUS_OFF;
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_ERROR_PASSIVE:
|
||||||
|
dev->state = CAN_STATE_ERROR_PASSIVE;
|
||||||
|
break;
|
||||||
|
case CANDEV_EVENT_ERROR_WARNING:
|
||||||
|
dev->state = CAN_STATE_ERROR_WARNING;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG("_can_event: unknown event\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
puts("candev test application\n");
|
||||||
|
|
||||||
|
isrpipe_init(&rxbuf, (uint8_t *)rx_ringbuf, sizeof(rx_ringbuf));
|
||||||
|
#ifdef BOARD_NATIVE
|
||||||
|
puts("Initializing Linux Can device");
|
||||||
|
candev_linux_init( &linux_dev, &(candev_linux_conf[0])); /* vcan0 */
|
||||||
|
candev = (candev_t *)&linux_dev;
|
||||||
|
#else
|
||||||
|
/* add initialization for other candev drivers here */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(candev);
|
||||||
|
|
||||||
|
candev->event_callback = _can_event_callback;
|
||||||
|
candev->isr_arg = NULL;
|
||||||
|
|
||||||
|
candev->driver->init(candev);
|
||||||
|
|
||||||
|
char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||||
|
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -11,6 +11,7 @@ USEMODULE += can_isotp
|
|||||||
USEMODULE += conn_can_isotp_multi
|
USEMODULE += conn_can_isotp_multi
|
||||||
USEMODULE += can_pm
|
USEMODULE += can_pm
|
||||||
USEMODULE += can_trx
|
USEMODULE += can_trx
|
||||||
|
USEMODULE += auto_init_can
|
||||||
|
|
||||||
CFLAGS += -DGNRC_PKTBUF_SIZE=4096
|
CFLAGS += -DGNRC_PKTBUF_SIZE=4096
|
||||||
CFLAGS += -DCAN_PKT_BUF_SIZE=64
|
CFLAGS += -DCAN_PKT_BUF_SIZE=64
|
||||||
|
Loading…
Reference in New Issue
Block a user