<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux系統下對硬件寄存器調試的應用設計研究

麥克泰技術 ? 來源:嵌入式系統專家之聲 ? 2024-03-12 13:59 ? 次閱讀

0 引言

嵌入式系統廣泛應用于生活中的各行各業,嵌入式硬件復雜度也在不斷增加,嵌入式系統開發與維護變得越來越復雜,然而嵌入式系統的開發與維護工具發展相對很滯后。為了提高嵌入式系統開發與維護的效率,發展嵌入式開發與維護工具是非常重要的。通過基于 Qt 平臺開發各種開發維護工具,實現嵌入式開發與維護的平臺化,是當前嵌入式開發和維護的趨勢[1-2]。當一款新的設備出廠之后,后期維護成了人們越來越關注的問題,為了延長設備使用周期,節約生產成本,使設備創造更大的價值,設備的操作與維護越來越受到人們的重視。

每當設備出現問題之后,就會調試底層驅動,這時可能需要調整寄存器的設置。面對這個問題,當前國內外開發與維護人員的通常做法是直接在程序里面修改硬件寄存器的數據,然后重新編譯程序,下載到設備,以此來檢驗設備運行情況[3-4]。但是這種方法比較麻煩,效率低下,不利于維護。為了提高開發人員開發和維護設備的效率,需要設計一個可視化工具,從而可以直接方便地對硬件內部寄存器進行修改與調試。這個工具擁有圖形化界面,可以直接讀寫下位機硬件寄存器的數值,首先輸入硬件寄存器要傳入的物理地址(這個物理地址可以通過芯片手冊確定,在驅動程序里面要通過映射為虛擬地址才能使用),然后根據要求來讀寫下位機任意硬件寄存器的數值。

1 系統設計框架

該系統采用嵌入式Linux操作系統作為開發的核心,包括三部分,分別為客戶端圖形化界面、服務器端和硬件設備??蛻舳擞脕砼c用戶進行交互,如輸入下位機硬件寄存器地址和數據,服務器端用來接收上位機客戶端用戶傳來的數據或者向客戶端發送數據,底層驅動用來操作硬件設備內部寄存器的數值。本系統采用Linux 網絡通信的方式連接上位機和下位機,使交互更加方便和高效。整個系統框架如圖1所示。

a3800a6a-e023-11ee-a297-92fbcf53809c.png

圖1系統框架

2 Linux 網絡通信設計

該網絡通信系統包括服務器端和客戶端兩個部分。服務器端實現對數據的采集和發送,以及通過TCP協議進行網絡傳輸;客戶端主要是接收服務器傳輸過來的數據并進行圖形化顯示。服務器端和客戶端使用 TCP協議進行網絡通信的具體流程圖如圖2所示。

a3b41b84-e023-11ee-a297-92fbcf53809c.png

圖2TCP網絡通信流程圖

客戶端和服務器端的交互過程如下:服務器端先初始化socket,分配文件描述符;然后調用bind() 將套接字與本地IP地址和端口綁定;接著調用listen()對端口進行監聽,并設置監聽隊列的大??;繼續調用accept()阻塞,等待客戶端連接[5]。如果有客戶端初始化一個socket()后調用connect()向服務器端發送連接請求,若經過三次握手,則連接成功,這時客戶端與服務器端的連接就建立了??蛻舳税l送數據請求,服務器端接收請求并處理請求,然后把回應數據發送給客戶端,客戶端讀取數據,最后調用close() 關閉連接,一次交互結束。

2.1服務器端設計

服務器端通過三次握手與客戶端建立連接之后,將驅動端映射到內核空間的數據讀取出來并且發送到客戶端,或者將客戶端要發送的數據接收到服務器端并發送給驅動端。

下位機服務器端的部分程序如下:

