声明:本文转载于http://www.cnblogs.com/kingst,版权归黑金动力社区(http://www.heijin.org)所有。
一、简介 这一节,我们来聊聊SDRAM吧。作为NIOS系统中最重要的一个外部器件,它担任着重要的角色,大家对它也应该很熟悉。每次上电的时候,FPGA都会把FLASH中的程序送到SDRAM中运行,之所以这样来做就是因为它的速度很快,但它掉电是要丢失数据的,所以要把数据存到FLASH中。
有关SDRAM的理论知识我在这里不说了,不知道的百度google一下都可以。其实在NIOS II开发过程中,就算你对SDRAM的理论知识不了解,也不耽误你对它的使用。SOPC builder都已经完美的将它驱动起来,我们只要知道怎么使用它就可以了。下面,我们就来讲讲他的使用方法,其实真的很简单。
在我们讲第一节的时候,我们就已经讲了如何构建SDRAM的控制器了,我在这里不再重复了,假设你已经构建好了,我主要讲一下有关软件的部分。
二、软件开发 首先打开NIOS II 9.0 IDE软件,打开后,我们来看看system.h文件,确定一下SDRAM控制器模块是否已经加入进来。如果加入,有下面的内容出现
1 | #define SDRAM_NAME "/dev/sdram" |
3 | #define SDRAM_TYPE "altera_avalon_new_sdram_controller" |
5 | #define SDRAM_BASE 0x01000000 |
接下来,我们开始编写有关SDRAM的软件代码,代码很简单,如下所示
02 | * ================================================================== |
04 | * Description: SDRAM读写试验 |
08 | * Compiler: Nios II 9.0 IDE |
10 | * Email: avic633@gmail.com |
11 | * ================================================================= |
14 | /*---------------------------------------------------------------- |
16 | *----------------------------------------------------------------*/ |
18 | #include "../inc/sopc.h" |
22 | /*--------------------------------------------------------------- |
24 | *---------------------------------------------------------------*/ |
25 | unsigned short * ram = (unsigned short *)(SDRAM_BASE+0x10000); //SDRAM地址 |
28 | * === FUNCTION =================================================== |
31 | * ================================================================= |
38 | //向ram中写数据,当ram写完以后,ram的地址已经变为(SDRAM_BASE+0x10100) |
45 | printf("%d\n",*(--ram)); |
程序很简单,就是向指定的SDRAM中赋值。在这个程序里面有几个地方需要说明一下。首先,我在程序前面定义了一个unsigned short类型的指针变量ram,并将其指向SDRAM+0x10000这个位置。之所以设置为unsigned short数据类型,是因为我们用的SDRAM是16位数据总线的。而将其指向SDRAM+0x10000是因为在NIOS II运行时会用到SDRAM的部分空间,我们必须避开这部分空间,以免运行错误。0x10000这个值不是固定的,只要避开SDRAM的那部分空间就可以了。除此之外还有一个地方需要注意,就是当我们对sdram赋值以后,指针就会向后移动,指向下一个地址空间,每加一次,地址都会向后面移动16位。假如我们现在是在SDRAM+0X10000这个位置,当指针向后移动一次以后,地址就变为了SDRAM+0X10002,再加一次就变为了SDRAM+0X10004,以此类推。这些都是内部自动处理的,不需要我们来参与,我们只要知道就可以了。
其实我讲这部分内容是想告诉大家,SDRAM控制器一旦构建好以后,我们对SDRAM的处理就像对内部地址一样,我们可以随意的进行赋值和读取。对于开发板上的64Mbit的SDRAM其实有很少一部分用给NIOS系统,其余部分都在空闲,大家是不是觉得很浪费呢。其实在有些情况下,我们就可以利用起这部分资源,比如在某个系统中,我们需要将外设接收到的数据缓存一下,我们就可以用这部分空闲的SDRAM空间来处理。
在C语言中,如果我们要接收比较大的数据,还有另一种处理方法,那就是借助堆(heap)。可能有些人对堆和栈还分不清楚,我在这简单解释一下。栈(stack) 由系统自动分配。 例如,声明在函数中一个局部变量 int b,系统自动在栈中为b开辟空间。而堆(heap)需要程序员自己申请,并指明大小。有人用这样一个比喻来解释堆和栈的区别,非常形象贴切:使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大,这个人真是太有才了。下面我来写一个堆的代码,这部分代码是节选的,并不完全,功能是通过xmodem协议接收数据,并将其内容放到堆里面。如下所示
02 | * === FUNCTION ================================================== |
05 | * ================================================================= |
09 | char *ram = (char *)malloc ( sizeof(char)* 500000 ); |
12 | fprintf ( stderr, "\ndynamic memory allocation failed\n" ); |
18 | /*------------------- FLASH -----------------------------*/ |
23 | printf("ram_cnt:%d\n",ram_cnt); |
24 | parse_srecord_buf(ram,ram_cnt); |
25 | printf("successful!"); |
看了上面的代码大家应该了解了堆的用法了吧,它是通过malloc向系统中申请空间的。申请成功以后,就会返回申请地址的首地址,失败则返回NULL。到底申请在什么地方,我们可以通过打印指针来得知,但并没这个必要,因为这些都是系统来处理的,我们得到了首地址然后用就可以了。需要注意一点,我们申请完的地址用完以后需要释放,用free来释放就可以了。如果不释放,可能会出现内存泄露问题,到时候麻烦就大了,具体大到什么程度我也不知道,呵呵。
可能有人会问,为什么不用栈来处理这个问题呢?这就跟编译有关系了,在编译过程中,系统会将栈需要的空间加到代码中,也就是说如果你在代码中用栈来处理大的数据,那么你编译以后的代码会非常大,你下载到flash以后,加载到sdram中的时间也会非常之长。而堆这不会,系统对堆的处理方式是何时用合适分配,并不占代码空间。
说到这,有关SDRAM部分的内容讲完了。总结一下,使用SDRAM有两种方法,第一种是直接对SDRAM地址处理;第二种方法就是利用堆来处理。好了,这部分内容就讲到这吧,如果大家对此有疑问,或者发现我讲的内容有问题可以直接跟我联系,邮箱:;qq:984597569。
阅读(927) | 评论(0) | 转发(0) |