ISO 您所在的位置:网站首页 pagebuffer ISO

ISO

2023-03-29 04:11| 来源: 网络整理| 查看: 265

iso14229

Build Status

iso14229是个针对嵌入式系统的UDS(ISO14229-1:2013)服务器和客户端会话层实现。为了让你能够更快上手、本库已包含isotp-c以及linux内核ISO15765-2 (ISO-TP)传输层实现。

API状态: 未稳定

快速上手: 服务器 #include "iso14229.h" static uint8_t fn(UDSServer_t *srv, UDSServerEvent_t ev, const void *arg) { return kServiceNotSupported; } int main() { UDSServer_t server; UDSServerConfig_t cfg = { .fn = &fn, }; UDSServerInit(&server, &cfg); for (;;) { UDSServerPoll(&server); } } 快速上手: 客户端 // 参考 examples/client.c

特点:

静态内存分配 独立于处理器架构 测试了: arm, x86-64, ppc 可以用qemu测试更多 单元测试又多又容易扩展 支持服务(服务器和客户端) SID 英文名 支持 0x10 diagnostic session control ✅ 0x11 ECU reset ✅ 0x14 clear diagnostic information ❌ 0x19 read DTC information ❌ 0x22 read data by identifier ✅ 0x23 read memory by address ❌ 0x24 read scaling data by identifier ❌ 0x27 security access ✅ 0x28 communication control ✅ 0x2A read periodic data by identifier ❌ 0x2C dynamically define data identifier ❌ 0x2E write data by identifier ✅ 0x2F input control by identifier ❌ 0x31 routine control ✅ 0x34 request download ✅ 0x35 request upload ❌ 0x36 transfer data ✅ 0x37 request transfer exit ✅ 0x38 request file transfer ❌ 0x3D write memory by address ❌ 0x3E tester present ✅ 0x83 access timing parameter ❌ 0x84 secured data transmission ❌ 0x85 control DTC setting ✅ 0x86 response on event ❌ 文档 服务器事件

参考iso14229.h enum UDSServerEvent

