日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > ZYNQ


QSPI是Quad SPI的簡(jiǎn)寫(xiě),表示4線spi,是Motorola公司推出的SPI接口的擴(kuò)展,比SPI應(yīng)用更加廣泛,本文主要演示zynq 7000下對(duì)QSPI 的讀寫(xiě)操作,以及讀取8字節(jié)唯一ID, 可以用于簡(jiǎn)單加密。

本文分為5部分:

  • 硬件設(shè)計(jì)

  • 軟件設(shè)計(jì)

  • 測(cè)試驗(yàn)證

  • 總結(jié)

  • 擴(kuò)展

本文的前提條件是讀者會(huì)helloworld 實(shí)驗(yàn),也就是會(huì)zynq 7000的SDK開(kāi)發(fā)過(guò)程,如果不會(huì),那先去看我的zynq 7000下的helloworld 實(shí)驗(yàn),或者開(kāi)發(fā)板提供的helloworld 實(shí)驗(yàn)教程。

我實(shí)驗(yàn)平臺(tái)是黑金的核心板AC7010, 其板上的QSPI芯片是W25Q256FV

1  硬件設(shè)計(jì)

硬件設(shè)計(jì)基本和helloworld 一樣,不同的是要選擇QSPI, 否則怎么做實(shí)驗(yàn)?zāi)?。還有工程名字取為qspi。

在zynq配置的peripheral I/O Pins里選擇Quad SPI Flash, 如圖:

在zynq配置的MIO configuration里選擇Quad SPI Flash的每個(gè)腳為 fast, 如圖:

除此以外,都和hello world 實(shí)驗(yàn)的硬件設(shè)計(jì)一樣。

2:軟件設(shè)計(jì)

在SDK里 新建工程,取名為qspi_t , 在Next 里可以選擇hello world 或者empty project。

下載我提供的xqspips_flash_polled_example.c 文件, 放入.src ,就是hellowrld.c 的地方,刪除helloworld.c 。

為什么取這樣一個(gè)名字呢?

這是Xilinx提供的樣例程序,你可以在你的xilinx 目錄下搜索到這個(gè)文件。我提供的程序是在其上修改得到的。

FlashWrite,FlashRead,FlashErase,FlashReadID都是樣例程序里包含的。

我做的工作只是修改了main函數(shù),還有仿照FlashReadID, 編寫(xiě)了一個(gè)FlashReadUID函數(shù)。

FlashWrite, 寫(xiě)Flash, 其參數(shù)是QSPI驅(qū)動(dòng)指針, FLash寫(xiě)的起始地址, 寫(xiě)入字節(jié)數(shù), 寫(xiě)命令:

 1void FlashWrite(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command)  2{  3 u8 WriteEnableCmd = { WRITE_ENABLE_CMD };  4 u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */  5 u8 FlashStatus[2];  6  7 /*  8 * Send the write enable command to the FLASH so that it can be  9 * written to, this needs to be sent as a seperate transfer before 10 * the write 11 */ 12 XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL, 13 sizeof(WriteEnableCmd)); 14 15 16 /* 17 * Setup the write command with the specified address and data for the 18 * FLASH 19 */ 20 WriteBuffer[COMMAND_OFFSET]   = Command; 21 WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16); 22 WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8); 23 WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF); 24 25 /* 26 * Send the write command, address, and data to the FLASH to be 27 * written, no receive buffer is specified since there is nothing to 28 * receive 29 */ 30 XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL, 31 ByteCount + OVERHEAD_SIZE); 32 33 /* 34 * Wait for the write command to the FLASH to be completed, it takes 35 * some time for the data to be written 36 */ 37 while (1) { 38 /* 39 * Poll the status register of the FLASH to determine when it 40 * completes, by sending a read status command and receiving the 41 * status byte 42 */ 43 XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd, FlashStatus, 44 sizeof(ReadStatusCmd)); 45 46 /* 47 * If the status indicates the write is done, then stop waiting, 48 * if a value of 0xFF in the status byte is read from the 49 * device and this loop never exits, the device slave select is 50 * possibly incorrect such that the device status is not being 51 * read 52 */ 53 if ((FlashStatus[1] & 0x01) == 0) { 54 break; 55 } 56 } 57}

