C C 有意思的指標(4)

2021-10-24 20:05:31 字數 1520 閱讀 4817

指標可以讓我們申請記憶體空間,並使用指標讀寫指定的記憶體區域。但還有另外一種情況,我們想把資料放到指定的記憶體區域,或說在某些暫存器與記憶體統一編址的平台,想要訪問某段暫存器,並更改暫存器的值。

通過檢視晶元手冊,知道裝置暫存器位址,然後通過把位址值轉換成指針對這段暫存器記憶體進行讀寫。

我們通過取位址符(&)來獲得記憶體位址,同理也可以知道指定記憶體位址值,把位址值轉換成指標。

外裝置控制暫存器,在驅動編寫時常需要根據需對外設進行設定,這就需要配置外設的功能控制暫存器來實現。所謂功能控制暫存器,就是為了實現某些功能,需要很多配置選項來支援功能的多樣性,功能越少,控制器越簡單。比如簡單的io埠控制器,只是需要配置 io埠的模式、速度、驅動強度、復用等幾項。更複雜的功能比如lcd顯示裝置外設可能控制器就很複雜,需要配置很多的暫存器來實現這些各種顯示功能。

某晶元gpio埠暫存器配置位址圖

以上是晶元gpio埠復用暫存器位址段

具體gpio埠復用控制暫存器某些位的功能配置

從紅色標註可以看到,這是乙個以0x2e00_0000為基位址段的記憶體空間。對基位址進行偏移(60h)從而讀寫具體的gpio埠復用控制暫存器。這個與定義結構然後進行偏移讀寫變數是乙個操作原理。

具體操作:

把 address: 20e_0000h base + 60h offset = 20e_0060h 由於這個控制暫存器為4位元組所以直接轉換成int型別指標是變好的,int* p = (int*)20e_0060h,後面再使用位操作配置暫存器各個位(常使用讀-改-寫方式)。

所以我們經常會在uboot啟動**或其它底層暫存器操作驅動中有把暫存器值進巨集定義等式如

/* 定義暫存器位址巨集 */

define gpio_io01_md 20e_0060h

define gpio_io02_md 20e_0064h

/* 定義暫存器位址轉成指標,並解引用獲得記憶體空間 */

#define __reg(x) (*((volatile u32 *)(x)))

#define __reg16(x) (*((volatile u16 *)(x)))

#define __reg8(x) (*((volatile u8 *)(x)))

/* 對暫存器記憶體空間進行賦值 */

__reg

(gpio_io01_md)

=0xf

;

只為理解指標進行的乙個流程演示,具體晶元暫存器配置試依各晶元廠商提供的巨集或函式來實現。

所以如果我們知道乙個記憶體位址,那麼通過把它轉換成合適的指標型別,就可以通過這個指針對這段記憶體空間進行讀寫操作。

也就是說如果我們知道記憶體的某個很大記憶體空間沒有人使用,那麼我們完全可以把它轉成指標,然後想怎麼玩怎麼樣,但很容易出問題就是哈哈。

C C 有意思的指標(1)

在c c 中指標是乙個常用的型別,但同時指標也是乙個重要且有意思的概念。這個概念說大了與量子糾纏什麼還能聯絡在一起,也可以與宇宙空間聯絡起來。而我更喜歡它另外乙個角度的理解 玄幻 裡男主角的空間戒指。記得以前看玄幻類 時常羨慕男主角的空間儲物戒指,想放什麼就放什麼,還可以在信物戒指裡面住,甚至生活都...

C C 有意思的指標(2)

普通變數的定義與使用不存在很大的區別,定義了直接使用即可。但指標的定義與使用是需要作區分的。int p nullptr 定義時 指記憶體位址,或說指向的記憶體區域首位址 cout p endl 指標使用時 是指對p存放的位址解引用,按p的資料型別讀取記憶體資料。這對指標型別作解析 int 型別中的 ...

有意思的話

1 要麼忍,要麼殘忍 2 下輩子我要做你的一顆牙,至少,我難受,你也會疼 3 心不動,則不痛 4 我們唯一的關係是沒有關係。5 你會流淚,並不代表真的慈悲 我會微笑,並不代表一切都好。6 孤單 是 你心裡面沒有人 寂寞 是 你心裡有的人卻不在身邊 7 冬天裡你給了我乙個夏天的夢 卻把我在春天叫醒了 ...