zoukankan      html  css  js  c++  java
  • 【真OO无双】如何在Nios II對Flash進行讀寫

    Abstract
    在DE2版子上,除了8MB的SDRAM最大外,排名第2的就是4MB的Flash,本文討論如何在Nios II對Flash進行讀寫。

    Introduction
    使用環境:Quartus II 8.0 + Nios II EDS 8.0 +
     DE2(Cyclone II EP2C35F627C6) or DE2-70 (Cyclone II EP2C70F896C6N)

    我曾經在(原創) 如何在Nios II使用Zip File System? (IC Design) (Nios II) (DE2)(原創) 如何讓Nios II一Power On就執行? (SOC) (Nios II) (SOPC Builder) (DE2) (DE2-70)討論對flash的使用,不過那只能算是『應用』,並未真的用HAL去存取過flash,剛好網友成電王超提到用HAL讀寫flash的問題,我就順手測試了一下。

    以DE2_NIOS_Lite 1.2為範本
    我使用(原創) DE2_NIOS_Lite 1.2 (SOC) (Nios II) (SOPC Builder) (DE2)為範本測試flash,這個SOPC已經將flash ip掛好,所以我們可以將重點放在HAL部分,不過考量有些人是自己建立SOPC系統,還是討論一下SOPC部分。

    SOPC Builder部分
    Step 1:
    掛上Tristate Bridge與Flash Memory(CFI)

    1

    tep 2:
    設定Flash Parameter & Timing

    1

    1

    Top Module部分

    DE2_NIOS_Lite.v / Verilog

    1 /* 
      2 (C) OOMusou 2008 http://oomusou.cnblogs.com
      3 
      4 Filename    : DE2_NIOS_Lite.v
      5 Compiler    : Quartus II 8.0 + ModelSim-Altera 6.1g
      6 Description : DE2_NIOS lite version 1.2
      7 Release     : 08/08/2008 1.0
      8 */
      9 
    10 module DE2_NIOS_Lite (
    11   input         CLOCK_50,     // On Board 50 MHz
    12   input  [3:0]  KEY,          // Pushbutton[3:0]
    13   input  [17:0] SW,           // Toggle Switch[17:0]
    14   output [8:0]  LEDG,         // LED Green[8:0]
    15   output [17:0] LEDR,         // LED Red[17:0]
    16   output [6:0]  HEX0,         // Seven Segment Digit 0
    17   output [6:0]  HEX1,         // Seven Segment Digit 1
    18   output [6:0]  HEX2,         // Seven Segment Digit 2
    19   output [6:0]  HEX3,         // Seven Segment Digit 3
    20   output [6:0]  HEX4,         // Seven Segment Digit 4
    21   output [6:0]  HEX5,         // Seven Segment Digit 5
    22   output [6:0]  HEX6,         // Seven Segment Digit 6
    23   output [6:0]  HEX7,         // Seven Segment Digit 7
    24   inout  [15:0] DRAM_DQ,      // SDRAM Data bus 16 Bits
    25   output [11:0] DRAM_ADDR,    // SDRAM Address bus 12 Bits
    26   output        DRAM_LDQM,    // SDRAM Low-byte Data Mask 
    27   output        DRAM_UDQM,    // SDRAM High-byte Data Mask
    28   output        DRAM_WE_N,    // SDRAM Write Enable
    29   output        DRAM_CAS_N,   // SDRAM Column Address Strobe
    30   output        DRAM_RAS_N,   // SDRAM Row Address Strobe
    31   output        DRAM_CS_N,    // SDRAM Chip Select
    32   output        DRAM_BA_0,    // SDRAM Bank Address 0
    33   output        DRAM_BA_1,    // SDRAM Bank Address 0
    34   output        DRAM_CLK,     // SDRAM Clock
    35   output        DRAM_CKE,     // SDRAM Clock Enable
    36   inout  [7:0]  FL_DQ,        // FLASH Data bus 8 Bits
    37   output [21:0] FL_ADDR,      // FLASH Address bus 22 Bits
    38   output        FL_WE_N,      // FLASH Write Enable
    39   output        FL_RST_N,     // FLASH Reset
    40   output        FL_OE_N,      // FLASH Output Enable
    41   output        FL_CE_N,      // FLASH Chip Enable
    42   inout  [15:0] SRAM_DQ,      // SRAM Data bus 16 Bits
    43   output [17:0] SRAM_ADDR,    // SRAM Address bus 18 Bits
    44   output        SRAM_UB_N,    // SRAM Low-byte Data Mask 
    45   output        SRAM_LB_N,    // SRAM High-byte Data Mask 
    46   output        SRAM_WE_N,    // SRAM Write Enable
    47   output        SRAM_CE_N,    // SRAM Chip Enable
    48   output        SRAM_OE_N     // SRAM Output Enable
    49 );
    50 
    51 wire CPU_CLK;
    52 wire CPU_RESET;
    53 
    54 assign FL_RST_N = 1'b1;
    55 
    56 Reset_Delay u0 (
    57   .iRST(KEY[0]),
    58   .iCLK(CLOCK_50),
    59   .oRESET(CPU_RESET)
    60 );
    61 
    62 SDRAM_PLL u1 (
    63   .inclk0(CLOCK_50),
    64   .c0(DRAM_CLK),
    65   .c1(CPU_CLK)
    66 );
    67 
    68 nios_ii u2 (
    69   .clk(CPU_CLK),
    70   .clk_50(CLOCK_50),
    71   .reset_n(CPU_RESET),
    72   // KEY
    73   .in_port_to_the_key_pio(KEY),
    74   // SW
    75   .in_port_to_the_sw_pio(SW),
    76   // LEDG
    77   .out_port_from_the_ledg_pio(LEDG),
    78   // LEDR
    79   .out_port_from_the_ledr_pio(LEDR),
    80   // SEG7
    81   .oSEG0_from_the_seg7(HEX0),
    82   .oSEG1_from_the_seg7(HEX1),
    83   .oSEG2_from_the_seg7(HEX2),
    84   .oSEG3_from_the_seg7(HEX3),
    85   .oSEG4_from_the_seg7(HEX4),
    86   .oSEG5_from_the_seg7(HEX5),
    87   .oSEG6_from_the_seg7(HEX6),
    88   .oSEG7_from_the_seg7(HEX7),
    89   // SDRAM
    90   .zs_addr_from_the_sdram(DRAM_ADDR),
    91   .zs_ba_from_the_sdram({DRAM_BA_1,DRAM_BA_0}),
    92   .zs_cas_n_from_the_sdram(DRAM_CAS_N),
    93   .zs_cke_from_the_sdram(DRAM_CKE),
    94   .zs_cs_n_from_the_sdram(DRAM_CS_N),
    95   .zs_dq_to_and_from_the_sdram(DRAM_DQ),
    96   .zs_dqm_from_the_sdram({DRAM_UDQM,DRAM_LDQM}),
    97   .zs_ras_n_from_the_sdram(DRAM_RAS_N),
    98   .zs_we_n_from_the_sdram(DRAM_WE_N),
    99   // SRAM
    100   .SRAM_ADDR_from_the_sram(SRAM_ADDR),
    101   .SRAM_CE_N_from_the_sram(SRAM_CE_N),
    102   .SRAM_DQ_to_and_from_the_sram(SRAM_DQ),
    103   .SRAM_LB_N_from_the_sram(SRAM_LB_N),
    104   .SRAM_OE_N_from_the_sram(SRAM_OE_N),
    105   .SRAM_UB_N_from_the_sram(SRAM_UB_N),
    106   .SRAM_WE_N_from_the_sram(SRAM_WE_N),
    107   // FLASH
    108   .address_to_the_cfi_flash(FL_ADDR),
    109   .data_to_and_from_the_cfi_flash(FL_DQ),
    110   .read_n_to_the_cfi_flash(FL_OE_N),
    111   .select_n_to_the_cfi_flash(FL_CE_N),
    112   .write_n_to_the_cfi_flash(FL_WE_N)
    113 );
    114 
    115 endmodule
    107行
    // FLASH
    .address_to_the_cfi_flash(FL_ADDR),
    .data_to_and_from_the_cfi_flash(FL_DQ),
    .read_n_to_the_cfi_flash(FL_OE_N),
    .select_n_to_the_cfi_flash(FL_CE_N),
    .write_n_to_the_cfi_flash(FL_WE_N)
    
    連接SOPC關於flash部分的接腳。
    
    54行
    assign FL_RST_N = 1'b1;

    這是大家常忽略的,記得將FL_RST_N設為1'b1。

    使用HAL對Flash做讀寫

    hello_world.c / C

    1 /* 
    2 (C) OOMusou 2008 http://oomusou.cnblogs.com
    3 
    4 Filename    : hello_world.c
    5 Compiler    : Nios II EDS 8.0 / ANSI C
    6 Description : Demo how to read / write CFI-Flash
    7 Release     : 10/19/2008 1.0
    8 */
    9 
    10 #include <stdio.h>
    11 #include "system.h"        // CFI_FLASH_NAME
    12 #include "sys/alt_flash.h" // flash HAL
    13 
    14 int main() {
    15   alt_flash_fd *fd;
    16   int i, j, return_code;
    17   i = 10;
    18   j = 9;
    19   
    20   // open flash
    21   fd = alt_flash_open_dev(CFI_FLASH_NAME);
    22   
    23   if (!fd) {
    24     printf("alt_flash_open_dev error\n");
    25     return -1;
    26   }
    27   
    28   // write flash
    29   return_code = alt_write_flash(fd, 0, &i, sizeof(int));
    30   if (return_code) {
    31     printf("alt_write_flash error\n");
    32     return -1;
    33   }
    34   
    35   // read flash  
    36   return_code = alt_read_flash(fd, 0, &j, sizeof(int));
    37   if (return_code) {
    38     printf("alt_read_flash error\n");
    39     return -1;
    40   }
    41   
    42   // compare input & output
    43   if (i == j)
    44     printf("i=%d, j=%d, flash read / write OK\n", i, j);
    45   else
    46     printf("i=%d, j=%d, flash read / write error\n", i, j);
    47   
    48   // close flash  
    49   alt_flash_close_dev(fd);    
    50   
    51   return 0;
    52 }
    53 

    執行結果

    2

    11行 
    
    #include "system.h"        // CFI_FLASH_NAME
    #include "sys/alt_flash.h" // flash HAL
    
    system.h記載著SOPC周邊的資訊,sys/alt_flash.h則記載著存取flash的HAL。
    
    20行
    
    // open flash
    fd = alt_flash_open_dev(CFI_FLASH_NAME);
    
    開啟flash。
    
    28行 
    
    // write flash
    return_code = alt_write_flash(fd, 0, &i, sizeof(int));
    
    將變數i寫入flash。
    
    35行
    
    // read flash  
    return_code = alt_read_flash(fd, 0, &j, sizeof(int));
    
    從flash讀出資料到變數j。
    
    42行
    
    // compare input & output
    if (i == j)
      printf("i=%d, j=%d, flash read / write OK\n", i, j);
    else
      printf("i=%d, j=%d, flash read / write error\n", i, j);
    
    比較i與j的值是否相等,若相等表示read/write正常。
    
    48行
    
    // close flash  
    alt_flash_close_dev(fd);   


    關閉flash。

    完整程式碼下載
    DE2_NIOS_Lite_12_flash.7z (for DE2)
    DE2_70_NIOS_10_flash.7z (for DE2-70)

    Conclusion
    事實上Altera還提供了其他對flash存取的HAL,以Quartus II 8.0而言,位於C:\altera\80\nios2eds\components\altera_hal\HAL\inc\sys\alt_flash.h,讀者可自行參考。

    DE2-70與DE2類似,就不另外討論,只有SOPC Builder的Flash paramters & timing不太一樣,只提供source code供讀者研究。

    See Also
    (原創) 如何在Nios II使用Zip File System? (IC Design) (Nios II) (DE2)
    (原創) 如何讓Nios II一Power On就執行? (SOC) (Nios II) (SOPC Builder) (DE2) (DE2-70)
    (原創) 如何解決No CFI table found at address的錯誤訊息? (SOC) (Nios II) (DE2)

    Reference
    徐光輝 等著 2006,基於FPGA的嵌入式開發與應用,電子工業出版社

  • 相关阅读:
    SpringBoot读取Resource下文件的几种方式(十五)
    Springboot+vue前后端分离文件上传、下载方式及与Spring的异同(十四)
    springboot多个service互相调用的事务处理(十三)
    Bigdecimal用法
    Linux常见wenti
    informix常见问题
    Spring-boot常见问题(十二)
    浅析VO、DTO、DO、PO的概念、区别和用处(八)
    Tbase读写分离与分库分表
    函数的节流和抖动
  • 原文地址:https://www.cnblogs.com/woshitianma/p/2932661.html
Copyright © 2011-2022 走看看