加密芯片ATSHA204读序列号(Serial Number)

        近段时间一个项目使用了atsha204,硬件电路设计好后,需要设计一个程序来测试芯片是否正常工作,于是写了一个读Serial Number的程序。

        本文参考了博文 《atsha204a加密芯片使用攻略——配置篇》,该博文比较详细地说明了芯片该如何使用,更详细的芯片使用可以参考该文,这里不赘述了。

        但是我也发现文章中的一些问题,以下内容都是我测试过可行的。

 

一、目标

        我设定的测试目标是读取芯片的Serial Number。Serial Number在Config区域中。


二、数据包的格式
1、芯片通讯包基本格式

Word Address

Count

Data

CRC

1 byte

1 byte

N byte

2 byte

 

2、查找datasheet中Read Command的具体样式


可以具体看到Read Command的数据包具体样式如下所示。其中Count的长度不包括Word Address,但包括Count本身

Word Address
 Count
 Opcode
 Param1
 Param2
CRC
1 byte
1 byte
1 byte
1 byte
1 byte
2 byte


3、填充其它内容

      接下来分别填充Qpcode、Param1和Param2的内容

3.1 Qpcode值

        Read指令,所以Qpcode = 0x02


3.2  Param1值

        Param1表示的是访问的区域,有三个区域Config、OTP和Data,分别对应的值为:0、1、2、

 

3.3  Param2值

        Param2中的Block指明操作哪个block和要offset多少个地址。这里是要读取 word 0 的值,所以Block和offset都是0


所以Read Command数据包的样式如下:

Word Address

Count

Opcode
Param1
Param2(byte0)

Param2(byte1)

   CRC
0x03
0x07
0x02
0x00
0x00
0x00
2 byte

 

4、计算CRC的值
使用Atmel官方提供的库中的sha204c_calculate_crc()函数算出后面的CRC的值,
库下载地址:http://www.atmel.com/tools/CRYPTOAUTHENTICATIONATSHA204DEVELOPMENTLIBRARY.aspx
sha204c_calculate_crc函数在sha204_comm.c中


void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) ;
第一个参数:Count ~ Param2(byte1)的个数,总共5个
第二个参数:需要计算的数据起始地址,即Count的地址
第三个参数:写入crc数据的起始地址(算出来的值为:0x1e, 0x2d)

最终Read Command数据包格式如下:

Word Address

Count

Opcode
Param1
Param2(byte0)

Param2(byte1)

CRC1

CRC2

0x03
0x07
0x02
0x00
0x00
0x00
0x1e
0x2d

三、程序设计
        芯片在读写之前,需要进行唤醒。Datasheet中的描述如下:


我写的程序思路如下:
1、设备需要Wake up才能读写数据。
2、查看slave是否有响应,此时读出4个字节,值分别为:0x04 0x11 0x33 0x43
3、发送Read Command
4、读出数据

四、实验结果



五、程序

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
 
#define SHA204_WRITE   0x01
#define SHA204_READ    0x03
 
struct my_i2c_msg {
    unsigned short addr;  /* slave address          */
    unsigned short flags;
    unsigned short len;       /* msg length             */
    unsigned char buf[64];        /* pointer to msg data          */
};
 
static void sha204c_calculate_crc( unsigned char  length, unsigned char  *data, unsigned char  *crc)
{
    unsigned char counter;
    unsigned short crc_register = 0;
    unsigned short polynom = 0x8005;
    unsigned char  shift_register;
    unsigned char  data_bit, crc_bit;
 
    for (counter = 0; counter < length; counter++) {
        for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) {
            data_bit = (data[counter] & shift_register) ? 1 : 0;
            crc_bit = crc_register >> 15;
            crc_register <<= 1;
            if (data_bit != crc_bit)
                crc_register ^= polynom;
        }
    }
    crc[0] = (unsigned char)(crc_register & 0x00FF);
    crc[1] = (unsigned char)(crc_register >> 8);
}
 
