RVOS-2.基于NS16550a ,為os添加終端交互功能。

2.1 實驗目的

為os添加uart功能,通過串口實現開發板與PC交互。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

2.1 硬件信息

QEMU虛擬SoC含有 虛擬NS16550A設備 。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

不同的地址線組合(A2、A1、A0)對應的讀寫模式和寄存器如下所示:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

2.2 NS16550a 的初始化

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

線路控制寄存器(LCR)中的bit7位來實現復用DLL、DLM兩個寄存器拼起來作為16位波特率寄存器。當bit7位被設置為1時,地址0和1用于訪問除數鎖存寄存器(DLL和DLM),用于設置波特率。

  • 關閉中斷
  • 設置波特率
  • 設置異步數據通信格式
void uart_init()
{/* disable interrupts. */uart_write_reg(IER, 0x00);/** Setting baud rate. Just a demo here if we care about the divisor,* but for our purpose [QEMU-virt], this doesn't really do anything.** Notice that the divisor register DLL (divisor latch least) and DLM (divisor* latch most) have the same base address as the receiver/transmitter and the* interrupt enable register. To change what the base address points to, we* open the "divisor latch" by writing 1 into the Divisor Latch Access Bit* (DLAB), which is bit index 7 of the Line Control Register (LCR).** Regarding the baud rate value, see [1] "BAUD RATE GENERATOR PROGRAMMING TABLE".* We use 38.4K when 1.8432 MHZ crystal, so the corresponding value is 3.* And due to the divisor register is two bytes (16 bits), so we need to* split the value of 3(0x0003) into two bytes, DLL stores the low byte,* DLM stores the high byte.*/uint8_t lcr = uart_read_reg(LCR);uart_write_reg(LCR, lcr | (1 << 7));uart_write_reg(DLL, 0x03);uart_write_reg(DLM, 0x00);/** Continue setting the asynchronous data communication format.* - number of the word length: 8 bits* - number of stop bits:1 bit when word length is 8 bits* - no parity* - no break control* - disabled baud latch*/lcr = 0;uart_write_reg(LCR, lcr | (3 << 1));
}

原代碼這里是這樣,感覺不太對,應該是左移一位的。

lcr = 0;
uart_write_reg(LCR, lcr | (3 << 0));

2.3 NS16550a 的數據讀寫

在NS16550A UART中,區分讀寫模式是通過控制信號(如讀/寫控制線)來實現的,而不是通過寄存器地址。這些控制信號通常由CPU或其他主控設備提供。以下是區分讀寫模式的一般步驟:

  1. 當CPU或其他主控設備想要從UART讀取數據時,它會將讀控制線置為有效狀態(低電平)。同時將芯片選擇信號置為有效狀態,以選中UART設備。
  2. 當CPU或其他主控設備想要向UART寫入數據時,它會將寫控制線置為有效狀態(低電平)。同樣將芯片選擇信號置為有效狀態,以選中UART設備。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

讀:

/** LINE STATUS REGISTER (LSR)* LSR BIT 0:* 0 = no data in receive holding register or FIFO.* 1 = data has been receive and saved in the receive holding register or FIFO.* ......* LSR BIT 5:* 0 = transmit holding register is full. 16550 will not accept any data for transmission.* 1 = transmitter hold register (or FIFO) is empty. CPU can load the next character.* ......*/
#define LSR_RX_READY (1 << 0)
#define LSR_TX_IDLE  (1 << 5)int uart_putc(char ch)
{while ((uart_read_reg(LSR) & LSR_TX_IDLE) == 0);return uart_write_reg(THR, ch);
}void uart_puts(char *s)
{while (*s) {uart_putc(*s++);}
}

寫:

練習 7-2

要求:參考code/os/01-helloRVOS,在此基礎上增加采?輪詢?式讀取控制臺上輸入的字符并 回顯 在控制臺上。另外?戶按下回?后能夠另起??從頭開始。

int uart_getc()
{char ch;while ((uart_read_reg(LSR) & LSR_RX_READY) == 0);ch = uart_read_reg(RHR);return ch;
}void uart_gets(char *s, int len)
{int i = 0;char ch;while (i < len - 1) {ch = uart_getc(); if (ch == '\r') { break;}s[i++] = ch;}s[i] = '\0'; 
}/*** 回顯功能:讀取用戶輸入并回顯到控制臺*/
void uart_echo()
{char buffer[100]; 	uart_puts("UART Echo Ready:\r\n");while (1) {uart_gets(buffer, sizeof(buffer)); uart_putc('\r'); uart_putc('\n'); uart_puts("--kernel收到數據--\n");uart_puts(buffer);uart_putc('\r'); uart_putc('\n'); }
}

最后一定記得在kernel.c添加extern聲明:

extern void uart_echo(void);void start_kernel(void)
{uart_init();uart_puts("Hello, RVOS!\n");uart_echo();  // 開始回顯while (1) {}; // stop here!
}

運行結果:

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

