1 /* 2 * Copyright (c) 2021 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _PICO_UNIQUE_ID_H 8 #define _PICO_UNIQUE_ID_H 9 10 #include "pico.h" 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /** \file pico/unique_id.h 17 * \defgroup pico_unique_id pico_unique_id 18 * 19 * \brief Unique device ID access API 20 * 21 * \if rp2040_specific 22 * RP2040 does not have an on-board unique identifier (all instances of RP2040 23 * silicon are identical and have no persistent state). However, RP2040 boots 24 * from serial NOR flash devices which have at least a 64-bit unique ID as a standard 25 * feature, and there is a 1:1 association between RP2040 and flash, so this 26 * is suitable for use as a unique identifier for an RP2040-based board. 27 * 28 * This library injects a call to the flash_get_unique_id function from the 29 * hardware_flash library, to run before main, and stores the result in a 30 * static location which can safely be accessed at any time via 31 * pico_get_unique_id(). 32 * 33 * This avoids some pitfalls of the hardware_flash API, which requires any 34 * flash-resident interrupt routines to be disabled when called into. 35 * \endif 36 * 37 * \if rp2350_specific 38 * On boards using RP2350, the unique identifier is read from OTP memory on boot. 39 * \endif 40 */ 41 42 #define PICO_UNIQUE_BOARD_ID_SIZE_BYTES 8 43 44 /** 45 * \brief Unique board identifier 46 * \ingroup pico_unique_id 47 * 48 * This structure contains an array of PICO_UNIQUE_BOARD_ID_SIZE_BYTES identifier bytes suitable for 49 * holding the unique identifier for the device. 50 * 51 * \if rp2040_specific 52 * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot, 53 * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE. 54 * \endif 55 * 56 * \if rp2350_specific 57 * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot. 58 * \endif 59 * 60 */ 61 typedef struct { 62 uint8_t id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES]; 63 } pico_unique_board_id_t; 64 65 /*! \brief Get unique ID 66 * \ingroup pico_unique_id 67 * 68 * Get the unique 64-bit device identifier. 69 * 70 * \if rp2040_specific 71 * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot, 72 * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE. 73 * \endif 74 * 75 * \if rp2350_specific 76 * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot. 77 * \endif 78 * 79 * \param id_out a pointer to a pico_unique_board_id_t struct, to which the identifier will be written 80 */ 81 void pico_get_unique_board_id(pico_unique_board_id_t *id_out); 82 83 /*! \brief Get unique ID in string format 84 * \ingroup pico_unique_id 85 * 86 * Get the unique 64-bit device identifier formatted as a 0-terminated ASCII hex string. 87 * 88 * \if rp2040_specific 89 * On an RP2040-based board, the unique identifier is retrieved from the external NOR flash device at boot, 90 * or for PICO_NO_FLASH builds the unique identifier is set to all 0xEE. 91 * \endif 92 * 93 * \if rp2350_specific 94 * On an RP2350-based board, the unique identifier is retrieved from OTP memory at boot. 95 * \endif 96 * 97 * \param id_out a pointer to a char buffer of size len, to which the identifier will be written 98 * \param len the size of id_out. For full serial, len >= 2 * PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1 99 */ 100 void pico_get_unique_board_id_string(char *id_out, uint len); 101 102 103 #ifdef __cplusplus 104 } 105 #endif 106 107 #endif 108