while(1){

//服務器阻塞,直到獲得連接請求并建立連接

int socklis=accept(sock,(struct sockaddr *)&.clientAddr,

&.len);

if(socklis<0){

perror("accept")

exit(1);

}

While(1){// 清空數組

memset(buff,0,1024);

//從客戶端接收數據

n=recv(socklis,buff,1024,0);

if(n<0){

perror("recv");

return—1

}

msgtype=*(unsigned int *)buff;

switch(msgtype){

case REGISTER_CTRL:{

structregister_ctrlregmsg;

structregister_info reg;

//內存拷貝

memcpy(&.regmsg,buff,sizeof(regmsg));

reg.addr=regmsg.addr;

reg.data=regmsg.data;

if(regmsg.cmd==1){

ioctl(fd_reg,REG_READ,);

printf("read reg:addr=%#x,data=%#x ",reg.

addr,reg.data);

//發送數據到客戶端

send(socklis,&.reg,sizeof(reg),0);

}else if(regmsg.cmd==0){

printf("write reg:addr=%#x,data =%#x ",reg.addr,

reg.data);

ioctl(fd_reg,REG_WRITE,&.reg);

}

break;

}

}

}

}

2.2客戶端設計

為了滿足人性化要求,本文設計了一個Qt客戶端圖形化界面,從而方便用戶操作和讀寫數據。Qt是一個跨平臺的C++圖形用戶界面應用程序框架,由挪威Troll- Tech公司出品,目前包括 QtCreator、Qt Embedded、Qt Designer等快速開發工具[6]。其中 Qt Creator是一個全新的、完整的、輕量級的圖形開發平臺,它可以按照設計人員的意愿建立圖形用戶界面,隨時進行顯示和修改,具有良好的適應性,保證了不同平臺之間設計的兼容性[7]。

在客戶端圖形化界面中,首先設計一個“寄存器地址”輸入框,用來輸入用戶需要操作的下位機寄存器物理地址;然后設計一個“寄存器數據”輸入框,用來顯示從下位機讀取的存儲在該寄存器里面的數據,或者向下位機發送用戶需要寫入到該寄存器中的數據;接著在旁邊設計一個“讀”數據復選框和一個“寫”數據復選框,用來發送“讀”或者“寫”命令;最后在界面下端設計一個“確定”按鈕,來確認需要執行的操作。Qt圖形化界面如圖3所示。該界面清晰明確、步驟簡單、操作方便、簡潔高效,大大縮短了用戶查看和編輯下位機設備硬件寄存器中數據的時間,提高了用戶調試和維護設備的效率。

a3d72fac-e023-11ee-a297-92fbcf53809c.png

圖3Qt圖形化界面

在Qt中通過使用Linux系統調用中的 TCP協議實現客戶端與服務器端的連接,并進行數據讀取、發送以及顯示,按下“確定”按鈕,建立網絡通信,開始進行數據的讀取、發送和顯示。

上位機客戶端部分應用程序如下:

void MainWindow::on_send_clicked(){

struetregister_ctrlreg;

structregister_inforeg_rsp;

reg.msgtype=REGISTERCTRL;

reg.addr=ui->addr->text().toUInt(NULL,16);

reg.data=ui->data->text().toUInt(NULL,16);

if(ui->read->isChecked()){

reg.cmd=1;

qDebug("read");

}

if(ui->write->isChecked()){

reg.cmd=0;

qDebug("write");

}

//發送數據到服務器端

send(m_fd_client,&.reg,sizeof(reg),0);

if(reg.cmd ==1){

//從服務器端接收數據

recv(m_fd_client,&.reg_rsp,sizeof(reg_rsp),0);

ui->data->setText(QString::number(reg_rsp.data,

16)):

}

}

3 底層驅動端設計

系統在運行時,外設的I/O內存資源的物理地址是已知的,由硬件設計決定,但是 CPU 通常并沒有為這些已知的外設I/O內存資源物理地址預定義虛擬地址范圍,驅動程序并不能直接通過物理地址訪問I/O內存資源,而必須將它們映射到核心虛地址空間內(通過頁表),然后根據映射所得到的核心虛擬地址范圍通過訪內指令訪問這些I/O內存資源[8]。

