Giter Site home page Giter Site logo

sandy-marker / iso14229 Goto Github PK

View Code? Open in Web Editor NEW

This project forked from driftregion/iso14229

0.0 0.0 0.0 113 KB

ISO 14229 (UDS) server and client for embedded systems

License: MIT License

GDB 0.07% Starlark 0.60% Makefile 2.09% C 95.74% Python 1.26% CMake 0.15% Shell 0.08%

iso14229's Introduction

iso14229

iso14229是个针对嵌入式系统的UDS(ISO14229-1:2013)服务器和客户端执行。

iso14229 is a UDS server and client implementation (ISO14229-1:2013) targeting embedded systems.

Stability: Experimental

iso14229 文档 / Documentation

服务器:怎么用 / Server: Usage

// =====================================
// STEP 1: implement the hooks
// =====================================
/**
* @brief iso14229.h required function
* Implement this with the functions available on your host platform
 */
int userSendCAN(const uint32_t arbitration_id, const uint8_t *data, const uint8_t size) {
    struct can_frame frame = {0};

    frame.can_id = arbitration_id;
    frame.can_dlc = size;
    memmove(frame.data, data, size);

    if (write(g_sockfd, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) {
        perror("Write err");
        exit(-1);
    }
    return 0;
}

/**
 * @brief iso14229.h required function
 * Implement this with the functions available on your host platform
 */
uint32_t userGetms() {
    struct timeval te;
    gettimeofday(&te, NULL);                                         // get current time
    long long milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; // calculate milliseconds
    return milliseconds;
}

/**
 * @brief iso14229.h required function
 * Implement this with the functions available on your host platform
 */
void userDebug(const char *fmt, ...) {}

/**
 * @brief Reset the server
 */
void hardReset() { printf("server hardReset!\n"); }

// =====================================
// STEP 2: initialize the server
// =====================================

int main(int ac, char **av) {
    // setup the linux CAN socket. This will vary depending on your platform. see example/server.c
    setupSocket(ac, av); 

    uint8_t isotpPhysRecvBuf[ISOTP_BUFSIZE];
    uint8_t isotpPhysSendBuf[ISOTP_BUFSIZE];
    uint8_t isotpFuncRecvBuf[ISOTP_BUFSIZE];
    uint8_t isotpFuncSendBuf[ISOTP_BUFSIZE];
    uint8_t udsSendBuf[ISOTP_BUFSIZE];
    uint8_t udsRecvBuf[ISOTP_BUFSIZE];

    IsoTpLink isotpPhysLink;
    IsoTpLink isotpFuncLink;
    Iso14229Server uds;

    const Iso14229ServerConfig cfg = {
        .phys_recv_id = SRV_PHYS_RECV_ID,
        .func_recv_id = SRV_FUNC_RECV_ID,
        .send_id = SRV_SEND_ID,
        .phys_link = &isotpPhysLink,
        .func_link = &isotpFuncLink,
        .receive_buffer = udsRecvBuf,
        .receive_buf_size = sizeof(udsRecvBuf),
        .send_buffer = udsSendBuf,
        .send_buf_size = sizeof(udsSendBuf),
        .userRDBIHandler = NULL,
        .userWDBIHandler = NULL,
        .userHardReset = hardReset,
        .userGetms = userGetms,
        .p2_ms = 50,
        .p2_star_ms = 2000,
        .s3_ms = 5000,
    };

    Iso14229Server srv;

    /* initialize the ISO-TP links */
    isotp_init_link(&isotpPhysLink, SRV_SEND_ID, isotpPhysSendBuf, sizeof(isotpPhysSendBuf),
                    isotpPhysRecvBuf, sizeof(isotpPhysRecvBuf), userGetms, userSendCAN,
                    userDebug);
    isotp_init_link(&isotpFuncLink, SRV_SEND_ID, isotpFuncSendBuf, sizeof(isotpFuncSendBuf),
                    isotpFuncRecvBuf, sizeof(isotpFuncRecvBuf), userGetms, userSendCAN,
                    userDebug);

    Iso14229ServerInit(&srv, &cfg);
    iso14229ServerEnableService(&srv, kSID_ECU_RESET);

    // =====================================
    // STEP 3: poll the server
    // =====================================

    while (!g_should_exit) {
        uint32_t arb_id;
        uint8_t data[8];
        uint8_t size;

        Iso14229ServerPoll(&srv);
        if (0 == CANRxPoll(&arb_id, data, &size)) {
            iso14229ServerReceiveCAN(&srv, arb_id, data, size);
        }
        msleep(10);
    }
}

服务器:例子 / Server: Example (linux)

See example for a simple server with socketCAN bindings

# 设置虚拟socketCAN接口
# setup a virtual socketCAN interface
sudo ip link add name can9 type vcan
sudo ip link set can9 up

# 构建例子服务器
# build the example server
make example/linux

# 在can9接口上运行例子服务器
# run the example server on can9
./example/linux can9
# (可选)在另外一个终端,看看虚拟CAN母线上的数据
# (Optional) In a another shell, monitor the virtual link
candump can9
# 在另外一个终端,安装python依赖性
# In another shell, install the required python packages
pip3 install -r example/requirements.txt

# 然后运行客户端
# then run the client
./example/client.py can9

服务器:自定服务回调函数 / Server: Custom Service Handlers

Service iso14229 Function
0x11 ECUReset void userHardReset()
0x22 ReadDataByIdentifier enum Iso14229ResponseCode userRDBIHandler(uint16_t dataId, const uint8_t *data, uint16_t *len)
0x27 SecurityAccess enum Iso14229ResponseCode userSecurityAccessHandler()
0x28 CommunicationControl enum Iso14229ResponseCode userCommunicationControlHandler(uint8_t controlType, uint8_t communicationType)
0x2E WriteDataByIdentifier enum Iso14229ResponseCode userWDBIHandler(uint16_t dataId, const uint8_t *data, uint16_t len)
0x31 RoutineControl int Iso14229ServerRegisterRoutine(Iso14229Server* self, const Iso14229Routine *routine);
0x34 RequestDownload, 0x36 TransferData, 0x37 RequestTransferExit int iso14229ServerRegisterDownloadHandler(Iso14229Server* self, Iso14229DownloadHandlerConfig *handler);

服务器:应用/启动软件(中间件) / Server: Application / Boot Software (Middleware)

用户自定的服务器逻辑(比如ISO-14229规范指定的”Application Software"和"Boot Software")可以用中间件来实现。 User-defined server behavior such as the "Application Software" and "Boot Software" described in ISO-14229 can be implemented through middleware.

struct Iso14229UserMiddleware;

客户端:怎么用 / Client: Basic Usage

Currently undocumented. See test_iso14229.c for usage examples

贡献/contributing

欢迎来贡献/contributions are welcome

感谢 / Acknowledgements

  • isotp which this project embeds

License

MIT

变更记录 / Changelog

0.0.0

  • initial release

0.1.0

  • Add client
  • Add server SID 0x27 SecurityAccess
  • API changes

iso14229开发文档 / design docs

bazel test --compilation_mode=dbg //...

客户端请求状态机

@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

iso14229's People

Contributors

driftregion avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.