2013年9月28日 星期六

[U-boot] analysis md for disscuss volatile and pointer

健忘如我,只好常常記錄讀過的東西來加深印象。
本記錄藉由 md (memory display) 來探討 volatile 以及 pointer 間接取值

我們在使用md時,實際上是呼叫do_mem_md函式。

在 do_mem_md 函式中 有三個case最後都會call print_buffer(... 秀出資料
1. print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
2. print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
3. print_buffer(addr, (void*)addr, size, length, DISP_LINE_LEN/size);
這裡以case 3 來作探討: 要印的資料就是addr的內容,在此只說明如何印出一筆資料。

先來看看print_buffer的宣告
int print_buffer (ulong addr, void* data, uint width, uint count, uint linelen);

就是因為函式的data參數型態為void*,因此須要先將addr轉換為void*的型態。

在print_buffer中和data相關的說明擷取如下

uint32_t x;
/* Copy from memory into linebuf and print hex values */
x = lb.ui[i] = *(volatile uint32_t *)data;
printf(" %0*x", width * 2, x);

由於傳入的實際上是記憶體中的位址addr,而要印的資料型態為uint32_t,因此要先做轉型 (uint32_t *) 至於volatile  稍後會說明。 再藉由間接取值的方式將記憶體內容assign給 x 作輸出。

再來說明volatile,網路上已經很多優秀的說明,這邊列出我覺得不錯的一個連結
http://blog.csdn.net/c_bg44/article/details/1538235

用volatile 的變數每次被呼叫使用時,會從ram中取值。
而沒有使用volatile的變數有可能從cpu register中取值,這是因為此變數之前有被呼叫使用過。(編譯器優化程式碼的結果,因為從cpu register取值比ram快多了)

因此若想要確保每次的取值都是乖乖從ram拿出來就要加上volatile。







沒有留言:

張貼留言