Protocol Description
UDS is a simple client-server centered protocol, with the client sending UDS requests and the server replying with UDS responses. The protocol itself is split into different types of requests, called UDS services, which in turn may (or may not) have sub-services.

The client initiates a UDS request by sending the server a series of bytes on a reserved communication channel to the ECU. This could be a special CAN identifier, a specific IP address and port, or any other specific, unique, communication channel only used by UDS. The reason for this is the ECU will listen specifically to this communication channel for UDS requests, and will interpret the data coming in according to the UDS protocol.
UDS Service
The first byte in each UDS request is the Service ID. This byte represents the type of UDS service the client wants the ECU server to perform. In total, there are 27 services, each asking the ECU to perform some special task:
Service Name | Byte Value | Description |
---|---|---|
Diagnostic Session Control | 0x10 | UDS sessions are logical containers that act as gateways to enabling and disabling other services. |
ECU Reset | 0x11 | This service instructs the ECU to perform a reset of itself, if safe to do so. |
Security Access | 0x27 | Security allows the ECU to authenticate the tester tool to make sure it is authorized to command UDS services. Many services will not run unless the tester has already authenticated themselves using this service. |
Communication Control | 0x28 | Communication control allows the tester to shut off regular communications on a chosen channel. It is often used before a major download or upload sequence, to free up bandwidth on the communication medium. |
Tester Present | 0x3E | Tester present is like a keep-alive signal between the client and the server. Every time interval, the client sends a tester present message, indicating that the tester is still present (I know, super not obvious). |
Access Timing Parameter | 0x83 | There are many key timing parameters in the UDS protocol dictating, among other things, how long the server has to respond to a command, and how often a client needs to refresh the tester present signal. To read these timings, or set new ones, this service can be used. |
Secure Data Transmission | 0x84 | Authenticating the tester through service 0x27 will guarantee the legitimacy of the tester. However, individual messages may still go through on the wire un-encrypted. If there is a need to encrypt the UDS request or response, this service can be used. |
Control DTC Setting | 0x85 | Diagnostic Trouble Codes (DTCs) indicate some failure detected by the ECU, and are generally not nice to have. During certain servicing events, the tester may want to temporarily turn off detection of DTCs, for which they’d use this service. |
Response on Event | 0x86 | Response on event is an interesting service that has many cool use cases. It essentially tells the ECU to broadcast a UDS message when an event occurs. The type of event which produces the message can be programmed. |
Link Control | 0x87 | Link control can be used to change the communication parameters between the client and server, for the purposes of increasing bandwidth. This could be a speed change (e.g. change the CAN bus baudrate from 500K to 1Mb), or a change in schedule table for LIN, or any other specified communication change. |
Read Data by Identifier | 0x22 | Probably the most widely used UDS service, it allows the client to request a piece of data from the ECU using a special moniker (called the data identifier). The data identifier is generally a 16-bit number. The type of data can literally be anything (engine speed, software version, board serial number, etc). |
Read Memory by Address | 0x23 | It’s what you think it is. Allows the client to read the data at a specified memory location on the ECU. |
Read Scaling Data by Identifier | 0x24 | This service returns the scaling factor for the data from service 0x22. The usual use is when the data returned from 0x22 is scaled into the form of an unsigned integer. Applying the scaling factor from this service can convert it back to a floating point value. |
Read Data by Periodic Identifier | 0x2A | Just like service 0x22, but instead of replying once with the data, this service instructs the ECU to continually broadcast the requested data. |
Dynamically Define Data Identifier | 0x2C | Usually the data ID’s used in service 0x22 are predefined by the ECU. However, using this service, the client can define new data identifiers containing sets of already existing IDs. |
Write Data by Identifier | 0x2E | Like service 0x22 is used to read defined pieces of data, service 0x2E is used to write in pieces of data from the client to the server. For example, 0x2E can be used to write in a serial number onto the ECU. |
Write Data by Address | 0x3D | Allows the client to write data to the ECU’s memory at a specified address. |
Clear Diagnostic Information | 0x14 | When the ECU detects an error, it records a Diagnostic Trouble Code (DTC). Generally, DTCs stay in the ECU’s memory until the error hasn’t been present for some number of key cycles, or when the tester clears them using this service. |
Read DTC Information | 0x19 | Allows the tester to read all the faults and their related details from the ECU – possibly the second most widely used service. |
Input / Output Control by Identifier | 0x2F | Like all the other “identifier” services, this allows the client to identify some I/O on the ECU by a special moniker and control it temporarily – for example, turning on a switch or overriding a PWM signal. |
Routine Control | 0x31 | A favorite of the automotive world, this service allows you to do anything. Only your imagination is the limit here, but this is generally used to exercise some sequence of actions in the ECU for testing purposes (i.e. run the windshield wiper motors at half speed for 15 seconds). |
Request Download | 0x34 | Used by the client to tell the ECU that it would like to download some data on to the ECU’s memory – used as part of a UDS flash sequence for updating firmware. |
Request Upload | 0x35 | Used by the client to tell the ECU it would like it to upload data from its memory back to the client. |
Transfer Data | 0x36 | After a successful upload / download request, this service transfers the payload between client and server. |
Request Transfer Exit | 0x37 | After a successful upload / download request and all payload information being transferred, this request states there is no more data required. |
Request File Transfer | 0x38 | If the ECU employs a proper file system then this service is much better suited than 0x34 or 0x35, as it allows the exchange of a file abstraction, rather than a simple block of hex data. |
Authentication | 0x29 | Brand new in the 2020 edition of ISO14229, this service is meant to bridge the gap with today’s new cybersecurity requirements by allowing a client to use PKI to authenticate itself. |
There will be posts that go into detail on each of these services, complete with typical use cases, tips and tricks, and best practices.
Request Format
As mentioned above, the first byte in what a client sends to the ECU according the UDS protocol is the Service ID. The bytes that follow will then be interpreted as sub-services and / or parameters of that service ID. Let’s see an example of a client request:

