W801/W800/W806唯一ID/CPUID/FLASHID

10 篇文章 0 订阅
7 篇文章 0 订阅

本文使用环境:
主控: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都采用结构体进行存储。

2.1、CPUID

^^^^这个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的一定用途,如下:
在这里插入图片描述
^^^^这是大佬对我说的话,大佬说的确实是有道理,也确实是我考虑不周。大家可以参考。

2.2、flashID

^^^^同样以下程序依然采用官方提供的代码,我只是对代码进行了总结,将宏定义全部放在了一起,如果是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

2.3、uniqueID

^^^^读取唯一的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进行了组合。
小疑惑: 这个函数我觉得还不是很理想,因为函数内部并未判断传入的参数是否合法,如果我传个很小的数组?传个非法地址?这样数据读出来可能是错的。当然这是题外话,大家使用的时候一定要注意。参数的合法性。

三、测试

3.1、测试代码

^^^^编写测试程序测试是否正确读取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);
	}

3.2、W800测试结果

在这里插入图片描述

3.3、W801测试结果

第一块W801:
在这里插入图片描述
第二块W801:
在这里插入图片描述

3.4、AIR101测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr·赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值