zoukankan      html  css  js  c++  java
  • NiosII中Flash的使用(转)

    NiosII中Flash的使用

           在嵌入式系统中,Flash是最常用组件之一。许多使用过flash的朋友都了解,Flash的特点是“读来容易写来难”。通常,可以直接读出Flash的内容;但如果要写入数据,就要发送一长串命令,比如像:555 ,AA,2AA,55,555,A0 ,PA,PD 就表示对PA地址写入数据PD,实际情况还要复杂一点,因为通常还要包含许多查询操作。

        哎呀,这真是好繁琐呀,有没有省力的方法呢?现在好了,NiosII的开发环境提供了对符合CFI标准的Flash的支持,使用几个简单的函数,就可以操作Flash,真是方便了许多。

       在这里,我粗略得介绍一下nios 中flash的使用;更加详细的帮助信息请您参考Altera公司提供的文档。如果本文能对您有一点点帮助,我都会感到非常高兴。

    一. 准备工作:

       在使用Flash之前,有几个准备工作要做:

       1。开发板上至少要有一片符合CFI标准的Flash。

       2。设计好对应目标板的Flash编程器(Flash Programmer)

        下面我以本站设计的开发板ezNiosDKC6B为目标板,来介绍如何使用Flash,你可以举一反三,在自己的系统中使用Flash.

    二. 为SOPC系统中添加Flash接口:

    1。   双击在Memory中的Flash Memory(Common Flash Interface),即可为系统添加Flash接口。

    2。 对于ezNiosDK的用户,Address Width可以选择 20 Bits,Data Width 可以选择 16 Bits,这样总的容量是2M Bytes

        [转载]NiosII中Flash的使用(转)

    3。Timing选项卡中,可以如下添写:

        [转载]NiosII中Flash的使用(转)

       完成后,选择Finish,即可为系统添加Flash接口。

    4。增加三态总线桥。Flash 接口必须通过三态总线桥接到实际的芯片上。双击Bridges下的Avalon Tri-State Bridge,请按照下图设置,为系统增加三态总线桥。

        [转载]NiosII中Flash的使用(转)

    5。为Flash接口分配引脚。请参考我之前的文章:Step By Step创建标准(Standard) niosII系统

        注意,如果Data Width是16Bits,那么tri_state_bridge_0_address[0]不必接到Flash上,tri_state_bridge_0_address[1]对应Flash的A[0],tri_state_bridge_0_address[2]对应Flash的A[1],以此类推。

    三. 在Nios IDE中使用Flash编程器:

    3-1。配置Component/Kit Library Search Path。目的是在系统中增加本站设计的Flash编程器目录,请把光盘CD1上的/Example/ezNiosC6 拷贝到您的电脑的硬盘上。比如,我把他放在h:/DB2005/project/niosDK/CD/CD1/Example/中,然后在Altera SOPC Builder中,选择File -> SOPC Builder Setup,增加如下搜索路径:+h:/DB2005/project/niosDK/CD/CD1/Example/ezNiosC6

    ezNiosC3的用户如下操作:请把光盘CD1上的/Example/ezNiosC3 拷贝到您的电脑的硬盘上。比如,我把他放在h:/DB2005/project/niosDK/CD/CD1/Example/中,然后在Altera SOPC Builder中,选择File -> SOPC Builder Setup,增加如下搜索路径:+h:/DB2005/project/niosDK/CD/CD1/Example/ezNiosC3

    并顺便检察Modelsim Directory是否正确:比如,我的是 g:/w2k/eda/fpga/altera/modeltech_6.0/win32

    然后,你需要关闭Altera SOPC Builder,然后再重新通过QuartusII的Tools ->SOPC Builder来开启SOPC Builder,这样上述修改才能生效。

       [转载]NiosII中Flash的使用(转)

    常见错误:有许多朋友往往在设置路径的时候,犯与下图类似的错误。错误在于第一个路径前面是不需要 + 号的!要去掉第一个路径前面的 + 号

    [转载]NiosII中Flash的使用(转)

    3-2:使用Flash编程器。

    我使用项目:ezC6Be_StdF50_zip_filesystem_0(在CD1ExampleezNiosC6BezC6Be_StdF50softwareezC6Be_StdF50_zip_filesystem_0下,请使用Nios IDE中的File-Import来导入这个项目),来说明如何使用Flash编程器。

        首先为系统上电,并连接好下载电缆。

        选择Tools -> Flash Programmer,启动 Flash 编程器

        选择New,可以看到增加了一个名为 ezC6Be_StdF50_zip_filesystem_0 programmer的flash 编程器

    [转载]NiosII中Flash的使用(转)

       选择Program software project into flash memory,然后选择Apply,在选择Program Flash,就启动了Flash 编程器!如果顺利的话,可以看到如下的提示:

        [转载]NiosII中Flash的使用(转)

    如果看到如上提示,OK,小功告成,我们已经可以正常使用Flash编程器啦!

       下面我来介绍如何在程序中引用Flash。

     使用NiosII提供的系统函数,可以方便得使用Flash,免除了通常操作Flash 的繁琐,这对用户来说,真是方便多了。

        Altera 提供了两种类型的函数,提供给客户:Simple Flash Access(简单的Flash访问),以及Fine-Grained Flash Access(细粒度Flash访问)。

        一般情况下,我还是推荐使用Fine-Grained Flash Access(细粒度Flash访问)函数,比 Simple Flash Access也复杂不了多少,但可以避免通常的跨块擦除问题。因为Flash是按照   Block组织起来的,通常一次擦除一整个块。如果写Flash的地址于Flash块的组织结构不吻合,比如跨越了Flash块的边缘,那么可能会擦除掉其余的数据。比如,即使要写入1Byte,也要擦除掉4Kbyte,也许这4Kbyte里面还有许多有用的数据,就会被抹掉。

        我们下面介绍几个常用的函数,关于更详细的内容,请参考Altera提供的文档。

        首先介绍第一步:打开Flash,就像c程序打开硬盘中的数据文件一样,使用之前要打开Flash.

    我们使用alt_flash_open_dev()打开Flash,它返回一个句柄。比如,下面是使用这个函数的片断:

    alt_flash_fd* fd;

    fd = alt_flash_open_dev(EXT_FLASH_NAME);

    其中,EXT_FLASH_NAME是预先定义的Flash的名字(#define EXT_FLASH_NAME "/dev/ext_flash"

    接下来的操作,都是通过该句柄:fd,来访问Flash的。

        读出Flash使用函数:alt_read_flash,原型如下:

    int alt_read_flash( alt_flash_fd* fd,

          int offset,

          void* dest_addr,

          int length )

        使用完了,也别忘记关闭该Flash,就象读写完硬盘中的数据文件后要关闭一样。其原型如下:

    void alt_flash_close_dev(alt_flash_fd* fd )

        Fine-Grained Flash Access机制提供了如下几个函数:alt_get_flash_info(), alt_erase_flash_block(), alt_write_flash_block()。

       alt_get_flash_info()可以提取Flash的信息,比如包含几个区域,每个区域有几个块,每个块的大小等等。它的原型如下:

        int alt_get_flash_info( alt_flash_fd* fd,flash_region** info,int* number_of_regions)

    比如,如下就是一个调用该函数的程序片断:

      int ret_code = 0;

      int number_of_regions=0;

      flash_region* regions;

      ret_code = alt_get_flash_info(fd, &regions, &number_of_regions

     这里涉及到一个结构:flash_region,原型如下:

    typedef struct flash_region

    {int offset;

    int region_size;

    int number_of_blocks;

    int block_size;

    }flash_region;

      擦除一个块使用函数:alt_flash_fd,函数原型如下:

    int alt_erase_flash_block( alt_flash_fd* fd,

               int offset,

               int length)

      写入一个块使用函数:alt_write_flash_block,函数原型如下:

    int alt_write_flash_block( alt_flash_fd* fd,

               int block_offset,

               int data_offset,

               const void *data,

               int length)

      罗罗嗦嗦说了这么多,下面我们来看一个实际的范例;这个范例是我使用来测试flash的,相信大家可以从中获益

    良多。

    #include <stdio.h>

    #include <errno.h>

    #include <string.h>

    #include "alt_types.h"

    #include "sys/alt_flash.h"

    #include "sys/alt_flash_dev.h"

    #define NUM_BYTES_TO_WRITE 512

    //#define NUM_BYTES_TO_WRITE 64

    int test_programming( alt_flash_fd* fd, int test_offset)

    {

    int i,j;

    alt_u8 data_written[NUM_BYTES_TO_WRITE];

    alt_u8 data_read[NUM_BYTES_TO_WRITE];

    int ret_code = 0;

    int test_length = sizeof(data_written);

     

    for (j=0;j<7;j++)

    {

    for(i=0;i<sizeof(data_written)/2;i++)

    data_written[i] = j*0x15;

    for(i=sizeof(data_written)/2;i<sizeof(data_written);i++)

    data_written[i] = (j*0x15)+1;

     

    ret_code = alt_write_flash(fd, test_offset, data_written, test_length);

    if (!ret_code)

    {

    ret_code = alt_read_flash(fd, test_offset, data_read, test_length);

    if(!ret_code)

    {

    if (memcmp(data_written, data_read, test_length))

    {

    printf( "nERROR: compare failed sector offset %#x iteration%#xn",

    test_offset, j);

    return ret_code;

    }

    }

    }

     

    printf("*");

    if (ret_code)

    {

    printf( "nERROR: function alt_write_flash failed. ret_code %dn",

    ret_code);

    return ret_code;

    }

    }

    return ret_code;

    }

    int test_flash_erase( alt_flash_fd* fd)

    {

    int ret_code = 0;

    int number_of_regions=0;

    flash_region* regions;

    int i,j,k;

    int test_offset;

    int test_length;

    alt_u8 read_data[200] ;

    ret_code = alt_get_flash_info(fd, &regions, &number_of_regions);

    if (ret_code)

    {

    printf( "nERROR: function alt_get_flash_info failed. ret_code %dn",

    ret_code);

    }

     

    printf("nThis is AMD29LV160DBn");

    printf("Flash name %sn",fd->name);

     

    printf("This flash has %d erase regionsn", number_of_regions);

    for (i=0;i<number_of_regions;i++)

    {

    printf("Start 0x%8x End 0x%8x Number of Blocks %3d Block Size 0x%8xn",

    (regions+i)->offset,

    (regions+i)->region_size+(regions+i)->offset,

    (regions+i)->number_of_blocks,

    (regions+i)->block_size);

    }

     

    for(j=0;j<number_of_regions;j++)

    {

    for(i=0;i<((regions+j)->number_of_blocks);i++)

    { test_offset = (regions+j)->offset + i*(regions+j)->block_size;

    test_length = (regions+j)->block_size;

    printf(" ---Testing flash block erase...@ 0x%8x length= 0x%8x n",test_offset,test_length);

    ret_code = alt_erase_flash_block(fd, (regions+j)->offset + i*(regions+j)->block_size, (regions+j)->block_size);

    if (ret_code)

    {

    printf( "nERROR: function alt_erase_flash_block failed. ret_code %dn", ret_code);

    break;

    }

    else

    {

    ret_code = alt_read_flash(fd, test_offset, read_data, 100);

    for (k=0;k<100;k++)

    {

    if (read_data[k] != 0xff)

    {

    printf("nERROR: erase compare failed. %d %#xn", k, read_data[k]);

    break;

    }

    }

    }

    }//@for(i=1

    }//@for(j=1)

    printf(" passed.n");

    return ret_code;

    }

     

     

     

    int test_flash_write( alt_flash_fd* fd)

    {

    int ret_code = 0;

    int number_of_regions=0;

    flash_region* regions;

    int i,j,k;

    int test_offset;

    int test_length;

    alt_u8 read_data[200] ;

    alt_u8 write_data[200];

    ret_code = alt_get_flash_info(fd, &regions, &number_of_regions);

    if (ret_code)

    {

    printf( "nERROR: function alt_get_flash_info failed. ret_code %dn",

    ret_code);

    }

     

    printf("nThis is AMD29LV160DBn");

    printf("Flash name %sn",fd->name);

     

    printf("This flash has %d erase regionsn", number_of_regions);

    for (i=0;i<number_of_regions;i++)

    {

    printf("Start 0x%8x End 0x%8x Number of Blocks %3d Block Size 0x%8xn",

    (regions+i)->offset,

    (regions+i)->region_size+(regions+i)->offset,

    (regions+i)->number_of_blocks,

    (regions+i)->block_size);

    }

     

    for(j=0;j<number_of_regions;j++)

    {

    for(i=0;i<((regions+j)->number_of_blocks);i++)

    { test_offset = (regions+j)->offset + i*(regions+j)->block_size;

    test_length = (regions+j)->block_size;

    printf(" ---Testing flash block erase...@ 0x%8x length= 0x%8x n",test_offset,test_length);

    ret_code = alt_erase_flash_block(fd, (regions+j)->offset + i*(regions+j)->block_size, (regions+j)->block_size);

    if (ret_code)

    {

    printf( "nERROR: function alt_erase_flash_block failed. ret_code %dn", ret_code);

    break;

    }

    else

    {

    ret_code = alt_read_flash(fd, test_offset, read_data, 100);

    for (k=0;k<100;k++)

    {

    if (read_data[k] != 0xff)

    {

    printf("nERROR: erase compare failed. %d %#xn", k, read_data[k]);

    break;

    }

    }//@for (k=0)

     

     

    printf(" -----------Now Testing flash block write...@ 0x%8x n",test_offset);

     

    for(k=0;k<100;k++)

    write_data[k] = k;

     

    ret_code = alt_write_flash_block( fd, (regions+j)->offset + i*(regions+j)->block_size,

    test_offset + i, write_data, 100);

    if (ret_code)

    {

    printf( "nERROR: function aXlt_write_flash_block failed. ret_code %dn", ret_code);

    break;

    }

    else

    { ret_code = alt_read_flash(fd, test_offset + i, read_data, 100);

    for (k=0;k<100;k++)

    {

    if (read_data[k] != write_data[k])

    {printf( "nERROR: compare failed, expected %#x read %#xn",write_data[i], read_data[i]);

    break;

    }

    }

    }//@ else

     

    }

    }//@for(i=1

    }//@for(j=1)

    printf(" passed.n");

    return ret_code;

    }

     

     

     

     

    int test_get_info( alt_flash_fd* fd)

    {

    int ret_code = 0;

    int number_of_regions=0;

    flash_region* regions;

    int i;

    ret_code = alt_get_flash_info(fd, &regions, &number_of_regions);

    if (ret_code)

    {

    printf( "nERROR: function alt_get_flash_info failed. ret_code %dn",

    ret_code);

    }

     

    if (0)

    {

     

    }

    else

    {

    printf("nThis is not the standard reference designn");

    printf("Flash name %sn",fd->name);

     

    printf("This flash has %d erase regionsn", number_of_regions);

    for (i=0;i<number_of_regions;i++)

    {

    printf("Start 0x%8x End 0x%8x Number of Blocks %3d Block Size 0x%8xn",

    (regions+i)->offset,

    (regions+i)->region_size+(regions+i)->offset,

    (regions+i)->number_of_blocks,

    (regions+i)->block_size);

    }

    }

    return ret_code;

    }

    int main (void)

    {

    int ret_code;

    int test_offset;

    alt_flash_fd* fd;

    alt_u8 write_data[100];

    alt_u8 read_data[100];

    int i,j;

     

    fd = alt_flash_open_dev(EXT_FLASH_NAME);

     

    if (fd)

    {

    printf("nnn<----> Running Flash Tests <---->n");

    printf("This will take approximately 1 minutenn");

     

    printf("-Testing flash info retrieval...");

    ret_code = test_get_info(fd);

    if (ret_code)

    {

    printf( "nERROR: function test_get_info failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    printf(" passed.n");

     

    printf("-Testing flash block erase,write...n");

    ret_code = test_flash_write(fd);

    if (ret_code)

    {

    printf( "nERROR: test_flash_erase failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    printf(" passed.n");

     

     

     

    printf("-Testing flash write...n");

     

    test_offset = 0x0;

    printf("n test_offset=0x%8x ",test_offset);

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

     

    test_offset = 0x4000;

    printf("n test_offset=0x%8x ",test_offset);

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

     

    test_offset = 0x6000;

    printf("n test_offset=0x%8x ",test_offset);

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

     

    test_offset = 0x8000;

    printf("n test_offset=0x%8x ",test_offset);

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

     

    for(j=1;j<=31;j++)

    {test_offset = 0x10000*j;

    printf("n test_offset=0x%8x ",test_offset);

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    }

    printf(" passed.n");

     

     

    printf(" 0x10ff00: ");

    test_offset = 0x10ff00;

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

     

     

    printf(" 0x100100: ");

    test_offset = 0x100100;

    ret_code = test_programming(fd, test_offset);

    if (ret_code)

    goto finished;

    printf(" passed.n");

    printf("-Testing flash block erase...n");

    ret_code = test_flash_erase(fd);

    if (ret_code)

    {

    printf( "nERROR: test_flash_erase failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    printf(" passed.n");

    test_offset = 0x10000;

    printf(" ---Testing flash block write...@ 0x%8x n",test_offset);

     

    for(i=0;i<100;i++)

    write_data[i] = i;

     

    ret_code = alt_write_flash_block( fd, 0x10000,

    test_offset, write_data,

    100);

    if (ret_code)

    {

    printf( "nERROR: function alt_write_flash_block failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    else

    {

    ret_code = alt_read_flash(fd, test_offset, read_data, 100);

    for (i=0;i<100;i++)

    {

    if (read_data[i] != write_data[i])

    {

    printf( "nERROR: compare failed, expected %#x read %#xn",

    write_data[i], read_data[i]);

    goto finished;

    }

    }

    }

    printf(" passed.n");

     

    test_offset = 0x10010;

    printf("-Testing unaligned writes.....");

    alt_erase_flash_block(fd, 0x10000, 0x100000);

     

    ret_code = alt_write_flash_block( fd, 0x10000,

    test_offset, write_data,

    100);

     

    if (ret_code)

    {

    printf( "nERROR: function alt_write_flash_block failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    else

    {

    ret_code = alt_read_flash(fd, test_offset, read_data, 100);

    for (i=0;i<100;i++)

    {

    if (read_data[i] != write_data[i])

    {

    printf( "nERROR: compare failed, expected %#x read %#xn",

    write_data[i], read_data[i]);

    goto finished;

    }

    }

    }

    printf(" passed.n");

     

    printf("-Testing flash block erase...n");

    ret_code = test_flash_erase(fd);

    if (ret_code)

    {

    printf( "nERROR: test_flash_erase failed. ret_code %dn",

    ret_code);

    goto finished;

    }

    printf(" passed.n");

     

     

    printf("All Tests Passed!n");

    }

    else

    {

    printf("Can't open the flash devicen");

    }

    finished:

    alt_flash_close_dev(fd);

    printf("Exiting Flash Testsn");

     

    return 0;

    }

  • 相关阅读:
    服务器状态码
    QuerySet中添加Extra进行SQL查询
    django配置一个网站建设
    MySQL数据库查询中的特殊命令
    125. Valid Palindrome
    121. Best Time to Buy and Sell Stock
    117. Populating Next Right Pointers in Each Node II
    98. Validate Binary Search Tree
    91. Decode Ways
    90. Subsets II
  • 原文地址:https://www.cnblogs.com/just4fun/p/2307614.html
Copyright © 2011-2022 走看看