1. 程式人生 > >嵌入式 Linux應用程式如何讀取(修改)晶片暫存器的值

嵌入式 Linux應用程式如何讀取(修改)晶片暫存器的值

這一問題來自專案中一個實際的需求:
我需要在Linux啟動之後,確認我指定的晶片暫存器是否與我在uboot的配置一致。

舉個例子:
暫存器地址:0x20000010負責對DDR2的時序配置,該暫存器是在uboot中設定,現在我想在Linux執行後,讀出改暫存器的值,再來檢查該暫存器是否與uboot的配置一致。

Linux應用程式執行的是虛擬空間,有沒有什麼機制可以是完成我提到的這一需求。若行,還請附些測試程式碼。
謝謝!

這個需要用mmap()函式將暫存器實體地址對映為使用者空間的虛擬地址,即將暫存器的那段記憶體對映到使用者空間,函式介紹如下:

  1. void*mmap(void* addr, size_t len
    , intprot,int flags, intfd, off_t offset);

該函式對映檔案描述符 fd 指定檔案的 [offset, offset + len] 實體記憶體區至呼叫程序的 [addr,addr + len]的使用者空間虛擬記憶體區,通常用於記憶體共享或者使用者空間程式控制硬體裝置,函式的返回值為最後檔案對映到使用者空間的地址,程序可直接操作該地址。下面是測試程式碼(僅供參考):

  1. #define DDR2_REG_BASE (0x20000000)
  2. #define MAP_SIZE4096UL
  3. #define MAP_MASK(MAP_SIZE- 1)
  4. static unsignedint
    pTestRegBase;
  5. static intdev_fd;
  6. dev_fd = open("/dev/mem",O_RDWR |O_NDELAY);
  7. if (dev_fd <</SPAN> 0) {
  8. LOGE("open(/dev/mem) failed.");
  9. return;
  10. }
  11. pTestRegBase = (void*)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, DDR2_REG_BASE &~MAP_MASK);
  12. if (MAP_FAILED == pTestRegBase) {
  13. printf("mmap failed.fd(%d), addr(0x%x), size(%d)\n"
    , dev_fd, DDR2_REG_BASE, MAP_SIZE);
  14. } else{
  15. unsigned intreg_value =*((volatile unsignedint *)(pTestRegBase + 10));
  16. printf("reg_value =0xx\n", reg_value);
  17. munmap((void*)pTestRegBase, MAP_SIZE);
  18. }
  19. pTestRegBase = 0;
  20. if(dev_fd)
  21. close(dev_fd);

這裡將DDR2_REG_BASE開始大小為1個page的實體地址對映到了使用者空間,然後就可以用pTestRegBase作為起始地址操作暫存器了。

  • 0支援 贊一個!可以看到我的開發板指定位置暫存器的值了。
    追問一下:
    我在我ubuntu主機(intel x86)上使用執行你給程式碼,會出現錯誤:
    [email protected]:~/program/c$ sudo ./a.out
    mmap failed. fd(3), addr(0x20000000), size(4096)
    但將15行的程式修改為:
    pTestRegBase = (void *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,MAP_SHARED, dev_fd, 0);
    執行時正常,這裡問題出再哪裡呢?是不是因為0x20000000~0x20000000+4096在ubuntu的機器上沒有地址對映的緣故呢?
  • 0支援 @ajaxhex86架構暫存器地址我不怎麼清楚,像arm架構的處理器暫存器一般都是在高階地址如0xF0000000以上,你可以在程式中把errno值打印出來看看是什麼原因引起的。

1、首先寫一個核心模組,在該核心模組中設定一個變數,用來儲存該暫存器的值。
2、在核心模組中建立一個對應的proc,用來向用戶空間輸出該暫存器的值。
3、在使用者空間直接cat之前建立的proc檔案。

需要以核心模組的方式執行

暈,不說詳細點,就扣分阿....

寫個核心模組
使用ioremap()
對映到user地址空間

看看這裡的咚咚

asm/io.h

