CpuUid: complete refactoring to meet review requirements

Hopefully all review items were addressed.
pull/5557/head
Michael Kaplan 2017-12-01 13:01:51 +01:00
parent 649ce41436
commit f7ed4b9f90
7 changed files with 188 additions and 109 deletions

View File

@ -22,59 +22,50 @@
namespace mbed {
uint8_t CpuUid::_uidbuf[MBED_CPU_UID_SIZE] = {0};
uint8_t* CpuUid::_uidptr = NULL;
char CpuUid::_strbuf[CPU_UID_STRING_BUFFER_SIZE] = {'\0'};
char* CpuUid::_strptr = NULL;
#ifndef MBED_CPU_UID_STR_SIZE_MAX
const char CpuUid::_hexChars[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
CpuUid::CpuUid() : _data(NULL)
{
_size = cpu_uid_get_length();
#ifdef MBED_ASSERT
MBED_ASSERT(_size > 0);
#endif
if (0 < _size) {
_data = new uint8_t[_size];
cpu_uid_get_uid(_data);
}
CpuUid::CpuUid()
{
populate_uid_buf();
}
CpuUid::~CpuUid()
{
if (_data) {
delete _data;
}
void CpuUid::populate_uid_buf()
{
if (_uidptr == NULL) {
cpu_uid_get_uid(_uidbuf);
_uidptr = _uidbuf;
}
}
CpuUid::operator std::string()
void CpuUid::populate_str_buf()
{
std::string str;
for (int i = 0; i < _size; ++i) {
str += _hexChars[_data[i] >> 4];
str += _hexChars[_data[i] & 0x0F];
if (_strptr == NULL) {
#ifdef MBED_CPU_UID_STR_SIZE_MAX
cpu_uid_get_str(_strbuf);
_strptr = _strbuf;
#else
int pos = 0;
populate_uid_buf();
for (int i = 0; i < MBED_CPU_UID_SIZE; ++i) {
_strbuf[pos++] = _hexChars[_uidptr[i] >> 4];
_strbuf[pos++] = _hexChars[_uidptr[i] & 0x0F];
}
_strbuf[pos] = '\0';
_strptr = _strbuf;
#endif
}
return str;
}
CpuUid::operator cpu_uid_array_t()
{
cpu_uid_array_t array;
for (int i = 0; i < _size; ++i) {
array.push_back(_data[i]);
}
return array;
}
uint8_t CpuUid::operator[](int x)
{
if (x >= 0 && x < _size) {
return _data[x];
}
return 0x00;
}
} // namespace mbed
#endif

View File

@ -20,6 +20,12 @@
#if defined(DEVICE_CPUUID) || defined(DOXYGEN_ONLY)
#ifdef MBED_CPU_UID_STR_SIZE_MAX
#define CPU_UID_STRING_BUFFER_SIZE MBED_CPU_UID_STR_SIZE_MAX
#else
#define CPU_UID_STRING_BUFFER_SIZE (MBED_CPU_UID_SIZE * 2 + 1)
#endif
#include <string>
#include <vector>
@ -33,10 +39,6 @@ namespace mbed {
*/
class CpuUid {
public:
/** CPU UID array typedef
*/
typedef std::vector<uint8_t> cpu_uid_array_t;
/** CpuUid constructor
*/
CpuUid();
@ -51,7 +53,7 @@ public:
*/
int size()
{
return _size;
return MBED_CPU_UID_SIZE;
}
/** Get CPU UID data pointer
@ -60,20 +62,26 @@ public:
*/
const uint8_t *data()
{
return _data;
populate_uid_buf();
return _uidptr;
}
/** Overload operator for std::string
/** Get CPU UID vendor string
*
* @return string object containing the CPU UID in uppercase hex letters in ascii format
*/
operator std::string();
/** Overload operator for cpu_uid_array_t
* @return Pointer to zero terminated uid vendor string
*
* @note
* If vendor did not define MBED_CPU_UID_STR_SIZE_MAX, CpuUid driver will
* assume the HAL interface function cpu_uid_get_str() is not implemented
* on the target, and instead the driver will construct just an ASCII
* string out of the uid byte buffer contents.
*
* @return cpu_uid_array_t object containing the CPU UID
*/
operator cpu_uid_array_t();
const char *c_str()
{
populate_str_buf();
return _strptr;
}
/** Overload operator for byte pointer
*
@ -81,7 +89,14 @@ public:
*/
operator const uint8_t*()
{
return _data;
populate_uid_buf();
return _uidptr;
}
operator const char*()
{
populate_str_buf();
return _strptr;
}
/** Overload operator for array subscript
@ -90,13 +105,27 @@ public:
*
* @return Byte located at index x
*/
uint8_t operator[](int x);
uint8_t operator[](int x)
{
if (x >= 0 && x < MBED_CPU_UID_SIZE) {
populate_uid_buf();
return _uidptr[x];
}
return 0x00;
}
private:
uint8_t *_data;
int _size;
void populate_uid_buf();
void populate_str_buf();
static uint8_t _uidbuf[MBED_CPU_UID_SIZE];
static uint8_t* _uidptr;
static char _strbuf[CPU_UID_STRING_BUFFER_SIZE];
static char* _strptr;
#ifndef MBED_CPU_UID_STR_SIZE_MAX
static const char _hexChars[16];
#endif
};
} // namespace mbed

View File

@ -23,6 +23,14 @@
#if DEVICE_CPUUID
#ifndef MBED_CPU_UID_SIZE
#error "CPU UID Vendor implementation must define macro MBED_CPU_UID_SIZE with the uid size in bytes!"
#endif
#ifndef MBED_CPU_UID_STR_SIZE_MAX
#warning "CPU UID max vendor string length not defined! cpu_uid_get_str() HAL interface is disabled!"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -32,25 +40,26 @@ extern "C" {
* @{
*/
/** Get length of CPU UID in bytes
*
* @return Number of uid bytes
*
* @note
* Shall be used by the driver to get the needed size of the byte buffer.
* Target implementation must return a value higher than 0 or the driver will assert.
*
*/
int cpu_uid_get_length(void);
/** Get CPU UID data bytes
*
* @param uid Byte buffer for uid. Must at least be of size obtained by call to cpu_uid_get_length()
* @param uid Byte buffer for uid. Must be of size MBED_CPU_UID_SIZE
*
*/
void cpu_uid_get_uid(uint8_t *uid);
#ifdef MBED_CPU_UID_STR_SIZE_MAX
/** Get UID vendor string
*
* @param str Character buffer for vendor specific UID string. Must be of size MBED_CPU_UID_STR_SIZE_MAX
*
* @note
* Implementing this function on target side can be used to provide a vendor specific
* string describing the contents of the UID.
* The string length including terminating zero character must not exceed MBED_CPU_UID_STR_SIZE_MAX bytes!
*
*/
void cpu_uid_get_str(char *str);
#endif
/**@}*/

View File

@ -43,24 +43,15 @@
#include "nrf.h"
#include "cpu_uid_api.h"
#define UID_LENGTH 8
#define UID_WORDS 2
int cpu_uid_get_length(void)
{
return UID_LENGTH;
}
void cpu_uid_get_uid(uint8_t *uid)
{
int pos = 0;
for (int i = (UID_WORDS-1); i >= 0; --i)
{
for (int j = 3; j >= 0; --j)
{
uid[pos] = (uint8_t)((NRF_FICR->DEVICEID[i] >> (j*8)) & 0xFF);
++pos;
for (int i = (UID_WORDS-1); i >= 0; --i) {
for (int j = 3; j >= 0; --j) {
uid[pos++] = (uint8_t)((NRF_FICR->DEVICEID[i] >> (j*8)) & 0xFF);
}
}
}

View File

@ -31,6 +31,7 @@
#if DEVICE_CPUUID
#include <string.h>
#if defined(TARGET_STM32F0)
#include "stm32f0xx_ll_utils.h"
#elif defined(TARGET_STM32F1)
@ -54,14 +55,11 @@
#endif
#include "cpu_uid_api.h"
#define UID_LENGTH 12
#define UID_WORDS 3
int cpu_uid_get_length(void)
{
return UID_LENGTH;
}
#ifdef MBED_CPU_UID_STR_SIZE_MAX
static int cpu_uid_itoa(int value, char *sp, int radix);
#endif
void cpu_uid_get_uid(uint8_t *uid)
{
@ -72,14 +70,82 @@ void cpu_uid_get_uid(uint8_t *uid)
uid_buf[1] = LL_GetUID_Word1();
uid_buf[2] = LL_GetUID_Word2();
for (int i = (UID_WORDS-1); i >= 0; --i)
{
for (int j = 3; j >= 0; --j)
{
uid[pos] = (uint8_t)((uid_buf[i] >> (j*8)) & 0xFF);
++pos;
for (int i = (UID_WORDS-1); i >= 0; --i) {
for (int j = 3; j >= 0; --j) {
uid[pos++] = (uint8_t)((uid_buf[i] >> (j*8)) & 0xFF);
}
}
}
#ifdef MBED_CPU_UID_STR_SIZE_MAX
void cpu_uid_get_str(char *str)
{
char buffer[16];
char lot_number[8];
uint8_t wafer_number;
uint16_t x, y;
uint32_t uid_buf[UID_WORDS];
uid_buf[0] = LL_GetUID_Word0();
uid_buf[1] = LL_GetUID_Word1();
uid_buf[2] = LL_GetUID_Word2();
lot_number[0] = (uid_buf[2] >> 24) & 0x000000FF;
lot_number[1] = (uid_buf[2] >> 16) & 0x000000FF;
lot_number[2] = (uid_buf[2] >> 8) & 0x000000FF;
lot_number[3] = uid_buf[2] & 0x000000FF;
lot_number[4] = (uid_buf[1] >> 24) & 0x000000FF;
lot_number[5] = (uid_buf[1] >> 16) & 0x000000FF;
lot_number[6] = (uid_buf[1] >> 8) & 0x000000FF;
lot_number[7] = '\0';
wafer_number = uid_buf[1] & 0x000000FF;
x = (uid_buf[0] >> 16) & 0x0000FFFF;
y = uid_buf[0] & 0x0000FFFF;
// make a string in format "Lot xxxxxxx Wafer xxx X=xxxxx Y=xxxxx" - max 38 chars including terminating zero
strcpy(str, "Lot ");
strcat(str, lot_number);
strcat(str, " Wafer ");
cpu_uid_itoa(wafer_number, buffer, 10);
strcat(str, buffer);
strcat(str, " X=");
cpu_uid_itoa(x, buffer, 10);
strcat(str, buffer);
strcat(str, " Y=");
cpu_uid_itoa(y, buffer, 10);
strcat(str, buffer);
}
int cpu_uid_itoa(int value, char *sp, int radix)
{
char tmp[16];// be careful with the length of the buffer
char *tp = tmp;
int i;
unsigned v = value;
while (v || tp == tmp) {
i = v % radix;
v /= radix; // v/=radix uses less CPU clocks than v=v/radix does
if (i < 10) {
*tp++ = i+'0';
}
else {
*tp++ = i + 'a' - 10;
}
}
int len = tp - tmp;
while (tp > tmp) {
*sp++ = *--tp;
}
*sp = '\0';
return len;
}
#endif
#endif

View File

@ -28,22 +28,14 @@
#include "em_system.h"
#include "cpu_uid_api.h"
#define UID_LENGTH 8
int cpu_uid_get_length(void)
{
return UID_LENGTH;
}
void cpu_uid_get_uid(uint8_t *uid)
{
int pos = 0;
uint64_t tempuid = SYSTEM_GetUnique();
for (int i = (UID_LENGTH-1); i >= 0; --i)
{
uid[pos] = (uint8_t)((tempuid >> (i*8)) & 0xFF);
++pos;
for (int i = (MBED_CPU_UID_SIZE - 1); i >= 0; --i) {
uid[pos++] = (uint8_t)((tempuid >> (i*8)) & 0xFF);
}
}

View File

@ -705,7 +705,7 @@
"public": false,
"extra_labels": ["STM"],
"supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"],
"macros": ["TRANSACTION_QUEUE_SIZE_SPI=2", "MBED_CPU_UID_SIZE=12", "MBED_CPU_UID_STR_SIZE_MAX=38"],
"config": {
"lse_available": {
"help": "Define if a Low Speed External xtal (LSE) is available on the board (0 = No, 1 = Yes). If Yes, the LSE will be used to clock the RTC, LPUART, ... otherwise the Low Speed Internal clock (LSI) will be used",
@ -2590,7 +2590,7 @@
"EFM32": {
"inherits": ["Target"],
"extra_labels": ["Silicon_Labs", "EFM32"],
"macros": ["MBEDTLS_CONFIG_HW_SUPPORT"],
"macros": ["MBEDTLS_CONFIG_HW_SUPPORT", "MBED_CPU_UID_SIZE=8"],
"public": false
},
"EFM32GG990F1024": {
@ -3212,7 +3212,8 @@
"CMSIS_VECTAB_VIRTUAL",
"CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"",
"NO_SYSTICK",
"MBED_TICKLESS"
"MBED_TICKLESS",
"MBED_CPU_UID_SIZE=8"
],
"MERGE_BOOTLOADER": false,
"extra_labels": ["NORDIC", "MCU_NRF51", "MCU_NRF51822_UNIFIED", "NRF5", "SDK11"],
@ -3270,7 +3271,7 @@
"MCU_NRF52": {
"inherits": ["Target"],
"core": "Cortex-M4F",
"macros": ["NRF52", "TARGET_NRF52832", "BLE_STACK_SUPPORT_REQD", "SOFTDEVICE_PRESENT", "S132", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"", "MBED_TICKLESS"],
"macros": ["NRF52", "TARGET_NRF52832", "BLE_STACK_SUPPORT_REQD", "SOFTDEVICE_PRESENT", "S132", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"", "MBED_TICKLESS", "MBED_CPU_UID_SIZE=8"],
"device_has": ["STCLK_OFF_DURING_SLEEP", "CPUUID"],
"extra_labels": ["NORDIC", "MCU_NRF52", "MCU_NRF52832", "NRF5", "SDK11", "NRF52_COMMON"],
"OUTPUT_EXT": "hex",