Skip to content

ISO 14229 (UDS) server and client for embedded systems

License

Notifications You must be signed in to change notification settings

markcorbinuk/iso14229

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iso14229

iso14229是个针对嵌入式系统的UDS(ISO14229-1:2013)服务器和客户端实现。这一套已包含isotp-c ISO15765-2 (ISO-TP)传输层。

iso14229 is a UDS server and client implementation (ISO14229-1:2013) targeting embedded systems. It embeds the isotp-c ISO15765-2 (ISO-TP) transport layer.

API状态: 不稳定 / API status: unstable

特点:

  • 依赖性注入
  • 静态内存分配
  • 独立于处理器架构
    • 测试了: arm, x86-64, ppc
    • 可以用qemu测试更多
  • 单元测试又多又容易扩展

Features:

  • dependency injection gives you complete control
  • uses only static memory allocation
  • architecture-independent
    • tested: arm, x86-64, ppc
    • tests run under qemu
  • has many existing unit-tests and tests are easy to extend

支持服务(服务器和客户端) / supported functions (server and client )

SID name supported
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 文档 / Documentation

例子 / Examples

examples/README.md

测试 / Tests

test_iso14229.c

运行测试 / running tests

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

贡献 / Contributing

欢迎提交贡献/contributions are welcome

感谢 / Acknowledgements

  • isotp which this project embeds

许可 / License

MIT

变更记录 / Changelog

0.0.0

  • 初次发布 / initial release

0.1.0

  • 加客户端 / Add client
  • 加服务器SID 0x27安全访问 / Add server SID 0x27 SecurityAccess
  • API更改 / API changes

0.2.0

  • 删除所有__attribute__((packed)) / removed all instances of __attribute__((packed))
  • 为了简化测试、重构服务器下载功能单元 / refactored server download functional unit API to simplify testing
  • 重构测试 / refactored tests
    • 按服务排列 / ordered by service
    • 给宏定义写文档 / documented macros
  • 删掉了中间件 / removed middleware
  • 简化了服务器例程控制API / simplified server routine control API
  • 删掉了重复函数iso14229ServerEnableService / removed redundant function iso14229ServerEnableService
  • 更新例子 / updated example

0.3.0

  • iso14229ClientRunSequenceBlocking(...) / added iso14229ClientRunSequenceBlocking(...)
  • 加了服务器和客户端例子 / added server and client examples
  • 简化测试流程、删掉了过分模糊宏定义和switch结构 / simplified test flow, deleted opaque macros and switch statements
  • 服务器和客户端结构体简化:尽量用一层深度 / flattened client and server main structs
  • 简化使用、放isotp-c初始化参数到服务器/客户端配置里面 / simplified usage by moving isotp-c initialization parameters into server/client config structs
  • 删除重复服务器缓冲器 / remove redundant buffers in server

iso14229开发文档 / design docs

客户端请求状态机

@startuml
title 客户端请求状态机
note as N1
enum {
    kNoError=0,
    kErrBadRequest,
    kErrP2Timeout,
} ClientErr;

static inline bool isRequestComplete() {return state==Idle;}

while (Idle != client->state) {
    receiveCAN(client);
    Iso14229ClientPoll(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 (时间超过<b>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

About

ISO 14229 (UDS) server and client for embedded systems

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C 95.8%
  • Makefile 2.5%
  • Python 0.7%
  • Starlark 0.6%
  • CMake 0.2%
  • Shell 0.1%
  • GDB 0.1%