UDS_SRV_EVT_DiagSessCtrl (0x10) 会话控制 参数 typedef struct { const enum UDSDiagnosticSessionType type; /**< 请求会话类型 */ uint16_t p2_ms; /**< 可选返回值: p2时间设置 */ uint32_t p2_star_ms; /**< 可选返回值: p2*时间设置 */ } UDSDiagSessCtrlArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 允许进入请求中的会话类型 0x12 kSubFunctionNotSupported 本器不支持请求中的会话类型 0x22 kConditionsNotCorrect 本器当前无法进入请求的会话类型 UDS_SRV_EVT_ECUReset (0x11) ECU复位 参数 typedef struct { const enum UDSECUResetType type; /**< 请求的复位类型 */ uint8_t powerDownTime; /**< 可选返回值: 通知客户端离关机的时间(0-254秒) 255表示无法判断具体关机时间*/ } UDSECUResetArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 允许复位 0x12 kSubFunctionNotSupported 本器不支持请求的复位类型 0x22 kConditionsNotCorrect 本器目前无法复位 0x33 kSecurityAccessDenied 当前安全级别不允许复位 UDS_SRV_EVT_ReadDataByIdent (0x22) 读取数据 参数 typedef struct { const uint16_t dataId; /*! 数据标识符 */ /*! 函数:拷贝数据到服务器发送缓冲器. 成功会返回`kPositiveResponse`。若数据大小超过了服务器发送缓冲器的大小、会返回`kResponseTooLong`。*/ const uint8_t (*copy)(UDSServer_t *srv, const void *src, uint16_t count); } UDSRDBIArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 允许读取 (注意调用copy(...)) 0x14 kResponseTooLong 响应大小超过发送缓冲器大小 0x31 kRequestOutOfRange 请求的标识符不支持 0x33 kSecurityAccessDenied 当前安全级别不允许读取请求的数据标识符 UDS_SRV_EVT_SecAccessRequestSeed, UDS_SRV_EVT_SecAccessValidateKey (0x27) 安全访问 参数 typedef struct { const uint8_t level; /*! 请求安全级别 */ const uint8_t *const dataRecord; /*! 请求数据 */ const uint16_t len; /*! 请求数据大小 */ /*! 函数:拷贝数据到服务器发送缓冲器. 成功会返回`kPositiveResponse`。若数据大小超过了服务器发送缓冲器的大小、会返回`kResponseTooLong`。*/ uint8_t (*copySeed)(UDSServer_t *srv, const void *src, uint16_t len); } UDSSecAccessRequestSeedArgs_t; typedef struct { const uint8_t level; /*! 请求安全访问级别 */ const uint8_t *const key; /*! 客户端发过来的密钥 */ const uint16_t len; /*! 密钥大小 */ } UDSSecAccessValidateKeyArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x12 kSubFunctionNotSupported 该安全级别未支持 0x22 kConditionsNotCorrect 当前无法处理该请求 0x31 kRequestOutOfRange dataRecord的数据无效 0x35 kInvalidKey 密钥对不上 0x36 kExceededNumberOfAttempts 密码错误太多 0x37 kRequiredTimeDelayNotExpired 不晓得 UDS_SRV_EVT_CommCtrl (0x28) 通讯控制 参数 typedef struct { enum UDSCommunicationControlType ctrlType; enum UDSCommunicationType commType; } UDSCommCtrlArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x12 kSubFunctionNotSupported 请求中的通讯控制类型未支持 0x22 kConditionsNotCorrect 当前无法开启/关闭请求中的通讯控制类型 0x31 kRequestOutOfRange 请求中的通讯控制类型或者通讯类型有错 UDS_SRV_EVT_WriteDataByIdent (0x2E) 写入数据 参数 typedef struct { const uint16_t dataId; /*! 数据标识符 */ const uint8_t *const data; /*! 数据 */ const uint16_t len; /*! 数据大小 */ } UDSWDBIArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 写入成功 0x22 kConditionsNotCorrect 当前无法写入 0x31 kRequestOutOfRange 数据标识符不支持或者数据内容有错 0x33 kSecurityAccessDenied 当前安全级别不允许写入请求中的数据标识符 0x72 kGeneralProgrammingFailure 写入内存失败 UDS_SRV_EVT_RoutineCtrl (0x31) 例程控制 参数 typedef struct { const uint8_t ctrlType; /*! 例程控制类型 */ const uint16_t id; /*! 例程标识符 */ const uint8_t *optionRecord; /*! 客户端可选数据 */ const uint16_t len; /*! 数据大小 */ /*! 函数:拷贝数据到服务器发送缓冲器. 成功会返回`kPositiveResponse`。若数据大小超过了服务器发送缓冲器的大小、会返回`kResponseTooLong`。*/ uint8_t (*copyStatusRecord)(UDSServer_t *srv, const void *src, uint16_t len); } UDSRoutineCtrlArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x22 kConditionsNotCorrect 当前无法操作 0x24 kRequestSequenceError 要求停止但未开始。要求开始但已开始(可选)。没有结果因为例程从来没有开始。 0x31 kRequestOutOfRange 请求中的例程标识符未支持或者optionRecord无效 0x33 kSecurityAccessDenied 当前安全访问级别不允许请求的操作 0x72 kGeneralProgrammingFailure 内部内存操作失败(如:擦除flash) UDS_SRV_EVT_RequestDownload (0x34) 请求下载 参数 typedef struct { const void *addr; /*! 请求下载地址 */ const size_t size; /*! 请求下载大小 */ const uint8_t dataFormatIdentifier; /*! 可选:数据格式标识符 */ uint16_t maxNumberOfBlockLength; /*! 返回值: 通知客户端能接受的`TransferData`长度是多长 */ } UDSRequestDownloadArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x22 kConditionsNotCorrect 当前无法操作 0x31 kRequestOutOfRange dataFormatIdentifier,addr或者size无效。 0x33 kSecurityAccessDenied 当前安全访问级别不允许请求的操作 0x34 kAuthenticationRequired 客户端权利不足 0x70 kUploadDownloadNotAccepted 因故障无法下载 UDS_SRV_EVT_TransferData (0x36) 传输数据 参数 typedef struct { const uint8_t *const data; /*! 数据 */ const uint16_t len; /*! 数据大小 */ /*! 函数:拷贝数据到服务器发送缓冲器. 成功会返回`kPositiveResponse`。若数据大小超过了服务器发送缓冲器的大小、会返回`kResponseTooLong`。*/ uint8_t (*copyResponse)( UDSServer_t *srv, const void *src, uint16_t len); } UDSTransferDataArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x31 kRequestOutOfRange data内容无效或者大小不对 0x72 kGeneralProgrammingFailure 写入内存失败 0x92 kVoltageTooHigh 无法写flash:电压过高 0x93 kVoltageTooLow 无法写flash:电压过低 UDS_SRV_EVT_RequestTransferExit (0x37) 请求传输结束 参数 typedef struct { const uint8_t *const data; /*! 数据 */ const uint16_t len; /*! 数据大小 */ /*! 函数:拷贝数据到服务器发送缓冲器. 成功会返回`kPositiveResponse`。若数据大小超过了服务器发送缓冲器的大小、会返回`kResponseTooLong`。*/ uint8_t (*copyResponse)(UDSServer_t *srv, const void *src, uint16_t len); } UDSRequestTransferExitArgs_t; 支持返回值 值 枚举 意义 0x00 kPositiveResponse 肯定响应 0x31 kRequestOutOfRange data内容无效或者大小不对 0x72 kGeneralProgrammingFailure 完成数据传输失败 例子

