bætti við can móttökuprófi með síu (Part 2.1)

This commit is contained in:
2026-10-15 15:51:19 +00:00
parent 13a89d7311
commit 6fdf57cca7
3 changed files with 89 additions and 0 deletions
+6
View File
@@ -33,3 +33,9 @@ build_flags = -D CAN_SEND_TEST=1
[env:can_frame_test]
extends = env:nucleo_l432kc
build_flags = -D CAN_FRAME_TEST=1
; CAN reception with a filter (src/can_rx_test.c) instead of the motor app.
; Build/upload: pio run -e can_rx_test -t upload
[env:can_rx_test]
extends = env:nucleo_l432kc
build_flags = -D CAN_RX_TEST=1
+80
View File
@@ -0,0 +1,80 @@
// Part 2.1: CAN reception with a filter. Only frames with id RX_CAN_ID are
// accepted. The driver puts them in a message queue from interrupt context,
// and the main loop takes them out and prints them.
// Built only with the can_rx_test environment (-D CAN_RX_TEST=1).
//
// Test from the Pi:
// cansend can0 321#DEADBEEF -> printed by the Nucleo
// cansend can0 322#DEADBEEF -> rejected by the filter, nothing printed
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/can.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#define CANBUS_NODE DT_CHOSEN(zephyr_canbus)
#define CAN_BITRATE 125000 // Must match the bitrate of can0 on the Pi
#define RX_CAN_ID 0x321 // The only id this node accepts
// Queue for up to 10 received frames. The CAN driver fills it in the
// receive interrupt; nothing else runs in interrupt context.
CAN_MSGQ_DEFINE(rx_msgq, 10);
void can_rx_test_main(void)
{
const struct device *dev = DEVICE_DT_GET(CANBUS_NODE);
if (!device_is_ready(dev)) {
printk("CAN device not ready\n");
return;
}
int err = can_set_bitrate(dev, CAN_BITRATE);
if (err != 0) {
printk("Error setting CAN bitrate (err %d)\n", err);
return;
}
// Accept only RX_CAN_ID: all 11 bits of the id must match the mask.
const struct can_filter filter = {
.id = RX_CAN_ID,
.mask = CAN_STD_ID_MASK,
#ifdef CAN_FILTER_DATA
// Older Zephyr versions must be told to match data frames.
.flags = CAN_FILTER_DATA,
#else
.flags = 0,
#endif
};
// Returns a filter id (>= 0) on success.
int filter_id = can_add_rx_filter_msgq(dev, &rx_msgq, &filter);
if (filter_id < 0) {
printk("Error adding RX filter (err %d)\n", filter_id);
return;
}
err = can_start(dev);
if (err != 0) {
printk("Error starting CAN controller (err %d)\n", err);
return;
}
printk("CAN RX test: %d bit/s, accepting id 0x%03X\n",
CAN_BITRATE, RX_CAN_ID);
struct can_frame frame;
while (1) {
// Sleeps until a frame is in the queue, then processes it here in
// the main thread, where printing is allowed.
k_msgq_get(&rx_msgq, &frame, K_FOREVER);
printk("Received id 0x%03X [%d]:", frame.id, frame.dlc);
for (int i = 0; i < can_dlc_to_bytes(frame.dlc); i++) {
printk(" %02X", frame.data[i]);
}
printk("\n");
}
}
+3
View File
@@ -3,6 +3,7 @@
void motor_application_main(void);
void can_send_test_main(void);
void can_frame_test_main(void);
void can_rx_test_main(void);
int main(void)
{
@@ -10,6 +11,8 @@ int main(void)
can_send_test_main();
#elif CAN_FRAME_TEST
can_frame_test_main();
#elif CAN_RX_TEST
can_rx_test_main();
#else
motor_application_main();
#endif