struct my_i2c_msg packet;
int main()
{
    int fd;

    fd = open("/dev/sha204", O_RDWR);
    if(fd < 0){
        printf("sha204 open failed!");
    }
 
    //1.wake up
    packet.addr = 0x00;
    packet.len = 1;
    packet.buf[0] = 0;
    ioctl(fd, SHA204_WRITE, &packet);
    usleep(2600);
     
    //2.read feedback bytes (4 bytes)
    packet.addr = 0xc8;
    packet.len = 4;
    ioctl(fd, SHA204_READ, &packet);
    printf("Feedback bytes: %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3]);
     
    //3.send read command
    packet.addr = 0xc8;
    packet.len = 8;
    packet.buf[0] = 0x03; //0x03, 0x07, 0x02, 0x00, 0x00, 0x00
    packet.buf[1] = 0x07;
    packet.buf[2] = 0x02;
    packet.buf[3] = 0x00;
    packet.buf[4] = 0x00;
    packet.buf[5] = 0x00;
    sha204c_calculate_crc(5 ,&packet.buf[1],&packet.buf[6]);
    printf("Read command: %x %x %x %x %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3],\
                                                    packet.buf[4],packet.buf[5],packet.buf[6],packet.buf[7]);\                               
    ioctl(fd, SHA204_WRITE, &packet);
    usleep(3000);
     
    //4.read data
    packet.addr = 0xc8;
    packet.len = 7;
    memset(packet.buf, 0, 7);
    ioctl(fd, SHA204_READ, &packet);
    printf("Reading Data: %x %x %x %x %x %x %x\n", packet.buf[0],packet.buf[1],packet.buf[2],packet.buf[3],\
                                                    packet.buf[4],packet.buf[5],packet.buf[6]);
     
    close(fd);
    return 0;
}


### 回答1: 清空加密芯片中存储数据的代码实现会依赖于具体的加密芯片型号和厂家提供的API。以下是一个示例代码,用于清空ATMEL CryptoAuthentication芯片中存储的数据: ```c #include <atca_basic.h> int main(void) { ATCA_STATUS status; ATCAIfaceCfg cfg = cfg_ateccx08a_i2c_default; uint8_t serial[ATCA_SERIAL_NUM_SIZE]; // 初始化接口 status = atcab_init(&cfg); if (status != ATCA_SUCCESS) { printf("Failed to init interface: %d\n", status); return -1; } // 芯片序列号 status = atcab_read_serial_number(serial); if (status != ATCA_SUCCESS) { printf("Failed to read serial number: %d\n", status); atcab_release(); return -1; } // 擦除存储区域 status = atcab_erase(0, 0, 0); if (status != ATCA_SUCCESS) { printf("Failed to erase data: %d\n", status); atcab_release(); return -1; } // 关闭接口 atcab_release(); printf("Data erased successfully\n"); return 0; } ``` 需要注意的是,此处使用了ATMEL的CryptoAuthentication库,因此需要按照厂家提供的文档进行配置和编译。同时,该示例代码只是一个简单的演示,实际应用中可能需要更复杂的逻辑和异常处理。 ### 回答2: 清空加密芯片中存储的数据的C语言代码示例如下: ```c #include <stdio.h> #include <stdlib.h> // 声明一个函数用于清空加密芯片中的数据 void clearData(void); int main() { // 执行清空数据操作 clearData(); printf("已成功清空加密芯片中的数据。\n"); return 0; } void clearData(void) { // 假设加密芯片中的数据存储在一个数组中 unsigned char chipData[256]; // 假设数据长度为256字节 // 将数组中所有元素设置为0 for (int i = 0; i < sizeof(chipData); i++) { chipData[i] = 0; } } ``` 上述代码中,通过定义一个名为`clearData`的函数来实现数据清空操作。在`clearData`函数中,首先声明了一个长度为256字节的无符号字符数组`chipData`,用于模拟加密芯片中存储的数据。然后通过一个循环遍历数组的所有元素,将每个元素的值设置为`0`,从而实现清空数据的操作。 在主函数`main`中,调用了`clearData`函数来执行清空数据的操作,并输出成功清空数据的提示信息。 ### 回答3: 清空加密芯片中存储的数据的 C 语言代码示例如下: ```c #include <stdio.h> void clearData(unsigned char *data, int size) { for (int i = 0; i < size; i++) { data[i] = 0x00; // 将数据全部置为 0x00 } } int main() { unsigned char encryptedData[100]; // 假设加密芯片中存储的数据大小为 100 字节 // 在这里进行一些加密芯片数据和解密的操作 // 清空加密芯片中存储的数据 clearData(encryptedData, sizeof(encryptedData)); // 在这里进行一些其他的操作 return 0; } ``` 在上面的示例代码中,`clearData` 函数用于将指定的 `data` 数组中的数据全部置为 0x00。在 `main` 函数中,首先假设 `encryptedData` 数组是用来存储加密芯片中的数据的,然后在需要清空数据的位置调用 `clearData` 函数来清空 `encryptedData` 数组中的数据。接下来的代码可根据具体需求进行其他操作。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值