As we see above, the client sends the bytes 19 02 01 to the ECU. If we dissect this, we can interpret the bytes as follows:
- 0x19 – From the table above, we see the client is requesting to read DTC information from the ECU.
- 0x02 – This service happens to have sub-services defined for it, and the second byte after the service ID is reserved for the sub-service ID. In this case, 0x02 is interpreted as sub-service 2, “Read DTC status by mask” (more on this later).
- 0x01 – This byte is now interpreted as a parameter to the sub-service “Read DTC status by mask”.
Response Format
Now that we’ve seen an example of a typical UDS request, let’s examine the possible values we can expect in return from the ECU.
Positive Response
A positive response is denoted by the ECU sending back as the first byte the requested service ID + 0x40. Memorize that rule – it comes in quite handy for deciphering logs. The bytes that follow will then be specific to the requested service, but in general either contain the requested data or simply an acknowledgement that the service was executed.
For example, let’s assume that our request from above was correctly processed by the ECU and resulted in a positive response. The return bytes would then be:

Remembering our first rule, we immediately recognize that 0x59 is 0x19 with 0x40 added to it, and hence this is indeed a positive response to our last service request. The other bytes are specific to the “Read DTC status by mask” sub-service.
Negative Response
A negative response is denoted by the first byte of the response being 0x7F. The second byte will then always be the original service ID to which this negative response was in reply to. Finally, a third byte is included, called the Negative Response Code (or NRC, for short). The NRC is the ECUs way of telling you why your request could not be fulfilled.
For example, suppose our request from above was met with a failure. Then, the returning bytes may look like:

A great list of possible NRC’s has been compiled here. As you decipher more and more logs, many NRC’s will begin to look familiar, and you likely won’t need a manual by your side all the time.
Response Pending
There is a third category of response (at least to me, some may disagree). Although technically a negative response, there is an NRC reserved for what is known as “response pending”. This is the ECUs way of informing you that up until now, you request has neither been refused nor denied. Rather, the ECU needs more time to give you a final response, which could still be negative or positive.
For example, below we see a transaction where the ECU replied with “response pending” for some time before rejecting the request:

And below we see several iterations of “response pending” before the ECU returns a positive response:

Conclusion
Now that you know the basics of the protocol, you can begin diving into each specific service, what it means, and how to utilize it. Look out for more posts where I delve into all the services and tie them together to show typical UDS session flows.
Leave a Reply