Uniquely Identify An Mbed?

23 Mar 2011

This might seem like pretty stupid questions. I searched but could not find any thing...

1.) Any properly complied BIN file (program) should run on any mbed correct? For example, If I wrote a program and compiled it. Then copied the bin file onto another mbed device, it should run on the other device correct? There is no key between the device and the compiled program is there?

2.) This leads to the second question... Is there anything on an mbed that makes it totaly unique from any other mbed? Like an embedded serial number or something like that? And if so, can it be exposed to your code?

Hope these questions makes sense...

Thanks in advance

Tim

23 Mar 2011

The answer to question 1 is yes, the bin file will work on any mbed and any LPC1768.

Remember that mbed.htm file you had to open so you can sign up for an account on this website? That file contains a serial key that is unique to your mbed. You can use the mbed to open and read that file. Search for "LocalFileSystem" on this site to figure out how.

23 Mar 2011
  1. Yes. Bins are portable across Mbeds (and any target using an LPC1768 with appropriate hardware).
  2. Yes. Each Mbed firmware has it's own serial number that makes it unique. The easiest way to get at this is by reading the MAC address using:-

extern "C" mbed_mac_address(char *);

int main() {
    char mac[6];
    mbed_mac_address(mac);
}

The MAC address is the number used when connecting an Mbed to an Ethernet. However, it's a 48bit/6byte unique number world wide. (note this only works for Mbeds. It will not work for LPC1768 target hardware that doesn't have the Mbed backend).

23 Mar 2011

Thank You Both. Very helpful.

Frank, just as you were writing your response I was poking around in the HTML file... Out of this string, which is the unique number? I would think it is the auth=xxx.... Corect?

auth=101000000xxxxxx&loader=11xxx&firmware=16xxx&configuration=4"

----

Andy, The same would hold true for the HTML file correct? That is not something you will find on every LPC1768 correct?

And if I hear you right. The MAC number on the MBED device is unique to that single mbed... So it can be seen as a unique device correct?

-

24 Mar 2011