嵌入式處理器訪問外設都是以地址指針的形式訪問,也就是說要想訪問外設,必須知道這個外設的物理地址。在Linux系統中,不管是在用戶空間還是內核空間,一律不允許直接訪問外設的物理地址,要想訪問需要提前將物理地址映射到內核虛擬地址或者用戶虛擬地址上,將來程序訪問用戶虛擬地址或者內核虛擬地址就是在訪問物理地址[9]。將Linux系統4G虛擬地址空間劃分如下,用戶虛擬地址為0x00000000~0xBFFF FFFF(0G~3G),內核虛擬地址為0xC0000000~0xFFFF FFFF(3G~4G)[10]。一個物理地址可以有多個虛擬地址,一個虛擬地址不能對應多個物理地址。如果要將物理地址映射到內核虛擬地址上,可以使用ioremap()函數;若要解除地址映射,可以使用iounmap() 函數。Linux地址映射機制如圖4所示。

a3eda43a-e023-11ee-a297-92fbcf53809c.png

圖4Linux 地址映射機制

驅動端部分程序如下:

staticlongreg_ioctl(structfile*file,unsignedintemd,unsigneclongarg){

//定義內核緩沖區

structreg_infokreg;

unsignedlong*gpiobase;

//拷貝用戶緩沖區到內核

copy_to_user((structreg_info *)arg,&kreg,sizeof

(kreg));

//將外設的物理地址映射到內核虛擬地址上

gpiobase=ioremap(kreg.addr,4);

//解析命令,操作硬件

switch(cmd){

case REG_READ:

kreg.data=*gpiobase;

copy_to_user((structreg_info *)arg,&kreg,sizeof

(kreg));

break;

case REG_WRITE:

*gpiobase=kreg.data;

break;

}

//解除地址映射

iounmap(gpiobase);

return0;

}

4 實驗結果

本系統使用基于Cortex-A53架構處理器的S5P6818開發板上面的點陣LED燈來驗證實驗結果。首先在下位機運行Linux系統,點亮第一個LED燈,將第二個和第三個LED燈關閉。然后查看芯片手冊,將物理地址為0xC001C000的32位寄存器的bit[12]、設為低電平,bit[11]和bit[7]設為高電平。對此,向該寄存器寫入數據0x880,并選中右邊的“寫”復選框,點擊“確認”按鈕(如圖5所示)后,發現開發板第一個LED燈被點亮,驗證成立,如圖6所示。接著選中右邊的“讀”復選框,再次點擊“確認”按鈕,發現寄存器數據顯示為0x880(如圖7所示),因為讀取的正是剛才寫入到該寄存器的數值。

a3f863e8-e023-11ee-a297-92fbcf53809c.png

圖5向寄存器寫數據

a3fc3a86-e023-11ee-a297-92fbcf53809c.png

圖6點陣LED被點亮

a40f6f48-e023-11ee-a297-92fbcf53809c.png

圖7 從寄存器讀數據

結語

本文所設計的寄存器讀寫器工具,只需知道設備的硬件寄存器物理地址就能快速準確地讀寫任意硬件寄存器的數值,操作簡單方便,快速高效,為設備操作與維護提供了一種有效的解決方案。特別是當系統邏輯比較復雜時,圖形化界面的調試工具可以大大節省用戶發現問題的時間,能夠讓用戶方便快速地處理設備中出現的各種問題,從而更好地維護產品和設備。




審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5006

    文章

    18440

    瀏覽量

    292134
  • 寄存器
    +關注

    關注

    30

    文章

    5167

    瀏覽量

    118226
  • Linux系統
    +關注

    關注

    4

    文章

    573

    瀏覽量

    27004
  • 上位機
    +關注

    關注

    26

    文章

    906

    瀏覽量

    54270
  • TCP通信
    +關注

    關注

    0

    文章

    145

    瀏覽量

    4154

原文標題:Linux 系統下對硬件寄存器調試的應用研究