寫個驅動,在驅動裡面去讀你的暫存器就可以了。
這裡有個例項,你可以下載試試:read_register_kmod.tar(下載地址:http://sdrv.ms/ZM8gFi)。

相關推薦

嵌入式 Linux應用程式如何讀取(修改)晶片

這一問題來自專案中一個實際的需求: 我需要在Linux啟動之後,確認我指定的晶片暫存器是否與我在uboot的配置一致。 舉個例子: 暫存器地址:0x20000010負責對DDR2的時序配置,該暫存器是在uboot中設定,現在我想在Linux執行後,讀出改暫存器的值,再來檢查該暫存器是否與uboot的配置一致

嵌入式Linux應用程式開發——多執行緒4(執行緒的同步——訊號量)

#include <pthread.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <semaphore.h> int

嵌入式初學者學習嵌入式必看必看書籍列表,有電子檔的同學可以共享出來,謝謝 Linux基礎 1、《Linux與Unix Shell 程式設計指南》 2、《嵌入式Linux應用程式開發詳解》

嵌入式初學者參考書目 無論學習哪方面的程式設計,都需要掌握基礎知識和程式語言,其中《深入理解計算機作業系統》是比較重要的。下面是一些計算機關於嵌入式方面的推薦,有些是借鑑他人的歸納。 Linux基礎 1、《Linux與Unix Shell 程式設計指南》 2、《嵌入式Linux應用程式開發詳

嵌入式linux應用程式開發完全手冊》NAND FLASH硬體程式設計學習筆記

1.先看一下Flash的引腳圖,它與S3C2440連線比較少(相對nor flash),地址資料和命令都是在如圖示的一些使能訊號的配合下,通過8個I/O引腳傳輸。寫地址,資料,命令時,nCE,nWE訊號

利用Eclipse和Sourcery G++ Lite通過GDBserver在Windows下單步除錯嵌入式Linux應用程式

我的開發平臺: 上位機:WIN7 32bit Home basic 下位機:AM3517, Linux 2.6.37  需要用的軟體資源: 1.      arm-2012.09-64-arm-none-linux-gnueabi.exe  (sourcery G++ L

基於ARM的嵌入式Linux應用程式開發

0 引 言   當今社會,嵌入式系統已經滲透到人們工作、生活中的各個領域,嵌入式處理器已佔分散處理器市場份額的94%。而嵌入式Linux系統也蓬勃發展,不僅繼承了Linux原始碼開放、核心穩定高效、軟體豐富等優勢,還具備支援廣泛處理器結構和硬體平臺、佔有空間小、成本低廉、結構緊湊等特點。 1 ARM處理

linux驅動中讀寫硬體(例如__raw_writel)

   __iomem原始碼位置:include/linux/compiler.h # define __force    __attribute__((force)) //變數可以進行強制轉換 # define __nocast &

mt6328晶片介面函式資料介紹

目前mt6735平臺,使用pMIC為MT6328。 MT6328提供的函式介面與之前MT6323和MT6325等相比,介面函式做了較大調整。具體檔案參考: upmu_common.c檔案。 在MT6323或MT6325相關檔案中,提供如下形式的介面函式: void upm

《ServerSuperIO Designer IDE使用教程》-3.Modbus協議,讀取多個,實現多種資料型別解析。釋出:v4.2.2版本

更新內容,v4.2.2版本:1.增加Modbus協議讀取多個暫存器,並且按多種資料型別解析資料。2.Modbus Serial和Modbus TCP兩個驅動合併成一個驅動。3.修改資料庫結構,儲存配置資訊。4.優化ServerSuperIO核心程式碼,應用過程中的潛在問題。 v4.2.2 下載地址:官方

Linux核心——cli()和sti()——標誌的中斷標誌

cli()和sti()有點類似於彙編指令中的CLI和STL,當某個任務在執行的過程中不想被中斷,則可以在任務的開始出執行cli(),在任務的結束處執行sti(),恢復中斷的執行。 為了避免競爭條件和中斷對臨界程式碼區的干擾,在Linux 0.12核心程式碼中許多地方使用

組合語言: 試編制一個程式,把BX內的二進位制數以十六進位制數的形式在螢幕上顯示出來

試編制一個程式,把BX暫存器內的二進位制數以十六進位制數的形式在螢幕上顯示出 來。 2017年5月29日15:47:49 data segment N dw 01111111

保護模式下的段轉化為線性地址過程

關鍵字: 段暫存器、段選擇子、全域性描述符表、區域性描述符表、段描述符、線性地址;     保護模式下使用段機制的CS,SS,DS,ESt,FS,GS儲存的並不是真實模式下的段地址,而是一個包含了段選擇子和偏移地址的組合值。CPU在讀取記憶體的時候,需要將段暫存器的值解析

用visual studio 2005開發嵌入式wince應用程式需要以下開發環境

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

嵌入式Linux應用開發完全手冊(二)GPIO

5 GPIO介面 5.1 GPIO硬體介面介紹 GPIO General Purpose I/O Port,通用輸入、輸出埠。簡單說就是這個埠可以配成輸入的(讀電平訊號),也可以配成輸出的(設定電平訊號) 無論是輸入還是輸出都是通過暫存器來實現的

嵌入式Linux應用開發完全手冊(一)嵌入式Linux基礎知識

嵌入式Linux應用開發完全手冊 3 嵌入式Linux基礎知識 3.1 交叉編譯工具 編譯工具鏈,編譯工作由幾個步驟完成,分別用到了不同的工具 PC端應用 gcc ld objcopy

嵌入式Linux應用開發完全手冊(四)UART

11. 通用非同步收發器 UART 11.1 UART原理,部件使用方法 11.1.1UART原理 UART是Universal Asynchronous Receiver Transmitter的縮寫,即通用非同步收發器 UART用來傳輸序列資料: - 傳送時,CPU將

嵌入式Linux應用開發完全手冊(三)中斷

9 中斷體系結構 9.1 ARM中斷體系 ARM CPU工作模式和狀態 工作模式,7種,1種使用者模式,其他6選中特權模式 usr 使用者模式,ARM處理器正常的工作模式 fiq 快速中斷模式,高速資料傳輸或者通道處理 irq

嵌入式linux應用開發完全手冊(二) 第六章 儲存控制器

第二篇 ARM9 嵌入式系統基礎例項篇 第五章 GPIO介面 5.1 GPIO硬體介紹 GPIO(General Purpose I/O Ports)意思為通用輸入/輸出埠,通俗的說,就是一些引腳,可以通過它們輸出高低電平或者通過它們讀入引腳的狀態——是高電平還是低電平。 5.1.1 通

嵌入式linux應用開發完全手冊(一)

第一篇 嵌入式Linux開發環境構建 1.1.2 嵌入式發展 SCM(Single Chip Microcomputer)微控制器; MCU(Micro Controller Unit)微控制器; SoC(System on a Chip):系統級晶片,在一個晶片上由於廣泛使用

Linux應用程式錯誤使用pthread_mutex_lock互斥鎖觸發SIG_ABRT訊號的原因分析

在進行程式開發過程中,錯誤使用了pthread_mutex_lock導致程式概率性的奔潰,奔潰時報如下錯誤: 問題分析: 本文分析在Linux應用程式中錯誤使用pthread_mutex鎖時會概率性觸發SIG_ABRT訊號而導致程式崩潰(庫列印輸出 :Assertion `mutex-