USB-SD-Mux now reads SD Card registers
The USB-SD-Mux is designed to make life easier for embedded software engineers by automating the transfer of an SD card between a host PC (deploying a new software image to the SD card) and an embedded Linux device. Since we have introduced this device into our Embedded Linux development workflow back in 2019 we have probably written thousands of SD card images with it. Now the usbsdmux software controlling the device has gained a new feature: It can now read and decode a few SD card information registers. This makes it possible to gain more insight into the capabilities of the used SD card - especially while developing on low-level software and drivers interfacing with the SD card.
Once the SD card is switched to host
the new info
command reads the
SCR
(SD Card Configuration Register),
CID
(Card Identification Register) and
CSD_20
(Card Specific Data) register.
To make post-processing easier, there is also a --json
switch that formats the output
machine readable.
In action the output looks something like this: (For a full example of the output scroll to the end of this post.)
$ usbsdmux /dev/usb-sd-mux/id-00035.00008 info
SCR Register Value: 0235848700000000
(...)
CID Register Value: 9f5449202020202010830258e5017600
MID: Manufacturer ID
raw: 0b10011111 == 0x9f == 159
enum: Kingston SD
(...)
PSN: Product serial number
raw: 0b10000011000000100101100011100101 == 0x830258e5 == 2197969125
value: 2197969125
MDT_Y: Manufacturing date (year)
raw: 0b00010111 == 0x17 == 23
value: 2023
MDT_M: Manufacturing date (month)
raw: 0b0110 == 0x6 == 6
value: 7
(...)
CSD_20 Register Value: 400e0032db79000074197f800a400000
(...)
TRAN_SPEED: max. data transfer rate
raw: 0b00110010 == 0x32 == 50
decoded: (2.5, '10Mbit/s')
value: 25000000.0 bit/s
To implement this feature Jan first implemented reading SD Card registers from our card reader. To archive this the tool uses vendor specific SCSI commands implemented by the card reader on the USB-SD-Mux.
Next Jan implemented register decoding.
Out of curiosity we we grabbed some SD cards we had lying around:
- SD Cards from well-known brands tend to carry (potentially) individual serial numbers.
Also the
Manufacturer
andProduct Name
fields are often set. - We have also found two no-name SD Cards (purchased at the same time and that totally look the same from the outside)
contain widely different values in the
CID
register. Also one of these cards had a serial number far below 10.000. But it's still unclear to us what that means.
We will probably write a statistics post at some point in the future 😀.
Statistics via MQTT
Next we want to automate the collection of SD Card information and statistics in our lab. Therefore we will add an (optional) MQTT client to the USB-SD-Mux tool. This way we hope to get more insight into details like:
- What cards are used.
- How manufacturers fill the fields in the
CID
register (e.g.product name
,serial number
). - How much data is written to a card over it's lifetime.
We are currently implementing this feature and will add it to the USB-SD-Mux tool once it is ready.
Complete list of decoded register values
Finally, here is the complete output of the info
command:
$ usbsdmux /dev/usb-sd-mux/id-00035.00008 info
SCR Register Value: 0235848700000000
SCR_STRUCTURE: SCR Structure
raw: 0b0000 == 0x0 == 0
enum: 1.0
SD_SPEC: SD Memory Card - Spec. Version
raw: 0b0010 == 0x2 == 2
enum: 2.00 or 3.0X
DATA_STAT_AFTER_ERASE: data status after erase
raw: 0b0 == 0x0 == 0
value: False
SD_SECURITY: CPRM Security Support
raw: 0b011 == 0x3 == 3
enum: SDHC Card (Security Version 2.00)
SD_BUS_WIDTHS: DAT Bus widths supported
raw: 0b0101 == 0x5 == 5
bits: 1 bit, 4 bit
SD_SPEC3: Spec. Version 3.00 or higher
raw: 0b1 == 0x1 == 1
EX_SECURITY: Extended Security Support
raw: 0b0000 == 0x0 == 0
RESERVED
raw: 0b100100001 == 0x121 == 289
CMD_SUPPORT: Command Support bits
raw: 0b11 == 0x3 == 3
bits: Speed Class Control (CMD20), Set Block Count (CMD23)
RESERVED_MFG
raw: 0b00000000000000000000000000000000 == 0x0 == 0
CID Register Value: 9f5449202020202010830258e5017600
MID: Manufacturer ID
raw: 0b10011111 == 0x9f == 159
enum: Kingston SD
OID: OEM/Application ID
raw: 0b0101010001001001 == 0x5449 == 21577
value: TI
PNM: Product name
raw: 0b0010000000100000001000000010000000100000 == 0x2020202020 == 137977929760
value:
PRV: Product revision
raw: 0b00010000 == 0x10 == 16
value: 1.0
PSN: Product serial number
raw: 0b10000011000000100101100011100101 == 0x830258e5 == 2197969125
value: 2197969125
RESERVED
raw: 0b0000 == 0x0 == 0
MDT_Y: Manufacturing date (year)
raw: 0b00010111 == 0x17 == 23
value: 2023
MDT_M: Manufacturing date (month)
raw: 0b0110 == 0x6 == 6
value: 7
CRC: CRC7 checksum
raw: 0b0000000 == 0x0 == 0
NU1: not used, always 1
raw: 0b0 == 0x0 == 0
CSD_20 Register Value: 400e0032db79000074197f800a400000
CSD_STRUCTURE: CSD structure
raw: 0b01 == 0x1 == 1
enum: 2.0
TAAC: data read access-time-1
raw: 0b00001110 == 0xe == 14
decoded: (1.0, '1ms')
value: 1000000.0 ns
NSAC: data read access-time-2
raw: 0b00000000 == 0x0 == 0
value: 0 CLK cycles
TRAN_SPEED: max. data transfer rate
raw: 0b00110010 == 0x32 == 50
decoded: (2.5, '10Mbit/s')
value: 25000000.0 bit/s
CCC: card command classes
raw: 0b110110110111 == 0xdb7 == 3511
bits: 0, 1, 2, 4, 5, 7, 8, 10, 11
READ_BL_LEN: max. read data block length
raw: 0b1001 == 0x9 == 9
value: 512 bytes
READ_BL_PARTIAL: partial blocks for read allowed
raw: 0b0 == 0x0 == 0
value: False
WRITE_BLK_MISALIGN: write block misalignment allowed
raw: 0b0 == 0x0 == 0
value: False
READ_BLK_MISALIGN: read block misalignment allowed
raw: 0b0 == 0x0 == 0
value: False
DSR_IMP: driver stage register implemented
raw: 0b0 == 0x0 == 0
value: False
C_SIZE: device size
raw: 0b0000000111010000011001 == 0x7419 == 29721
value: 15582887936 bytes
ERASE_BLK_EN: erase single block enable
raw: 0b1 == 0x1 == 1
value: True
SECTOR_SIZE: erase sector size
raw: 0b1111111 == 0x7f == 127
value: 128 write blocks
WP_GRP_SIZE: write protect group size
raw: 0b0000000 == 0x0 == 0
value: 1 erase sectors
WP_GRP_ENABLE: write protect group enable
raw: 0b0 == 0x0 == 0
value: False
R2W_FACTOR: write speed factor
raw: 0b010 == 0x2 == 2
value: 4 multiples of read access time
WRITE_BL_LEN: max. write data block length
raw: 0b1001 == 0x9 == 9
value: 512 bytes
WRITE_BL_PARTIAL: partial blocks for write allowed
raw: 0b0 == 0x0 == 0
value: False
FILE_FORMAT_GRP: file format group
raw: 0b0 == 0x0 == 0
COPY: copy flag
raw: 0b0 == 0x0 == 0
value: False
PERM_WRITE_PROTECT: permanent write protection
raw: 0b0 == 0x0 == 0
value: False
TMP_WRITE_PROTECT: temporary write protection
raw: 0b0 == 0x0 == 0
value: False
FILE_FORMAT: file format
raw: 0b000 == 0x0 == 0
enum: Hard disk-like file system with partition table
CRC
raw: 0b0000000 == 0x0 == 0
Further Readings
USB-SD-Mux: EMC Testing
Today Jonas and I went to our EMC testing lab to continue the measurements needed to certify electromagnetic compatibility for the USB-SD-Mux.
USB-SD-Mux: Automated SD-Card Juggler
Once the bootloader on your embedded device is up and running the development of kernel and userland in PTXdist-based BSPs is usually based on booting from network. Thus there is no need for the developer to write the boot media with a new image.
The USB-SD-Mux is now FAST
We have been distributing the USB-SD-Mux with our partner company Linux Automation GmbH since 2019. This has enabled us to make work easier for many embedded developers and improve software quality. At the same time, technology is advancing: micro SD cards are becoming faster and USB-C is now established as the standard.
LXA USB-T1L ❤️ Beagle Play: Exploring Single Wire Ethernet
It seems everybody is talking about Single Pair Ethernet (SPE) these days. So we want to follow the trend and do the same :-) SPE is a class of Ethernet transmission standards that uses just a single pair of twisted pair cable for data transmission. There are multiple SPE variants spanning maximum data rates from a hand full MBit/s to multiple GBit/s and cable lengths from a hand full of meters to kilometers. The most interesting ones from our embedded-centric point of view are 10Base-T1L (point-to-point, up to 1 km), 10Base-T1S (multidrop, approx. 10 m) and 100Base-T1 (point-to-point, 15 m). The new Beagle Play comes with a 10Base-T1L PHY. This makes it a great peer to experiment with our Linux Automation USB-T1L. In this post we will explore the possibilities of 10Base-T1L on a recent Linux system.
labgrid Tutorials
This week, we started our series of YouTube labgrid tutorials. In the next few weeks we will publish more video tutorials showing you labgrid's features and giving you handy tips and tricks.
Showcase: Embedded off-the-shelf
A firmware upgrade is due. A newly implemented feature needs to be rolled out, a security issue patched or new hardware support added. The software, while capable, is complex. Pengutronix' strategy to handle this complexity is working on a version- controlled Board Support Package (BSP) with continuous updates and tests on the latest mainline Linux kernel.
Showcase: Remote Working
Project work with our customers includes the handling of hardware prototypes. Since work is generally done in parallel, on many project for many customers, there is a constant flood of hardware prototypes accumulating on the desks of our developers. These accumulations of loose boards can become a problem. This is especially the case when a number of people work on a prototype. Another common annoyance occurs when a project has not been worked on for a period of time, as this might involve moving the hardware from one desk (or storage location) to another and setting it up again. Right now, in a situation where working from home is more common and relevant than ever, this has become even more of an issue. The distances between desks and storage locations of our developers are now measured in kilometers, rather than meters.