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

来源:互联网 发布:mysql notifier 关闭 编辑:程序博客网 时间:2024/05/16 09:18

        近段时间一个项目使用了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, 0x06, 0x02, 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;}


0 0
原创粉丝点击