The serial number found within the MBED.HTM file is actually based off the MAC address. Correct, it is unique to the Mbed platform and not unique to the LPC1768 (as it's only found within the device on the underside of your Mbed and not the target LPC1768 on the topside of your Mbed). Follow the previous link to learn more about the MAC address and what makes it unique.

If you are designing your own hardware with an LPC1768 as the target then you will need an alternate method to aquire a unique identifier.

  1. Program each target with a unique number during production. Pros: no hardware costs and you control the number sequence, Cons: needs each device to have a unique bin file for each production unit you make which can be done with a post processing step but still means programming your production unit requires more steps.
  2. Use a device that gives you an unique number such as an 25AA02E48. Pros: makes all bin files identical making production units easier to produce, ensures the number is globally unique, Cons: more hardware, increases unit cost.
24 Mar 2011

Thanks Andy;

BTW: I'm having trouble getting that code snip to work... I'm trying to return that value as a string from a function. I got it to compile but I get nothing back. Not sure what I'm doing wrong...

Here's what I did...

extern "C" void mbed_mac_address(char *);

string mbedUID(){

string sReturn;

char mac[6]; mbed_mac_address(mac);

for(int i = 0; i <= 6; i++){sReturn += mac[i];};

return sReturn;

}

24 Mar 2011

It's not a string, it's a binary number.

psuedo code

extern "C" mbed_mac_address(char *);

int main() {
    uint64_t uid = 0;
    char mac[6];
    mbed_mac_address(mac);
    uid = mac[0] << 40 | mac[1] << 32 |
          mac[2] << 24 | mac[3] << 16 |
          mac[4] << 8  | mac[5] << 0;    
}
24 Mar 2011

Hi

FYI: MAC addresses NOT neccesarily unique (anymore). They where unique in the old days but those have been gone. And just like IP adresses space the MAC space is limited too.

Mosts operating systems have api's to change it (or MAC spoofing would not be possible). MAC adresses are used for MAC based filtering and identifying a device in a local network to be able to assign it an ip adress with DHCP. There is as far as i know no need for a world-wide uniqueness. But chances are minimal that you have a dupe in the same (local) network.

If mBed cpu's are indeed programmed with a non changable and unique MAC address this would greatly help in identifying devices.

24 Mar 2011

OK, so we can pick holes at MAC address uniqueness. But if you are looking for a unique Mbed number the MAC address is fine. Simon bought a huge official ARM block for Mbeds. So at the Mbed level at least it's going to be unique.

As for the 25AA02E48 Microchip program these with their initial 3byte unique manufacturer code. Thus these are unique also.

If people want to go breaking standards by manipulating an i/f MAC address manually to one that is "officially owned" by a manufacturer then they should expect their stuff to break.

24 Mar 2011

Hi

Thanks for the good news that Simon made sure the MAC's are unique on the Mbed. Makes life easier! I should add this code to my projects asap.

24 Mar 2011

Thanks Andy for the code feedback. I'm a real newbie so this helps a bunch. I've learned alot but things like this show me how much more I need to learn.

BTW: The reason why I'm trying to get this into a string is because I want to be able to transmit it via serial to my PC. Let me see if I can get this new code to do the trick...

Thanks again.

24 Mar 2011

Got it to work. Good enough for my needs anyway... Thanks again.

24 Mar 2011

I am currently building my own LPC1768 board, hopefully with Ethernet capability's, using a DP83848CVV chip,

/media/uploads/ceri/_scaled_imag1369.jpg

Although I have not really used the Ethernet capabilities of the MBED, it would be nice, to add to my board.

I am wondering, if this MAC address is going to stop MY Ethernet from working, if it doses, then is there a solution ?

I am by the way assuming the 'magic' chip has nothing to do with the Ethernet, and a program made using MBED Compiler will work, even if I have to manually set a few parameters (anyone know how)

Confused

Ceri.

24 Mar 2011

ceri

No. On your target hardware you have no "Mbed backend". The MAC address is stored in this location (the chips on the bottom side of your Mbed). So when you go to your own target hardware that MAC address provided by mbed_mac_address() function will not be available to you. You will need to source you own MAC address.

Please see discussion above about the EEPROM device from Microchip that holds a MAC address you can use and about overriding Mbed's mbed_mac_address() function to use your own.

24 Mar 2011

You can use a "Locally Administered" MAC address of your own creation. This is allowed by the standard.

Locally administered MAC addresses are distinguished from Universally administered MAC addresses by setting the second least significant bit of the most significant byte of the MAC address. If the bit is 1 the address is locally administered, if it is zero, it is universally administered. A Universally administered address should not be used, unless it has been assigned to you or a device you're using.

/media/uploads/Harry/475px-mac-48_address.svg-1-.png

Note, that assigned Organizationally Unique Identifiers (OUIs) do not apply to locally administered addresses. The only other bit you have to be concerned with is the least significant bit of the most significant byte, the unicast/multicast bit.

If you need a unique number to distinguish your LPC1768 processor (whether it be on an mbed board or your own board), you can use the LPC1768 unique serial number. It uniquely identifies a single unit among all LPC17XX devices and is available in the LPC1768's flash.

Here is a sample program to retrieve and display an LPC1768's unique serial number:

/media/uploads/Harry/serialnumberprogram.png

/media/uploads/Harry/serialnumberprogram.txt

21 Apr 2011

Hi,

Where is this serialnumber documented?

21 Apr 2011

It's part of the IAP interface. See the manual, section 32.8 (page 631)

21 Apr 2011

Hi Andy,,

Thanks! That clears things.

Btw the section 32.10.2 is also interesting, is this done during cpu startup/boot or can we do this in user code?

09 May 2011

Andy K wrote:

  1. Yes. Each Mbed firmware has it's own serial number that makes it unique. The easiest way to get at this is by reading the MAC address using:-

extern "C" mbed_mac_address(char *);

int main() {
    char mac[6];
    mbed_mac_address(mac);
}

The MAC address is the number used when connecting an Mbed to an Ethernet.

I'm compiling my own binary, without the mbed library, but I do use an mbed (not just LPC1768). How do I find the mac address without the use of mbed_mac_address (since I don't have access to that function). I.e., how does the mbed_mac_address function find the mac address? Does it communicate with the mbed processor on the bottom of the mbed or is it programmed somewhere in flash maybe when the target processor is programmed?