文章出處:【微信號:麥克泰技術,微信公眾號:麥克泰技術】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何根據自己設計中的寄存器配置總線定義來生成一套寄存器配置模版

    無論是FPGA還是ASIC,系統設計中總會存在配置寄存器總線的使用,我們會將各種功能、調試寄存器掛載在寄存器總線上使用。
    的頭像 發表于 03-04 13:56 ?512次閱讀
    如何根據自己設計中的<b class='flag-5'>寄存器</b>配置總線定義來生成一套<b class='flag-5'>寄存器</b>配置模版

    linux寄存器概念

    linux寄存器簡介
    發表于 05-11 14:33

    簡單研究一下Armv8-A的AArch64寄存器

    的指令系統主要是寄存器-寄存器型。說了這么多,就是想強調一在Armv8-A中寄存器的重要性。在AArch64應用級角度,一個PE(Proc
    發表于 09-20 14:54

    寄存器與移位寄存器

    寄存器與移位寄存器 寄存器是用來寄存數碼的邏輯部件,所以必須具備接收和寄存數碼的功能。任何一種觸發器都可以構成
    發表于 03-12 15:19 ?59次下載

    寄存器,寄存器是什么意思

    寄存器,寄存器是什么意思 寄存器定義  寄存器是中央處理器內的組成部分。寄存器是有限存貯容量的高速存貯部件,它們可用
    發表于 03-08 14:26 ?2.1w次閱讀

    數據寄存器,數據寄存器是什么意思

    數據寄存器,數據寄存器是什么意思 數據寄存器數據寄存器包括累加器AX、基址寄存器BX、計數寄存器
    發表于 03-08 14:38 ?1.2w次閱讀

    32位寄存器,32位寄存器是什么意思

    32位寄存器,32位寄存器是什么意思  從X8086開始學了一年,第一個ASM的程序就是變32換16進制的程序,不過現在叫我從新開始寫ASM程
    發表于 03-08 17:26 ?1.7w次閱讀

    寄存器與移位寄存器

    寄存器與移位寄存器:介紹寄存器原理和移位寄存器的原理及實現。
    發表于 05-20 11:47 ?0次下載

    微控制器的寄存器調試

      嵌入式系統的軟件調試通常側重于代碼執行、存儲器的值、堆棧指針、中斷時間和寄存器的值。在這篇文章中,我們將向你展示如何使用ARM版的IAREmbeddedWorkbench調試
    發表于 09-20 17:24 ?5次下載
    微控制器的<b class='flag-5'>寄存器</b>的<b class='flag-5'>調試</b>

    開發一個Linux調試器就必須要知道寄存器和內存!

    在我們正真的讀取寄存器前,調試器需要知道一些關于x8664架構的相關知識。包括通用寄存器,專用寄存器以及浮點寄存器和向量
    發表于 05-14 17:28 ?1389次閱讀

    新版IAR調試查看寄存器問題 STM8代碼大小優化問題

    新版IAR調試查看寄存器問題、STM8代碼大小優化問題
    的頭像 發表于 03-07 16:13 ?3452次閱讀

    深度學習_硬件知識_上拉寄存器與下拉寄存器

    上拉寄存器上拉寄存器是控制對應端口上拉使能的。當對應位為0時,設置對應引腳上拉使能,對應位為1時,禁止對應引腳上拉使能。如果上拉寄存器使能,無論引腳功能寄存器如何設置(輸入、輸出、數據
    發表于 01-14 14:31 ?10次下載
    深度學習_<b class='flag-5'>硬件</b>知識_上拉<b class='flag-5'>寄存器</b>與下拉<b class='flag-5'>寄存器</b>

    Linux應用層操作寄存器

    --- > [*] /dev/mem virtual device support Linux應用層操作寄存器 除了直接使用devmem,我們也可以在Linux應用層自己實現一個devmem
    的頭像 發表于 10-08 15:16 ?669次閱讀
    <b class='flag-5'>Linux</b>應用層操作<b class='flag-5'>寄存器</b>

    arm三個寄存器在gdb調試時的作用

    arm三個寄存器在gdb調試時作用? ARM是一種廣泛使用的微處理器架構,它廣泛應用于移動設備、嵌入式系統和其他高性能計算設備。當我們在使用gdb(GNU調試器)
    的頭像 發表于 01-31 10:44 ?366次閱讀

    AFE模擬前端寄存器讀取操作

    AFE模擬前端寄存器讀取操作是電子系統設計和調試中不可或缺的一環。寄存器作為AFE模擬前端中的重要組成部分,存儲著各種配置參數和狀態信息,通過讀取這些
    的頭像 發表于 03-15 15:50 ?254次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>