【連載】【FPGA黑金開發板】NIOS II那些事兒–SDRAM實驗(十二)

來源:互聯網
上載者:User
聲明:本文為原創作品,著作權歸本博文作者 所有,如需轉載,請註明出處 http://www.cnblogs.com/kingst/

一、簡介

      這一節,我們來聊聊SDRAM吧。作為NIOS系統中最重要的一個外部器件,它擔任著重要的角色,大家對它也應該很熟悉。每次上電的時候,FPGA都會把FLASH中的程式送到SDRAM中運行,之所以這樣來做就是因為它的速度很快,但它掉電是要遺失資料的,所以要把資料存到FLASH中。

      有關SDRAM的理論知識我在這裡不說了,不知道的百度google一下都可以。其實在NIOS II開發過程中,就算你對SDRAM的理論知識不瞭解,也不耽誤你對它的使用。SOPC builder都已經完美的將它驅動起來,我們只要知道怎麼使用它就可以了。下面,我們就來講講他的使用方法,其實真的很簡單。

      在我們講第一節的時候,我們就已經講了如何構建SDRAM的控制器了,我在這裡不再重複了,假設你已經構建好了,我主要講一下有關軟體的部分。

二、軟體開發

      首先開啟NIOS II 9.0 IDE軟體,開啟後,我們來看看system.h檔案,確定一下SDRAM控制器模組是否已經加入進來。如果加入,有下面的內容出現

#define SDRAM_NAME "/dev/sdram"#define SDRAM_TYPE "altera_avalon_new_sdram_controller"#define SDRAM_BASE 0x01000000…… 

接下來,我們開始編寫有關SDRAM的軟體代碼,代碼很簡單,如下所示

/* * ==================================================================*       Filename:  main.c*    Description:  SDRAM讀寫實驗 *        Version:  1.0.0 *        Created:  2010.4.16 *       Revision:  none *       Compiler:  Nios II 9.0 IDE *         Author:  馬瑞 (AVIC) *          Email:  avic633@gmail.com   * ================================================================= *//*---------------------------------------------------------------- * Include  *----------------------------------------------------------------*/#include <stdio.h>#include "../inc/sopc.h"#include "system.h"#include "string.h"/*--------------------------------------------------------------- *  Variable *---------------------------------------------------------------*/unsigned short * ram = (unsigned short *)(SDRAM_BASE+0x10000); //SDRAM地址/*  * ===  FUNCTION  =================================================== *         Name:  main *  Description:  函數主程式 * ================================================================= */int main(void){    int i;        memset(ram,0,100);    //向ram中寫資料,當ram寫完以後,ram的地址已經變為(SDRAM_BASE+0x10100)    for(i=0;i<100;i++){        *(ram++) = i;    }    //逆向讀取ram中的資料    for(i=0;i<100;i++){        printf("%d\n",*(--ram));    }           return 0;}

      程式很簡單,就是向指定的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協議接收資料,並將其內容放到堆裡面。如下所示

/*  * ===  FUNCTION  ================================================== *         Name:  main *  Description:  主函數 * ================================================================= */int main(){        char *ram = (char *)malloc ( sizeof(char)* 500000 );    if ( ram==NULL ) {        fprintf ( stderr, "\ndynamic memory allocation failed\n" );        exit (EXIT_FAILURE);    }            uart.init();        /*------------------- FLASH -----------------------------*/        while(1){        if(uart.mode_flag){             xmodem.xmodem_rx();            printf("ram_cnt:%d\n",ram_cnt);            parse_srecord_buf(ram,ram_cnt);            printf("successful!");            ram_cnt = 0;            uart.mode_flag = 0;        }                            }    free (ram);            return 0;}

      看了上面的代碼大家應該瞭解了堆的用法了吧,它是通過malloc向系統中申請空間的。申請成功以後,就會返回申請地址的首地址,失敗則返回NULL。到底申請在什麼地方,我們可以通過列印指標來得知,但並沒這個必要,因為這些都是系統來處理的,我們得到了首地址然後用就可以了。需要注意一點,我們申請完的地址用完以後需要釋放,用free來釋放就可以了。如果不釋放,可能會出現記憶體泄露問題,到時候麻煩就大了,具體大到什麼程度我也不知道,呵呵。

      可能有人會問,為什麼不用棧來處理這個問題呢?這就跟編譯有關係了,在編譯過程中,系統會將棧需要的空間加到代碼中,也就是說如果你在代碼中用棧來處理大的資料,那麼你編譯以後的代碼會非常大,你下載到flash以後,載入到sdram中的時間也會非常之長。而堆這不會,系統對堆的處理方式是何時用合適分配,並不佔代碼空間。

      說到這,有關SDRAM部分的內容講完了。總結一下,使用SDRAM有兩種方法,第一種是直接對SDRAM地址處理;第二種方法就是利用堆來處理。好了,這部分內容就講到這吧,如果大家對此有疑問,或者發現我講的內容有問題可以直接跟我聯絡,郵箱:avic633@gmail.com;qq:984597569。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.