examples/README.md

测试

test_uds.c

运行测试 make test qemu CC=powerpc-linux-gnu-gcc make test_bin qemu-ppc -L /usr/powerpc-linux-gnu test_bin wine CC=x86_64-w64-mingw32-gcc make test_bin wine test_bin.exe 贡献

欢迎提交贡献

感谢 isotp which this project embeds 许可

MIT

变更记录 0.0.0 初次发布 0.1.0 加客户端 加服务器SID 0x27安全访问 API更改 0.2.0 删除所有__attribute__((packed)) 为了简化测试、重构服务器下载功能单元 重构测试 按服务排列 给宏定义写文档 删掉了中间件 简化了服务器例程控制API 删掉了重复函数udsServerEnableService 更新例子 0.3.0 加udsClientRunSequenceBlocking(...) 加了服务器和客户端例子 简化测试流程、删掉了过分模糊宏定义和switch结构 服务器和客户端结构体简化:尽量用一层深度 简化使用、放isotp-c初始化参数到服务器/客户端配置里面 删除重复服务器缓冲器 0.4.0 重构RDBIHandler:用安全memmove 尽可能不用enum在结构体里面 传输层可插件。现在支持linux内核ISO-TP驱动。isotp-c同时也支持。看看例子 examples 0.5.0 可用性: 重构成单个.c/.h模块 可用性: 默认传输层配置现在自带 API整理: 用UDS前缀在所有导出函数上 API整理: 服务器事件用单个回调函数 开发者文档 客户端请求状态机 @startuml title 客户端请求状态机 note as N1 enum { kNoError=0, kErrBadRequest, kErrP2Timeout, } ClientErr; static inline bool isRequestComplete() {return state==Idle;} while (Idle != client->state) { receiveCAN(client); UDSClientPoll(client); } end note state Idle state Sending state Sent state SentAwaitResponse state ProcessResponse Idle: if (ISOTP_RET_OK == isotp_receive(...)) // Error ProcessResponse: isotp_receive() ProcessResponse: _ClientValidateResponse(...) ProcessResponse: _ClientHandleResponse(...) Sending --> Sent: 传输层完成传输 Sent --> Idle : suppressPositiveResponse Sending --> SentAwaitResponse: !suppressPositiveResponse SentAwaitResponse -> Idle: 响应收到了 ||\np2 超时 SentAwaitResponse --> ProcessResponse : ISOTP_RECEIVE_STATUS_FULL == link->receive_status ProcessResponse --> Idle [*] -> Idle Idle -> Sending : _SendRequest() @enduml @startuml title Request Lifecycle alt normal alt positive response client --> client: Sending client -> server : *Any* Service client --> client: SentAwaitResponse: set p2 alt 0x78 requestCorrectlyReceived-ResponsePending server -> client : 0x3F 0x78 client -->server : txLink idle client --> client: SentAwaitResponse: set p2star end server -> client : Positive Service Response client --> client: Idle else negative response server -> client !! : Negative Service Response client --> client: Idle: RequestErrorNegativeResponse else SID mismatch server -> client !! : Mismatched Service Response client --> client: Idle: RequestErrorResponseSIDMismatch end else unexpected response server -> client !! : Unexpected Response client --> client: Idle: RequestErrorUnsolicitedResponse end @enduml @startuml ' !pragma useVerticalIf on title 客户端请求流程 start :clientSendRequest(); if (验证参数) then (对) :ok; else (不对) :foo; detach endif :clearRequestContext(); if (等待UDS访问) then (访问接收了,进入UDS会话) else (时间超过20ms) @enduml 服务器 0x78 requestCorrectlyReceived-ResponsePending @startuml client -> server : *Any* Service server -> userServiceHandler: handler(args) note right: Doing this will take a long time\nso I return 0x78 userServiceHandler -> server: 0x78 server -> client : 0x3F 0x78 client -->server : txLink idle server -> userServiceHandler: handler(args) note right: actually call the long-running service ... p2* > t > p2 ... userServiceHandler -> server : Service Response server -> client : Service Response @enduml @startuml ' !pragma useVerticalIf on title 0x78流程(写flash) start :BufferedWriterWrite(BufferedWriter *self, const uint8_t *ibuf, uint32_t size, bool RCRRP); if (RCRRP) then (true) :write to flash; else (false) endif if (iBufIdx == size) then (true) :write to pageBuffer; :iBufIdx = 0; :return kBufferedWriterWritePending; :0x78 RCRRP; detach; else (false) :memmove(pageBuffer + pageBufIdx, iBuf + iBufIdx, size - iBufIdx); :write to pageBuffer; :iBufIdx += size; :0x01 PositiveResponse; :0x78 RCRRP; detach endif @enduml


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有