rt-thread-official/bsp/essemi/es32f369x/drivers/bsp_driver_example/can_sample.c

149 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-06-25 misonyo first implementation.
*/
/*
* 程序清单:这是一个 CAN 设备使用例程
* 例程导出了 can_sample 命令到控制终端
* 命令调用格式can_sample can
* 命令解释:命令第二个参数是要使用的 CAN 设备名称,为空则使用默认的 CAN 设备
* 程序功能:通过 CAN 设备发送一帧,并创建一个线程接收数据然后打印输出。
*/
#include <rtthread.h>
#include "rtdevice.h"
#ifdef RT_USING_CAN
#define CAN_DEV_NAME "can0" /* CAN 设备名称 */
static struct rt_semaphore rx_sem; /* 用于接收消息的信号量 */
static rt_device_t can_dev; /* CAN 设备句柄 */
/* 接收数据回调函数 */
static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
{
/* CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void can_rx_thread(void *parameter)
{
int i;
struct rt_can_msg rxmsg = {0};
/* 设置接收回调函数 */
rt_device_set_rx_indicate(can_dev, can_rx_call);
#ifdef RT_CAN_USING_HDR
rt_err_t res;
struct rt_can_filter_item items[5] =
{
RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x100~0x1ffhdr为-1设置默认过滤表 */
RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), /* std,match ID:0x300~0x3ffhdr为-1 */
RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), /* std,match ID:0x211hdr为-1 */
RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), /* std,match ID:0x486hdr为-1 */
{0x555, 0, 0, 0, 0x7ff, 7,} /* std,match ID:0x555hdr为7指定设置7号过滤表 */
};
struct rt_can_filter_config cfg = {5, 1, items}; /* 一共有5个过滤表 */
/* 设置硬件过滤表 */
res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
RT_ASSERT(res == RT_EOK);
#endif
while (1)
{
/* hdr值为-1表示直接从uselist链表读取数据 */
rxmsg.hdr = -1;
/* 阻塞等待接收信号量 */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
/* 从CAN读取一帧数据 */
rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
/* 打印数据ID及内容 */
rt_kprintf("ID:%x ", rxmsg.id);
for (i = 0; i < 8; i++)
{
rt_kprintf("%2x ", rxmsg.data[i]);
}
rt_kprintf("\n");
}
}
int can_sample(int argc, char *argv[])
{
struct rt_can_msg msg = {0};
rt_err_t res;
rt_size_t size;
rt_thread_t thread;
char can_name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(can_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
}
can_dev = rt_device_find(can_name);
if (!can_dev)
{
rt_kprintf("find %s failed!\n", can_name);
return RT_ERROR;
}
/* 初始化CAN接收信号量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 以中断接收及发送方式打开CAN设备 */
res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
RT_ASSERT(res == RT_EOK);
thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
rt_kprintf("create can_rx thread failed!\n");
}
msg.id = 0x78; /* ID为0x78 */
msg.ide = RT_CAN_STDID; /* 标准格式 */
msg.rtr = RT_CAN_DTR; /* 数据帧 */
msg.len = 8; /* 数据长度为8 */
/* 待发送的8字节数据 */
msg.data[0] = 0x00;
msg.data[1] = 0x11;
msg.data[2] = 0x22;
msg.data[3] = 0x33;
msg.data[4] = 0x44;
msg.data[5] = 0x55;
msg.data[6] = 0x66;
msg.data[7] = 0x77;
/* 发送一帧CAN数据 */
size = rt_device_write(can_dev, 0, &msg, sizeof(msg));
if (size == 0)
{
rt_kprintf("can dev write data failed!\n");
}
return res;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(can_sample, can device sample);
#endif