存在一個問題就是在終端輸入的內容無法顯示,且無法刪除。

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳


問題解決:在當前實現中,輸入的字符雖然被回顯,但無法正確處理刪除鍵(Backspace)的功能。這是因為 uart_gets 函數沒有對刪除鍵 (‘\b’ 或 ASCII 8) 進行處理。以下是改進方案:

我們需要在 uart_gets 中添加對刪除鍵的處理邏輯。當用戶按下刪除鍵時,應該從緩沖區中移除最后一個字符,并在終端上刪除回顯的字符。

void uart_gets(char *s, int len)
{int i = 0;char ch;while (i < len - 1) {ch = uart_getc(); // 讀取一個字符if (ch == '\r') { // 如果是回車符,結束讀取break;} else if (ch == '\b' || ch == 127) { // 處理刪除鍵('\b' 或 ASCII 127)if (i > 0) {i--; // 從緩沖區中移除最后一個字符uart_putc('\b'); // 回顯刪除鍵uart_putc(' ');  // 用空格覆蓋已刪除的字符uart_putc('\b'); // 將光標移回一格}} else {s[i++] = ch; 	// 存儲字符uart_putc(ch); 	// 回顯輸入的字符}}s[i] = '\0'; // 添加字符串結束符
}

問題完美解決!!

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

【[完結] 循序漸進,學習開發一個RISC-V上的操作系統 - 汪辰 - 2021春】 https://www.bilibili.com/video/BV1Q5411w7z5/?p=19&share_source=copy_web&vd_source=d63943fdb26087d14a536adf35c52d6b

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/76098.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/76098.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/76098.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java導入excel更新設備經緯度度數或者度分秒

文章目錄 一、背景介紹二、頁面效果三、代碼0.pom.xml1.ImportDevice.vue2.ImportDeviceError.vue3.system.js4.DeviceManageControl5.DeviceManageUserControl6.Repeater7.FileUtils8.ResponseModel9.EnumLongitudeLatitude10.詞條 四、注意點本人其他相關文章鏈接 一、背景介…

【力扣hot100題】(080)爬樓梯

讓我們掌聲恭迎動態規劃的始祖—— 最基礎的動態規劃&#xff0c;原始方法是維護一個數組&#xff0c;每次記錄到該階梯的方案數量&#xff0c;每次的數量是到上一個階梯的方案數量加上到上上一階梯的方案數量&#xff0c;因為只有兩種走法。 進階可以優化空間復雜度&#xf…

CVE-2025-24813 漏洞全解析|Apache Tomcat 關鍵路徑繞過與RCE

CVE-2025-24813 漏洞全解析&#xff5c;Apache Tomcat 關鍵路徑繞過與RCE 作者:Factor .Poc作者:iSee857 CVE-2025-24813 漏洞全解析&#xff5c;Apache Tomcat 關鍵路徑繞過與RCE一、漏洞概述二、影響版本三、漏洞原理&#x1f3af; 利用流程&#xff08;兩步&#xff09;&am…

初識Linux:常見指令與權限的理解,以及相關衍生知識

目錄 前言 關于linux的簡介 代碼開源 網絡功能強大 系統工具鏈完整 一、Linux下的基本指令 1.ls指令 2.pwd指令 3.cd指令 4.whoami指令 5.touch指令 6.mkdir指令 7.rm指令 8.man指令 9.cp指令 10.mv指令 11.nano指令 12.cat指令 13.tac指令 14.more指令 15.less指令 16.head指令…

JVM虛擬機篇(七):JVM垃圾回收器全面解析與G1深度探秘及四種引用詳解

JVM垃圾回收器全面解析與G1深度探秘及四種引用詳解 JVM虛擬機&#xff08;七&#xff09;&#xff1a;JVM垃圾回收器全面解析與G1深度探秘及四種引用詳解一、JVM有哪些垃圾回收器1. Serial回收器2. ParNew回收器3. Parallel Scavenge回收器4. Serial Old回收器5. Parallel Old回…

革新電銷流程,數企云外呼開啟便捷 “直通車”

在當今競爭激烈的商業環境中&#xff0c;電銷作為一種重要的營銷手段&#xff0c;依舊在企業的客戶拓展與業務增長中扮演著關鍵角色。然而&#xff0c;傳統電銷流程常常面臨諸多困擾&#xff0c;像是封卡封號風險、接通率不理想、客戶開發與管理艱難以及銷售考核復雜等問題&…

適合工程建筑行業的OA系統有什么推薦?

工程行業具有項目周期長、協作鏈條復雜等特性&#xff0c;傳統管理模式下的 “人治”“紙質化” 弊端日益凸顯。OA 系統作為數字化管理的核心載體&#xff0c;通過流程標準化、數據可視化&#xff0c;精準解決工程行業項目管理核心痛點。 泛微 e-office 深度聚焦工程場景&#…

車載刷寫架構 --- ECU收到相同的blockSequenceCounter數據包的思考

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 周末洗了一個澡,換了一身衣服,出了門卻不知道去哪兒,不知道去找誰,漫無目的走著,大概這就是成年人最深的孤獨吧! 舊人不知我近況,新人不知我過…

C++ RAII 的用途及業務代碼實現案例

C RAII 的用途及業務代碼實現案例 RAII 的核心概念 RAII (Resource Acquisition Is Initialization&#xff0c;資源獲取即初始化) 是 C 的核心編程范式&#xff0c;其核心思想是&#xff1a; 資源獲取與對象構造綁定資源釋放與對象析構綁定利用 C 對象生命周期自動管理資源…

黑馬 SpringAI+DeepSeek 實戰:從對話機器人到企業級知識庫的大模型開發全攻略

附完整代碼 項目案例&#xff0c;3 天吃透大模型應用開發核心技術 需要完整項目學習視頻以及源碼的私信博主&#xff0c;謝謝~大家一起加油吶&#xff01;&#xff01; 01.認識AI和大模型 小結 AI的發展過程 符號主義 機器學習 深度學習——自然語言處理&#xff08;NLP…

共工新聞社與韓國新華報社達成合作

在當下媒體融合浪潮奔涌的時代背景下&#xff0c;大灣區經濟網戰略媒體香港共工新聞社與韓國新華報社順利簽署合作協議&#xff0c;攜手為傳播全球化進程以及海外華文媒體從單一媒體向多媒體的內涵拓展&#xff0c;乃至區域經濟協同與文化融合發展貢獻力量。 締結友好華文媒體協…

嵌入式Linux驅動——3 總線設備驅動模型

目錄 1.總線設備驅動模型 1.1 總線設備驅動模型 1.2 設備樹 1.3 platform_device 和 platform_driver 的匹配規則 1.3.1 最先比較 1.3.2 然后比較 1.3.3 最后比較 2.LED 模板驅動程序的改造&#xff1a;總線設備驅動模型 1.總線設備驅動模型 在前面的 led 驅動程序中…

操作系統常用命令

邏輯卷創建及掛載步驟&#xff1a; vgcreate vg_app /dev/sda //在sda盤上創建vg_app卷組 lvcreate -L 50G -n lv_mysql vg_app //在vg_app卷組上創建邏輯卷lv_mysql mkfs.xfs /dev/vg_app/lv_mysql //對lv_mysql 邏輯卷創建文件系統 mkdir mysql //創建mysql目錄 ech…

Git 的進階功能和技巧

1、分支的概念和使用 1.1、什么是分支&#xff1f; 分支&#xff08;Branch&#xff09;是在版本控制中非常重要的概念。幾乎所有版本控制系統都支持某種形式的分支。在 Git 中&#xff0c;分支是 Git 強大功能之一&#xff0c;它允許我們從主開發線分離出來&#xff0c;在不…

mapbox基礎,加載F4Map二維地圖

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性二、??F4Map 簡介2.1 ??技術特點2.2 ??核…

Conda使用方法詳解

Conda是一個開源的包管理和環境管理系統&#xff0c;主要用于Python/R等科學計算領域&#xff0c;可以輕松管理不同項目的依賴關系。以下是Conda的詳細使用方法&#xff1a; 一、安裝與配置 1.安裝Miniconda/Anaconda Miniconda是精簡版&#xff0c;只包含conda和Python Ana…

Unity ViewportConstraint

一、組件功能概述 ViewportConstraint是一個基于世界坐標的UI邊界約束組件&#xff0c;主要功能包括&#xff1a; 將UI元素限制在父容器范圍內支持自定義內邊距&#xff08;padding&#xff09;可獨立控制水平和垂直方向的約束 二、實現原理 1. 邊界計算&#xff08;世界坐…

代碼隨想錄-動態規劃24

leetcode-300-最長遞增子序列 dp[i]表示i之前包括i的以nums[i]結尾的最長遞增子序列的長度 dp[j]是(0,i-1)不包括i的以nums[i-1]結尾的最長遞增子序列長度 int lengthOfLIS(int* nums, int numsSize) {if(numsSize < 1)return numsSize;int dp[numsSize];for(int i 0 ; i &…

銀河麒麟V10 Ollama+ShellGPT打造Shell AI助手——筑夢之路

環境說明 1. 操作系統版本: 銀河麒麟V10 2. CPU架構&#xff1a;X86 3. Python版本&#xff1a;3.12.9 4. 大模型&#xff1a;mistral:7b-instruct 準備工作 1. 編譯安裝python 3.12 # 下載python 源碼wget https://www.python.org/ftp/python/3.12.9/Python-3.12.9.tg…

2025 跨平臺技術如何選:KMP 與 Flutter 的核心差異

前言 在移動開發的演進歷程中&#xff0c;跨平臺技術始終是一個充滿爭議卻無法回避的話題。從早期的 React Native 到如今的 Kotlin Multiplatform&#xff08;KMP&#xff09;和 Flutter&#xff0c;開發者們始終在代碼復用與原生體驗之間尋找平衡。本文我們從技術實現、性能…