FlashRead, 讀Flash, 其參數(shù)是QSPI驅(qū)動(dòng)指針, FLash讀的起始地址, 讀取字節(jié)數(shù), 讀命令

 1void FlashRead(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 Command)  2{  3 /*  4 * Setup the write command with the specified address and data for the  5 * FLASH  6 */  7 WriteBuffer[COMMAND_OFFSET]   = Command;  8 WriteBuffer[ADDRESS_1_OFFSET] = (u8)((Address & 0xFF0000) >> 16);  9 WriteBuffer[ADDRESS_2_OFFSET] = (u8)((Address & 0xFF00) >> 8); 10 WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF); 11 12 if ((Command == FAST_READ_CMD) || (Command == DUAL_READ_CMD) || 13 (Command == QUAD_READ_CMD)) { 14 ByteCount += DUMMY_SIZE; 15 } 16 /* 17 * Send the read command to the FLASH to read the specified number 18 * of bytes from the FLASH, send the read command and address and 19 * receive the specified number of bytes of data in the data buffer 20 */ 21 XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, ReadBuffer, 22 ByteCount + OVERHEAD_SIZE); 23}

FlashErase, 擦出Flash, 其參數(shù)是QSPI驅(qū)動(dòng)指針, FLash擦除起始地址, 擦除字節(jié)數(shù)。

 1void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount)  2{  3 u8 WriteEnableCmd = { WRITE_ENABLE_CMD };  4 u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 }; /* must send 2 bytes */  5 u8 FlashStatus[2];  6 int Sector;  7  8 /*  9 * If erase size is same as the total size of the flash, use bulk erase  10 * command  11 */  12 if (ByteCount == (NUM_SECTORS * SECTOR_SIZE)) {  13 /*  14 * Send the write enable command to the FLASH so that it can be  15 * written to, this needs to be sent as a seperate transfer  16 * before the erase  17 */  18 XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,  19 sizeof(WriteEnableCmd));  20  21 /*  22 * Setup the bulk erase command  23 */  24 WriteBuffer[COMMAND_OFFSET]   = BULK_ERASE_CMD;  25  26 /*  27 * Send the bulk erase command; no receive buffer is specified  28 * since there is nothing to receive  29 */  30 XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL,  31 BULK_ERASE_SIZE);  32  33 /*  34 * Wait for the erase command to the FLASH to be completed  35 */  36 while (1) {  37 /*  38 * Poll the status register of the device to determine  39 * when it completes, by sending a read status command  40 * and receiving the status byte  41 */  42 XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,  43 FlashStatus,  44 sizeof(ReadStatusCmd));  45  46 /*  47 * If the status indicates the write is done, then stop  48 * waiting; if a value of 0xFF in the status byte is  49 * read from the device and this loop never exits, the  50 * device slave select is possibly incorrect such that  51 * the device status is not being read  52 */  53 if ((FlashStatus[1] & 0x01) == 0) {  54 break;  55 }  56 }  57  58 return;  59 }  60  61 /*  62 * If the erase size is less than the total size of the flash, use  63 * sector erase command  64 */  65 for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++) {  66 /*  67 * Send the write enable command to the SEEPOM so that it can be  68 * written to, this needs to be sent as a seperate transfer  69 * before the write  70 */  71 XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,  72 sizeof(WriteEnableCmd));  73  74 /*  75 * Setup the write command with the specified address and data  76 * for the FLASH  77 */  78 WriteBuffer[COMMAND_OFFSET]   = SEC_ERASE_CMD;  79 WriteBuffer[ADDRESS_1_OFFSET] = (u8)(Address >> 16);  80 WriteBuffer[ADDRESS_2_OFFSET] = (u8)(Address >> 8);  81 WriteBuffer[ADDRESS_3_OFFSET] = (u8)(Address & 0xFF);  82  83 /*  84 * Send the sector erase command and address; no receive buffer  85 * is specified since there is nothing to receive  86 */  87 XQspiPs_PolledTransfer(QspiPtr, WriteBuffer, NULL,  88 SEC_ERASE_SIZE);  89  90 /*  91 * Wait for the sector erse command to the FLASH to be completed  92 */  93 while (1) {  94 /*  95 * Poll the status register of the device to determine  96 * when it completes, by sending a read status command  97 * and receiving the status byte  98 */  99 XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd, 100 FlashStatus, 101 sizeof(ReadStatusCmd)); 102 103 /* 104 * If the status indicates the write is done, then stop 105 * waiting, if a value of 0xFF in the status byte is 106 * read from the device and this loop never exits, the 107 * device slave select is possibly incorrect such that 108 * the device status is not being read 109 */ 110 if ((FlashStatus[1] & 0x01) == 0) { 111 break; 112 } 113 } 114 115 Address += SECTOR_SIZE; 116 } 117}

