forked from driftregion/iso14229
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e89de7e
commit 1882a01
Showing
2 changed files
with
294 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,262 @@ | ||
# iso14229 | ||
|
||
iso14229 is a UDS server and client implementation (ISO14229-1:2013) targeting embedded systems. It embeds the [`isotp-c`](https://github.com/lishen2/isotp-c) ISO15765-2 (ISO-TP) transport layer. | ||
|
||
API status: **unstable** | ||
|
||
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 | ❌ | | ||
|
||
# Documentation | ||
|
||
## Examples | ||
|
||
[examples/README.md](examples/README.md) | ||
|
||
## Tests | ||
|
||
[test_iso14229.c](test_iso14229.c) | ||
|
||
### Running Tests | ||
|
||
```sh | ||
make test | ||
``` | ||
|
||
## qemu | ||
|
||
```sh | ||
CC=powerpc-linux-gnu-gcc make test_bin | ||
qemu-ppc -L /usr/powerpc-linux-gnu test_bin | ||
``` | ||
## wine | ||
|
||
```sh | ||
CC=x86_64-w64-mingw32-gcc make test_bin | ||
wine test_bin.exe | ||
``` | ||
|
||
|
||
# Contributing | ||
|
||
contributions are welcome | ||
|
||
|
||
# Acknowledgements | ||
|
||
- [`isotp`](https://github.com/lishen2/isotp-c) which this project embeds | ||
|
||
# License | ||
|
||
MIT | ||
|
||
# Changelog | ||
|
||
## 0.0.0 | ||
- initial release | ||
|
||
## 0.1.0 | ||
- Add client | ||
- Add server SID 0x27 SecurityAccess | ||
- API changes | ||
|
||
## 0.2.0 | ||
- | ||
- removed all instances of `__attribute__((packed))` | ||
- refactored server download functional unit API to simplify testing | ||
- refactored tests | ||
- ordered by service | ||
- documented macros | ||
- removed middleware | ||
- simplified server routine control API | ||
- removed redundant function `iso14229ServerEnableService` | ||
- updated example | ||
|
||
## 0.3.0 | ||
- added `iso14229ClientRunSequenceBlocking(...)` | ||
- added server and client examples | ||
- simplified test flow, deleted opaque macros and switch statements | ||
- flattened client and server main structs | ||
- simplified usage by moving isotp-c initialization parameters into server/client config structs | ||
- remove redundant buffers in server | ||
|
||
--- | ||
|
||
# Design Docs | ||
|
||
## Client State Machine | ||
|
||
```plantuml | ||
@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 | ||
``` | ||
|
||
```plantuml | ||
@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 | ||
``` | ||
|
||
|
||
```plantuml | ||
@startuml | ||
' !pragma useVerticalIf on | ||
title 客户端请求流程 | ||
start | ||
:clientSendRequest(); | ||
if (验证参数) then (对) | ||
:ok; | ||
else (不对) | ||
:foo; | ||
detach | ||
endif | ||
:clearRequestContext(); | ||
if (等待UDS访问) then (访问接收了,进入UDS会话) | ||
else (时间超过<b>20ms) | ||
@enduml | ||
``` | ||
|
||
## Server 0x78 requestCorrectlyReceived-ResponsePending | ||
|
||
```plantuml | ||
@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 | ||
``` | ||
|
||
```plantuml | ||
@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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters