Skip to content

**can_uds** is a lightweight, portable implementation of the ISO14229-1 (Unified Diagnostic Services) protocol stack. It is designed specifically for embedded systems and features a robust port for the **RT-Thread** real-time operating system.**can_uds** 是一个轻量级、可移植的 ISO14229-1 (统一诊断服务) 协议栈实现。它是专为嵌入式系统设计的,并包含针对 **RT-Thread** 实时操作系统的全功能移植层。

License

Notifications You must be signed in to change notification settings

wdfk-prog/can_uds

Repository files navigation

can_uds

1. Introduction

can_uds is a lightweight, portable implementation of the ISO14229-1 (Unified Diagnostic Services) protocol stack. It is designed specifically for embedded systems and features a robust port for the RT-Thread real-time operating system.

It enables your device to act as a UDS Server (ECU) over the CAN bus (via ISO-TP), leveraging RT-Thread's device framework and IPC mechanisms for efficient, non-blocking operation.

1.1. Features

  1. Separation of Concerns: The core UDS logic (iso14229.c) is strictly decoupled from the OS/Hardware layer (iso14229_rtt.c).
  2. RT-Thread Integration: Native support for RT-Thread threads, message queues, and CAN device drivers.
  3. Efficient Dispatching: Utilizes an O(1) lookup table and a "Chain of Responsibility" pattern for event handling, allowing multiple callbacks for a single Service ID (SID).
  4. User-Controlled I/O: The library does not monopolize the CAN interrupt. Users feed data into the stack via a simple API (rtt_uds_feed_can_frame), allowing for flexible filtering and sharing of the CAN bus.
  5. Static Memory Friendly: Service nodes are allocated by the user (typically statically), minimizing dynamic memory fragmentation.

1.2. Directory Structure

Name Description
examples Example code for RT-Thread (MSH commands)
iso14229.c/h Core UDS protocol logic
iso14229_rtt.c/h RT-Thread porting layer
rtt_uds_config.h Default configuration file
Kconfig RT-Thread menuconfig description
SConscript RT-Thread build script
LICENSE License file

1.3. License

can_uds is licensed under the MIT License. See the LICENSE file for details.

2. Usage

2.1. Configuration

Enable the package using RT-Thread's menuconfig:

RT-Thread online packages  --->
    peripherals packages  --->
        [*] Enable iso14229 (UDS) library  --->
            (32) Event Dispatch Table Size
            [*] Enable UDS server example application

2.2. Integration Steps

Step 1: Define a Service Handler

Create a callback function for the specific UDS service (e.g., 0x2E WriteDataByIdentifier) and define the node using the helper macro.

#include "iso14229_rtt.h"

static UDSErr_t handle_led_control(UDSServer_t *srv, void *data) {
    UDSWDBIArgs_t *args = (UDSWDBIArgs_t *)data;
    if (args->dataId == 0x0100) {
        // Perform business logic...
        return UDS_PositiveResponse;
    }
    return UDS_NRC_RequestOutOfRange; // Pass to next handler
}

/* Define the node statically */
RTT_UDS_SERVICE_DEFINE(led_node, UDS_EVT_WriteDataByIdent, handle_led_control);

Step 2: Initialize & Register

Create the UDS instance and register your service node.

rtt_uds_config_t cfg = {
    .can_name = "can1",
    .phys_id = 0x7E0,
    .func_id = 0x7DF,
    .resp_id = 0x7E8,
    .func_resp_id = UDS_TP_NOOP_ADDR,
    .thread_name = "uds_task",
    .stack_size = 2048,
    .priority = 12,
    .rx_mq_pool_size = 32
};

rtt_uds_env_t *env = rtt_uds_create(&cfg);
rtt_uds_service_register(env, &led_node);

Step 3: Feed CAN Data

In your CAN RX callback, read the data and feed it to the stack.

static rt_err_t can_rx_callback(rt_device_t dev, rt_size_t size) {
    struct rt_can_msg msg;
    if (rt_device_read(dev, 0, &msg, sizeof(msg)) == sizeof(msg)) {
        rtt_uds_feed_can_frame(env, &msg); // Non-blocking
    }
    return RT_EOK;
}

3. Examples

The examples directory contains a ready-to-run example (app_uds_example.c). It provides MSH commands to start/stop the UDS server.

Usage in MSH:

msh > uds_example start can1
UDS Started on can1.

Testing with Linux cansend:

# Send WriteDataByIdentifier (0x2E) to DID 0x0001 with value 0x01
cansend can0 7E0#042E000101

4. Contact & Thanks

If you find this package helpful, please give it a Star!


1. 简介

