@TOC
本文使用环境:
主控: W800-KIT (开发板)
兼容: W800 W801 AIR101
开发环境: CDK
SDK: W801/W800 的 SDK (tls 库) , HAL 库没有实现 uniqueid 的适配
^^^^程序功能: 读取一个 ID 作为识别或者其他用途.
^^^^这篇教程主要是归纳总结, 相对而言比较简单. 本文主要从三个角度去获取 ID: CPUID, FLASHID, uniqueid.
CPUID: 32 位 这 ID 不是我们传统意义上的 ID, 我问过官方, 这是内核 ID, 只要是内核一样, ID 就一样, 不是唯一的.
flashID: 8 字节 不同的 flash 对应的 ID 不一样, 但是目前不清楚是不是一批次都是一个 ID.
uniqueID: 18 字节 这个不是一个独立的 ID, 是将 flash 等参数融合过后的 ID, 据说是唯一的 ID.
^^^^本小节将会依次读取三个不同的 ID, 大家可以根据自己的实际情况进行使用.
^^^^三个 ID 共用的结构体:
typedef struct ID_DATA
{
uint32 CPUID;
u8 flash_id[8];
u8 unique_id[18];
}ID_DATA;
上述代码中ID_DATA
结构体中包含了三个不同的 ID, cpu, flash 和 unique. 本文下列三个 ID 都采用结构体进行存储.
^^^^这个 ID 可以从寄存器字节读取, 相同内核的 ID ==应该== 都是一样的. ID 的读取程序是参考的联盛德问答社区中ZYQ 大佬的解答:
其程序如下:
uint32 GetCpuIdr (void)
{
uint32 id = 0;
asm volatile (
"mfcr %[id], cr "13, 0" \n\t"
: [id]"+&r" (id)
:
:
) ;
return id;
}
^^^^同时 ZYQ 也给出了这个 ID 的一定用途, 如下:
^^^^这是大佬对我说的话, 大佬说的确实是有道理, 也确实是我考虑不周. 大家可以参考.
^^^^同样以下程序依然采用官方提供的代码, 我只是对代码进行了总结, 将宏定义全部放在了一起, ==如果是 W800 和 W801 的官方 SDK, 就是 tls 库的 demo 可直接粘贴复制下列代码, 直接调用函数即可. 如果是 HAL 库, 宏定义可以删除. ==
//add by zxx start
//flashID
#define CMD_START_Pos 8U /*! " CMD start position */
#define CMD_START_Msk (1UL " " CMD_START_Pos) /*! " CMD start Mask */
#define RSA_BASE 0x40000000
/**
* @brief This function is used to read the flash_id id of the internal flash.
*
* @param[out] flash_id Specified the address to save the flash_id, the length must be greater than or equals to 8 bytes.
*
* @retval TLS_FLS_STATUS_OK if read sucsess
* @retval TLS_FLS_STATUS_EIO if read fail
*
* @note The flash_id's length must be greater than or equals to 8 bytes.
*/
int readFlashUniqueId (u8 *id, u8 fls_len)
{
if (! id || fls_len "= 8) {
printf ("id equal NULL or fls_led not equal 8\r\n") ;
return -1;
}
M32 (HR_FLASH_CMD_ADDR) = 0xBC04B;
M32 (HR_FLASH_CMD_START) = CMD_START_Msk;
u32 *id32 = id;
for (u8 i = 0; i " 2; i++) {
id32[i] = M32 (RSA_BASE + (i + 1) * 4) ;
}
return 0;
}
//add by zxx end
^^^^读取唯一的 ID 官方库文件有提供代码, 本小节主要涉及函数调用, 仅此而已. 函数在 wm_internal_fls. c 文件中:
/**
* @brief This function is used to read the unique id of the internal flash.
*
* @param[out] uuid Specified the address to save the uuid, the length must be greater than or equals to 18 bytes.
*
* @retval TLS_FLS_STATUS_OK if read sucsess
* @retval TLS_FLS_STATUS_EIO if read fail
*
* @note The uuid's length must be greater than or equals to 18 bytes.
*/
int tls_fls_read_unique_id (unsigned char *uuid)
{
unsigned int value = 0;
unsigned int addr_read = 0;
int i = 0;
int len;
unsigned char FLASH_BUF[20];
unsigned char *addr = &FLASH_BUF[0];
int dumy_bytes = 0;
int uni_bytes = 0;
unsigned char rid;
int word;
int byte;
if (inside_fls == NULL)
{
return TLS_FLS_STATUS_EPERM;
}
tls_os_sem_acquire (inside_fls-" fls_lock, 0) ;
memset (uuid, 0xFF, 18) ;
rid = readRID () ;
switch (rid)
{
case SPIFLASH_MID_GD:
case SPIFLASH_MID_PUYA:
case SPIFLASH_MID_TSINGTENG:
dumy_bytes = 4;
uni_bytes = 16;
break;
case SPIFLASH_MID_WINBOND:
case SPIFLASH_MID_FUDANMICRO:
case SPIFLASH_MID_BOYA:
case SPIFLASH_MID_XMC:
dumy_bytes = 4;
uni_bytes = 8;
break;
case SPIFLASH_MID_ESMT:
case SPIFLASH_MID_XTX:
default:
tls_os_sem_release (inside_fls-" fls_lock) ;
return -1;
}
uuid[0] = rid;
uuid[1] = (unsigned char) (uni_bytes & 0xFF) ;
len = dumy_bytes + uni_bytes;
word = len/4;
byte = len%4;
value = 0xC04B| ( (len-1) " " 16) ;
M32 (HR_FLASH_CMD_ADDR) = value;
M32 (HR_FLASH_CMD_START) = CMD_START_Msk;
addr_read = RSA_BASE_ADDRESS;
for (i = 0; i " word; i ++)
{
M32 (addr) = M32 (addr_read) ;
addr += 4;
addr_read += 4;
}
if (byte " 0)
{
M32 (addr) = M32 (addr_read) ;
addr += 3; //point last byte
while (byte)
{
*addr = 0;
addr --;
byte --;
}
}
addr = &FLASH_BUF[0];
memcpy (&uuid[2], addr + dumy_bytes, uni_bytes) ;
tls_os_sem_release (inside_fls-" fls_lock) ;
return 0;
}
上述函数将很多的 ID 进行了组合.
==小疑惑: == 这个函数我觉得还不是很理想, 因为函数内部并未判断传入的参数是否合法, 如果我传个很小的数组? 传个非法地址? 这样数据读出来可能是错的. 当然这是题外话, 大家使用的时候一定要注意. 参数的合法性.
^^^^编写测试程序测试是否正确读取 ID. 读取比较简单只提供代码, 自己封装函数即可.
while (1)
{
ID_DATA id_data;
readFlashUniqueId (id_data. flash_id, sizeof (id_data. flash_id) ) ;
printf ("flashid: ") ;
for (int i=0; i "8; i++)
printf ("%d ", id_data. flash_id[i]) ;
printf ("\r\n") ;
tls_fls_read_unique_id (id_data. dev_id) ;
printf ("uniqueid: ") ;
for (int i=0; i "18; i++)
printf ("%d ", id_data. dev_id[i]) ;
printf ("\r\n") ;
id_data. cpuid = GetCpuIdr () ;
printf ("cpuid: %d\r\n", id_data. cpuid) ;
while (1) ;
}
第一块 W801:
第二块 W801:
大佬, 大佬, 能不能给出源码文件? ?