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
Weiterführende Links
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.
Der USB-SD-Mux ist nun FAST
Seit 2019 vertreiben wir mit unserer Partner-Firma Linux Automation GmbH den USB-SD-Mux. Damit konnten wir vielen Embedded Entwickler*innen die Arbeit erleichtern und dadurch die Softwarequalität verbessern. Zugleich schreitet die Technik voran: Micro-SD-Karten werden schneller und mittlerweile hat sich USB-C als Standard etabliert.
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
Ein Firmware-Upgrade ist fällig. Eine neu implementierte Funktion muss ausgerollt, eine Sicherheitslücke gepatcht oder neue Hardware-Unterstützung hinzugefügt werden. Die Software ist zwar leistungsfähig, aber komplex. Pengutronix' Strategie, mit dieser Komplexität umzugehen, ist die Arbeit an einem versionskontrollierten Board Support Package (BSP) mit kontinuierlichen Updates und Tests auf dem neuesten Mainline-Linux-Kernel.
Showcase: Remote Working
Zur Projektarbeit mit unseren Kunden gehört die Arbeit mit Prototypen-Hardware. Da wir grundsätzlich parallel für mehrere Kunden an vielen verschieden Projekten arbeiten, bedeutet das eine Flut von Prototypen auf den Schreibtischen unserer Entwickler. Spätestens wenn im Team an einem Prototypen gearbeitet werden soll oder längere Zeit nicht aktiv an einem Projekt gearbeitet wird, muss die Hardware regelmäßig umgezogen und am neuen Arbeitsplatz verkabelt werden. Erschwerend kommt hinzu, dass die Entfernung zwischen unseren Entwickler-Schreibtischen durch die aktuelle Homeoffice-Situation, nicht wie gewohnt in Metern, sondern in Kilometern gemessen wird.