Chinaunix首页 | 论坛 | 博客
  • 博客访问: 133530
  • 博文数量: 55
  • 博客积分: 1870
  • 博客等级: 上尉
  • 技术积分: 540
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-21 20:51
文章分类

全部博文(55)

文章存档

2011年(27)

2009年(3)

2008年(25)

我的朋友

分类: C/C++

2011-05-04 13:32:06

声明:本文转载于http://www.cnblogs.com/kingst,版权归黑金动力社区(http://www.heijin.org)所有。

4

一、简介

      这一节,我们来聊聊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"
2 
3#define SDRAM_TYPE "altera_avalon_new_sdram_controller"
4 
5#define SDRAM_BASE 0x01000000
6 
7……

接下来,我们开始编写有关SDRAM的软件代码,代码很简单,如下所示

01/*
02 * ==================================================================
03*       Filename:  main.c
04*    Description:  SDRAM读写试验
05 *        Version:  1.0.0
06 *        Created:  2010.4.16
07 *       Revision:  none
08 *       Compiler:  Nios II 9.0 IDE
09 *         Author:  马瑞 (AVIC)
10 *          Email:  avic633@gmail.com 
11 * =================================================================
12 */
13 
14/*----------------------------------------------------------------
15 * Include
16 *----------------------------------------------------------------*/
17#include
18#include "../inc/sopc.h"
19#include "system.h"
20#include "string.h"
21 
22/*---------------------------------------------------------------
23 *  Variable
24 *---------------------------------------------------------------*/
25unsigned short * ram = (unsigned short *)(SDRAM_BASE+0x10000); //SDRAM地址
26 
27/*
28 * ===  FUNCTION  ===================================================
29 *         Name:  main
30 *  Description:  函数主程序
31 * =================================================================
32 */
33int main(void)
34{
35    int i;
36     
37    memset(ram,0,100);
38    //向ram中写数据,当ram写完以后,ram的地址已经变为(SDRAM_BASE+0x10100)
39    for(i=0;i<100;i++){
40        *(ram++) = i;
41    }
42 
43    //逆向读取ram中的数据
44    for(i=0;i<100;i++){
45        printf("%d\n",*(--ram));
46    }
47        
48    return 0;
49}

      程序很简单,就是向指定的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协议接收数据,并将其内容放到堆里面。如下所示

01/*
02 * ===  FUNCTION  ==================================================
03 *         Name:  main
04 *  Description:  主函数
05 * =================================================================
06 */
07int main()
08{   
09    char *ram = (char *)malloc ( sizeof(char)* 500000 );
10 
11    if ( ram==NULL ) {
12        fprintf ( stderr, "\ndynamic memory allocation failed\n" );
13        exit (EXIT_FAILURE);
14    }       
15 
16    uart.init();
17     
18    /*------------------- FLASH -----------------------------*/
19     
20    while(1){
21        if(uart.mode_flag){
22            xmodem.xmodem_rx();
23            printf("ram_cnt:%d\n",ram_cnt);
24            parse_srecord_buf(ram,ram_cnt);
25            printf("successful!");
26            ram_cnt = 0;
27            uart.mode_flag = 0;
28        }
29                         
30    }
31 
32    free (ram);
33         
34    return 0;
35}

      看了上面的代码大家应该了解了堆的用法了吧,它是通过malloc向系统中申请空间的。申请成功以后,就会返回申请地址的首地址,失败则返回NULL。到底申请在什么地方,我们可以通过打印指针来得知,但并没这个必要,因为这些都是系统来处理的,我们得到了首地址然后用就可以了。需要注意一点,我们申请完的地址用完以后需要释放,用free来释放就可以了。如果不释放,可能会出现内存泄露问题,到时候麻烦就大了,具体大到什么程度我也不知道,呵呵。

      可能有人会问,为什么不用栈来处理这个问题呢?这就跟编译有关系了,在编译过程中,系统会将栈需要的空间加到代码中,也就是说如果你在代码中用栈来处理大的数据,那么你编译以后的代码会非常大,你下载到flash以后,加载到sdram中的时间也会非常之长。而堆这不会,系统对堆的处理方式是何时用合适分配,并不占代码空间。

      说到这,有关SDRAM部分的内容讲完了。总结一下,使用SDRAM有两种方法,第一种是直接对SDRAM地址处理;第二种方法就是利用堆来处理。好了,这部分内容就讲到这吧,如果大家对此有疑问,或者发现我讲的内容有问题可以直接跟我联系,邮箱:;qq:984597569。

阅读(927) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~