For my RNet stack I need a way to identify nodes in the network using a unique address. What I need is Media-Access (MAC) address. Base on such a unique address I can assign short addresses (e.g. with a DHCP or similar protocol to automatically assign shorter network addresses). So how to uniquely identify my network nodes?
The Freescale Kinetis microcontroller have nice feature: they have a Unique Identification Register (UID) which would be a perfect fit for a MAC address :-).
Unique Identification Register
In the Freescale factory, every device gets a unique ID assigned during the production process. Freescale uses 16+32+32=80bits. Below is the address map for the KL25Z:
Although this are 3 times a 32bits, the higher bits of SIM_UIDMH always are zero bits (so I have 80 bits):
Unique ID for all Kinetis Devices
The first question which came to my mind was if that ID is unique only within the microcontroller family (e.g. KL25Z). According to a response in the Freescale forum this ID is even unique across the Kinetis family!
Format of UID?
I was wondering how the UID is formatted. There must be a logical pattern which reflects the fabrication process. At least for Freescale i.MX the UID contains die X/Y cooardinates, waver number and lot ID. I was not able to find a similar information for Kinetis UID.
Using an UID
My first thought was to use the UID to identify devices in my network. But there are other usages too:
- That unique ID can be used to restrict even software to run on a device (or to run with a device). See the P&E/Freescale OpenSDA implementation which only works if the ID of the target device matches the check in the OpenSDA firmware (see “Using the FRDM-KL25Z with CMSIS-DAP to program non-Freescale ARM Microcontrollers“).
- As the ID is unique for each device, it can be use as input of an encryption algorithm or as a seed (different for each microcontroller).
Reading the UID
With Processor Expert, the UID registers are declared inside IO_Map.h:
Using these defines, I can easily get the UID and for example dump it in a terminal window:
UTIL1_strcpy(buf, sizeof(buf), (unsigned char*)"0x"); UTIL1_strcatNum16Hex(buf, sizeof(buf), SIM_UIDMH); UTIL1_strcatNum32Hex(buf, sizeof(buf), SIM_UIDML); UTIL1_strcatNum32Hex(buf, sizeof(buf), SIM_UIDL); UTIL1_strcat(buf, sizeof(buf), (unsigned char*)"\r\n"); CLS1_SendStatusStr((unsigned char*)" UID", buf, io->stdOut);
💡 I’m using the Utility (UTIL1) and Command Line Shell (CLS1) Processor Expert components.
Then this gives for one of my FRDM-KL25Z boards:UID : 0x0045000F900924824E45
Another KL25Z reports this:UID : 0x0040000D900324824E45
So the ID’s are somewhat similar, but still different. As such, I think I always need to use all bits, and not just a few bytes.
Freescale Kinetis devices have a unique identification number (UID) which is unique across all Kinetis devices. That UID can be used for different purposes
- Networking: Identifying devices in a network
- Quality assurance: possible to track devices on board
- Hardware/Software protection: checking the ID and only allow operation if the ID is matching.
- Using the ID for cryptographic inputs.
Reading the UID only requires to read 3 32bit registers. And until there is no information how the UID is constructed, I recommend to read and use all bits.
Happy Identifying 🙂