can_uds 是一个轻量级、可移植的 ISO14229-1 (统一诊断服务) 协议栈实现。它是专为嵌入式系统设计的,并包含针对 RT-Thread 实时操作系统的全功能移植层。

它支持基于 CAN 总线(通过 ISO-TP)的 UDS 服务器(ECU)角色,利用 RT-Thread 的设备框架和 IPC 机制实现高效、非阻塞的运行。

1.1. 特性

  1. 关注点分离:核心逻辑 (iso14229.c) 与 OS/硬件层 (iso14229_rtt.c) 严格解耦。
  2. RT-Thread 集成:内置对 RT-Thread 线程、消息队列和 CAN 设备驱动的支持。
  3. 高效分发:使用 O(1) 查找表和“责任链”模式处理服务回调,支持同一服务 ID (SID) 注册多个处理函数(例如不同模块处理不同的 DID)。
  4. 用户控制 I/O:库不独占 CAN 中断。用户通过简单的 API (rtt_uds_feed_can_frame) 将数据投递到协议栈,允许用户灵活过滤或共享 CAN 总线。
  5. 静态内存友好:服务节点由用户分配(通常是静态定义的),减少动态内存碎片。

1.2. 目录结构

名称 描述
examples RT-Thread 示例代码 (MSH 命令)
iso14229.c/h UDS 协议核心逻辑
iso14229_rtt.c/h RT-Thread 移植层
rtt_uds_config.h 默认配置文件
Kconfig RT-Thread menuconfig 配置描述
SConscript RT-Thread 构建脚本
LICENSE 许可证文件

1.3. 许可证

can_uds 遵循 MIT 许可证。详情请参阅 LICENSE 文件。

2. 使用方法

2.1. 配置

在 RT-Thread 的 menuconfig 中启用该软件包:

RT-Thread online packages  --->
    peripherals packages  --->
        [*] Enable iso14229 (UDS) library  --->
            (32) Event Dispatch Table Size   (事件分发表大小)
            [*] Enable UDS server example application (启用示例)

2.2. 集成步骤

步骤 1: 定义服务处理函数

为特定的 UDS 服务(如 0x2E 写数据)创建回调函数,并使用宏定义节点。

#include "iso14229_rtt.h"

static UDSErr_t handle_led_control(UDSServer_t *srv, void *data) {
    UDSWDBIArgs_t *args = (UDSWDBIArgs_t *)data;
    if (args->dataId == 0x0100) {
        // 执行业务逻辑...
        return UDS_PositiveResponse;
    }
    return UDS_NRC_RequestOutOfRange; // 传递给责任链中的下一个处理者
}

/* 静态定义服务节点 */
RTT_UDS_SERVICE_DEFINE(led_node, UDS_EVT_WriteDataByIdent, handle_led_control);

步骤 2: 初始化与注册

创建 UDS 实例并注册您的服务节点。

rtt_uds_config_t cfg = {
    .can_name = "can1",
    .phys_id = 0x7E0,
    .func_id = 0x7DF,
    .resp_id = 0x7E8,
    .func_resp_id = UDS_TP_NOOP_ADDR,
    .thread_name = "uds_task",
    .stack_size = 2048,
    .priority = 12,
    .rx_mq_pool_size = 32
};

rtt_uds_env_t *env = rtt_uds_create(&cfg);
rtt_uds_service_register(env, &led_node);

步骤 3: 投递 CAN 数据

在您的 CAN 接收回调中,读取数据并投递给协议栈。

static rt_err_t can_rx_callback(rt_device_t dev, rt_size_t size) {
    struct rt_can_msg msg;
    if (rt_device_read(dev, 0, &msg, sizeof(msg)) == sizeof(msg)) {
        rtt_uds_feed_can_frame(env, &msg); // 非阻塞调用,可在 ISR 中使用
    }
    return RT_EOK;
}

3. 示例

examples 目录包含一个完整的可运行示例 (app_uds_example.c)。它提供了 MSH 命令来启动/停止 UDS 服务器。

在 MSH 中使用:

msh > uds_example start can1
UDS Started on can1.

使用 Linux cansend 测试:

# 发送 0x2E 写数据指令到 DID 0x0001,值为 0x01
cansend can0 7E0#042E000101

4. 联系方式与致谢

About

**can_uds** is a lightweight, portable implementation of the ISO14229-1 (Unified Diagnostic Services) protocol stack. It is designed specifically for embedded systems and features a robust port for the **RT-Thread** real-time operating system.**can_uds** 是一个轻量级、可移植的 ISO14229-1 (统一诊断服务) 协议栈实现。它是专为嵌入式系统设计的,并包含针对 **RT-Thread** 实时操作系统的全功能移植层。

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published