09 May 2011

Hi Rob,

You can read the full UID of the mbed (from which the MAC is extracted) using a semihost call to the mbed interface. Here is the outline code:

#define USR_UID 0x101

int semihost_uid(char *uid) {
	uint32_t args[2];
	args[0] = (uint32_t)uid;
	args[1] = 33;
	return __semihost(USR_UID, &args);
}

Hope that gives you what you need!

Simon

09 May 2011

Hi Simon

Does your semihost call return the same value as Harry Wahl's code?

Wim

09 May 2011

According to the LPC17xx User Manual, all LPC17xx devices contain a unique serial number. This can be accessed via user software using routines in the on-chip boot loader. Refer to Chapter 32, section 8.7 for details.

Quote:

Table 595. IAP Read device serial number command
Command Read device serial number
Input Command code: 5810
Parameters: None
Return Code CMD_SUCCESS
Result
Result0: First 32-bit word of Device Identification Number (at the lowest address)
Result1: Second 32-bit word of Device Identification Number
Result2: Third 32-bit word of Device Identification Number
Result3: Fourth 32-bit word of Device Identification Number
Description This command is used to read the device identification number. The serial number may be used to uniquely identify a single unit among all LPC17xx devices.

The LPC17xx User Manual is on the NXP web site as document UM10360.

10 May 2011

Hi Simon,

In your code, what values should we pass for uid?

I also found some interesting register in the arm manuals (and it compiles but as I do not have my mbed at hand I cannot test it yet).

register uint32_t cpuid __asm("cpuid");

printf("CPUID=%0.8X\r\n", cpuid);

See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337i/Cihhbddh.html

It should return the part number and revision of the CPU.

Wim

09 Nov 2012

See the user manual UM10360 section 32.8 IAP commands. I pretty much copied the code example and it is at https://mbed.org/users/dminear/code/get_serial_number/

main.cpp

/*
 * How to read LPC1768 part ID and device serial number
 * Dan Minear
 * 2012-11-08
 */
 
#include "mbed.h"
 
#define IAP_LOCATION 0x1FFF1FF1
 
typedef void (*IAP)(unsigned long [], unsigned long[] );
IAP iap_entry = (IAP) IAP_LOCATION;
 
DigitalOut myled(LED1);
 
int main() {
    unsigned long command[5] = {0,0,0,0,0};
    unsigned long result[5] = {0,0,0,0,0};
 
    printf("\r\nStart...\r\n");
    
    // See User Manual section 32.8.5
    command[0] = 54;    // partID
    printf("\r\nPart ID: (should be 0x2601 3F37 for LPC1768)\r\n");
    iap_entry(command, result);
    if (result[0] == 0) {
        for(int i = 1; i < 2; i++) {
            printf( "0x%x\r\n", result[i] );
        }
    } else {
        printf("Status error!\r\n");
    }
    
    // See User Manual section 32.8.7
    command[0] = 58;  // read device serial number
    printf("\r\nSerial number:\r\n");
    iap_entry(command, result);
    if (result[0] == 0) {
        for(int i = 1; i < 5; i++) {
            printf( "0x%x\r\n", result[i] );
        }
    } else {
        printf("Status error!\r\n");
    }
        
    printf( "\r\nEnd\r\n" );
        
    // and now back to the default new project, just flash a LED
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}


This is pretty much the same as Harry Wahl's response.

Dan

09 Nov 2012

You can also retreive the mbed's Ethernet MAC address. The 3 lowest bytes ( mac[3], mac[4], mac[5] ) are unique to a specific mbed device:

extern "C" void mbed_mac_address(char *s);

uint64_t uid = 0;

char mac[6];

int main() {

Retrieve MAC Address

mbed_mac_address(mac);

uid = mac[0] << 20 << 20 | mac[1] << 16 << 16 |

mac[2] << 24 | mac[3] << 16 |

mac[4] << 8 | mac[5] << 0;

...kevin