1. 程式人生 > >ROM、RAM、Register(酷學玩summer STM32開發板 日記)

ROM、RAM、Register(酷學玩summer STM32開發板 日記)

     做嵌入式這一行的,和通用機程式設計師的不同在於成天不僅要和軟體打交道,還要和硬體打交道。這也是嵌入式最具魅力的地方,因為你可以完全掌握你的程式在硬體裡執行的具體情況,讓CPU 跑得更快更歡。同時,思考如何讓程式更加有效率的執行,也成為一個嵌入式工作者必須具備的素質。
      我曾參加過公司的面試,我發現來面試的很多人,會寫程式,但是卻不清楚CPU 內部構造,寫出來的
程式,自然脫離了實際,要知道,酷睿和51 的速度,是有本質區別的。要寫好嵌入式程式,就要充分了解
硬體。下面,我來講解一下嵌入式裡面最重要的三個概念:ROM、RAM 和暫存器。
     ROM又叫固化儲存器,在嵌入式裡面,其就是Flash 的代名詞,注意這裡的Flash 指CPU 內部的Flash
或者掛在資料匯流排和地址總線上的Flash,Spi Flash 是不能被包括在裡面的。ROM 有一個特點,就是其內
部的資料,是不能改變的,而且是實實在在會被CPU 執行的。我們平時說的“下載”“燒錄”,其實就是指
將我們的程式寫到ROM 中去。
       一般而言,ROM 有一個起始地址,比如0 地址,在CPU 上電啟動的時候,就會去執行0 地址裡的指
令,然後順次往後執行。除非遇到了中斷,CPU 是會一直按地址遞增的順序執行下去的。遇到中斷的時候,
CPU 就會跳到ROM 裡面的指定地址去執行指令。這個“指定地址”又叫中斷向量表。不管是起始地址還
是向量表,在CPU 的晶片手冊裡都是會提到的,不過萬變不離其宗。
        這裡大家應該就能明白了,如果我們在程式中寫上一句a=b+c,首先,這句話會被編譯器轉換成彙編,
然後又由彙編得到CPU 能看懂的0101 機器碼(又稱指令),從而得到一個BIN 檔案,這個BIN 檔案燒寫
到ROM 裡面,就可以被CPU 按照前面說的原則執行了。
RAM又叫掉電易失儲存器,在嵌入式裡面,其實就是記憶體的代名詞。這種器件,不像ROM 可以永遠
儲存資料,RAM 一旦斷電,裡面的資料就會失效。但是RAM 最大的優點,就是速度很快,不管讀或者寫,
速度都遠遠快於ROM。於是,在我們CPU 執行程式的時候,RAM 就用來存放變數,比如上面提到的a=b+c
中的a、b、c 三個變數,就是存放到RAM 裡面的。

        在寫程式的時候,知道了這些,我們就應該根據實際情況來決定程式如何寫。比如,在定義一個變數

時,如果這個變數定義好初值後就不會被改變,我們就應該在其前面加上const 關鍵字,這個關鍵字一旦放
在一個變數前面,就表示這個變數就是常量(如圖片陣列),不會被程式改變,而編譯時,就會將這個變數
變成BIN 的一部分,固化到ROM 裡面去。這樣做,可以大大節省RAM。
        Register 也是一個嵌入式系統裡面很重要的一部分,暫存器分兩種,一種叫工作暫存器。工作暫存器其
實和RAM 很像,也是可以隨時改變的,也是掉電就失效,但是因為工作暫存器一般在CPU 內部,所以其
讀寫速度比RAM 更快。工作暫存器,在實際執行時,會被用來存放一些變數(如地址值),用來進行一些
資料交換等等。另外一種,叫功能暫存器,功能暫存器在CPU 內部有很多,基本每個模組都有多個功能寄
存器,功能暫存器的作用只有一個,就是決定CPU 某個功能的屬性。比如,CPU 內部一般有一箇中斷功能
暫存器,裡面的某些位置1 後,某些中斷就不響應了。又比如,CPU 內部一般有個狀態暫存器,用來存放
當前CPU 的狀態,程式可以藉此讀出CPU 的執行狀態。功能暫存器根據實際情況,可讀可寫。
        不管是ROM、RAM 和暫存器,在CPU 內部都是有地址的,根據哈佛匯流排和馮諾依曼匯流排的不同,他
們都有著自己唯一的地址,一般ROM 和RAM 大家不需要思考地址這個問題,因為對ROM 和RAM 的直
接訪問,基本都是靠變數名來代替地址了。但是暫存器卻不同。
        要訪問暫存器,必須用指標的方式,下面摘取一部分程式碼片段:


        可以看到,我們定義了一個巨集CPU_REG_NVIC_NVIC,這個巨集代替的語句是(*((volatile CPU_INT32U
*)(0xE000E004)))。這一句語句,首先將0xE000E004 這個數進行強制型別轉換成了volatile CPU_INT32U *,
即表示這是一個地址,然後用指標符*來獲取這個地址的內容。所以,我們在想要讀或者寫這個暫存器時,
只需要把這個巨集當作一個變數那樣操作即可。
      這裡要注意的是volatile 這個關鍵字,這個關鍵字是要告訴編譯器,這個變數是一個可能會自己改變的
變數(CPU 會自己改變某些暫存器的值),讓編譯器不要對其做優化,否則會造成不可預料的後果。所以,
如果我們要定義一個暫存器時,一定要加這個關鍵字。
     上面針對ROM、RAM 和暫存器的這些小知識,很少有書會系統的提到,但是在嵌入式這行卻是很重
要的知識,基本每個人去面試相關工作時都會被問到,所以希望大家能好好了解。