寫(xiě)命令其實(shí)只有一個(gè)WRITE_CMD, 但讀命令有4個(gè)選擇:

  • READ_CMD

  • FAST_READ_CMD

  • DUAL_READ_CMD

  • QUAD_READ_CMD

FlashReadID就是讀取JEDEC ID

 1int FlashReadID(void)  2{  3 int Status;  4  5 /*  6 * Read ID in Auto mode.  7 */  8 WriteBuffer[COMMAND_OFFSET]   = READ_ID;  9 WriteBuffer[ADDRESS_1_OFFSET] = 0x23; /* 3 dummy bytes */ 10 WriteBuffer[ADDRESS_2_OFFSET] = 0x08; 11 WriteBuffer[ADDRESS_3_OFFSET] = 0x09; 12 13 Status = XQspiPs_PolledTransfer(&QspiInstance, WriteBuffer, ReadBuffer, 14 RD_ID_SIZE); 15 if (Status != XST_SUCCESS) { 16 return XST_FAILURE; 17 } 18 19 xil_printf("Flash  JEDEC ID=0x%x 0x%x 0x%x\n\r", ReadBuffer[1], ReadBuffer[2], 20 ReadBuffer[3]); 21 22 return XST_SUCCESS; 23}

FlashReadUID是我仿照上面函數(shù)寫(xiě)的, 我查看了W25Q256FV的手冊(cè),讀取唯一ID的cmd 是0x4B, 我不確定其他芯片是否一樣,你需要自己查看。

 1int FlashReadUID(void)  2{  3 int Status;  4  5 /*  6 * Read ID in Auto mode.  7 */  8 WriteBuffer[COMMAND_OFFSET]   = 0x4B;  9 WriteBuffer[ADDRESS_1_OFFSET] = 0x23; /* 3 dummy bytes */ 10 WriteBuffer[ADDRESS_2_OFFSET] = 0x08; 11 WriteBuffer[ADDRESS_3_OFFSET] = 0x09; 12 13 Status = XQspiPs_PolledTransfer(&QspiInstance, WriteBuffer, ReadBuffer, 14 16); 15 if (Status != XST_SUCCESS) { 16 return XST_FAILURE; 17 } 18 19 xil_printf("Flash Unique ID=0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",ReadBuffer[5], ReadBuffer[6], ReadBuffer[7], ReadBuffer[8], ReadBuffer[9], ReadBuffer[10], ReadBuffer[11], ReadBuffer[12]); 20 21 return XST_SUCCESS; 22}

主程序的流程是:

基本初始化,獲取Flash 的驅(qū)動(dòng)指針,給WriteBuffer數(shù)組賦值,就是打算 寫(xiě)什么東西進(jìn)去,調(diào)用2個(gè)id 讀取, 擦除,讀取,顯示內(nèi)容,寫(xiě)入, 讀取,顯示內(nèi)容,調(diào)用2個(gè)id 讀取并顯示。

3:程序運(yùn)行

以下是程序運(yùn)行在串口監(jiān)視終端上的顯示內(nèi)容:


4:總結(jié)

按資料介紹,唯一id 每個(gè)芯片都是不一樣的,可不可以把你 的id 告訴我,看看是不是都不一樣。

如果這樣的話,我們就可以用這個(gè)id 加密,就是用一個(gè)算法,比如des,des3,得到一個(gè)結(jié)果,而這個(gè)結(jié)果只有知道算法的人才知道。

把這個(gè)結(jié)果填入一個(gè)地方,那就是程序員認(rèn)可了。這樣如果簡(jiǎn)單復(fù)制程序,那就不行的,防止盜版。

5 : 擴(kuò)展

其實(shí)xilinx 也有一套加密的算法,xilinx 的加密方法相關(guān)文檔是:

https://www.xilinx.com/support/documentation/user_guides/ug1025-zynq-secure-boot-gsg.pdf

xapp1175_zynq_secure_boot.pdf

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