全志D1s裸机开发之体验第一个程序

news/2024/7/27 9:05:13/文章来源:https://blog.csdn.net/weixin_43094346/article/details/136557600

体验第一个程序

2.1 编译烧录运行

2.1.1 编译

先进入源码目录,打开 Git Bash,如下图操作:

在这里插入图片描述

然后在 Git Bash 中执行 make 命令,可以生成 benos_payload.bin 文件,如下图所示:

在这里插入图片描述

2.1.2 烧录运行

使用 2 条 USB 线,分别连接开发板的 3.OTG烧录接口4.调试&串口接口 ,使用串口工具打开串口,波特率设为 115200 , 8 个数据位,1 个停止位,不使用流量控制。

烧录方法如下:

① 先让开发板进入烧录模式:

方法为:先按住 2.烧录模式按键 不松开,然后按下、松开 5.系统复位按键 ,最后松开 2.烧录模式按键

② 然后在 Git Bash 开执行 make burn 命令

如下图所示:

在这里插入图片描述

烧写成功后,按下、松开 5.系统复位按键 即可启动程序,可以在串口看到输出信息:

在这里插入图片描述

2.2 调试

2.2.1 GDB 常用命令

使用 GDB 调试时,涉及两个软件:

① 在 Git Bash 中运行的 riscv64-unknown-elf-gdb :它发出各类调试命令,比如连接调试服务软件 (T-HeadDebugServer) 、单步运行、查看变量等等

② T-HeadDebugServer :它就是“调试服务软件”,负责接收、处理各类调试命令

常见的命令如下表所示:

命令简写形式说明
target连接调试服务器,比如: target remote 127.0.0.1:1025
runr运行程序
continuec、cont继续运行
breakb设置断点,比如: b sbi_main.c:121 b sbi_main b *0x20000
deleted删除断点
disabledis禁用断点
info breakpointsinfo b显示断点信息
nextn执行下一行
nextini执行下一行(以汇编代码为单位)
steps一次执行一行,包括函数内部
setpisi执行下一行
listl显示函数或行
printp显示表达式,比如: print a print $pc // 打印寄存器 print *0x20000//打印内存 print /x a // 16进制打印
x显示内存内容,比如: x 0x20000 x /x 0x20000 //16进制
info registersinfor r打印所有寄存器的值
set设置变量,比如: set var a=1 set *(unsigned int *)0x28000 = 0x55555555 set var $pc=0x22000
finish运行到函数结束
helph显示帮助一览
backtracebt、where显示 backtrace
symbol-file加载符号表,比如 symbol-file benos.elf

2.2.2 benos_payload 程序组成

《RISC-V体系结构编程与实践》中的代码分为两部分:

① mysbi.elf:运行于 M 模式的底层软件,提供各种系统服务

② benos.elf:运行于 S 模式的应用软件

benos_payload 是这两部分程序的组合:

2.2.2 benos_payload 程序组成

《RISC-V体系结构编程与实践》中的代码分为两部分:

① mysbi.elf:运行于 M 模式的底层软件,提供各种系统服务

② benos.elf:运行于 S 模式的应用软件

benos_payload 是这两部分程序的组合:

benos_payload.elf = mysbi.elf + benos.elf
benos_payload.bin = mysbi.bin + benos.bin

烧写、运行 benos_payload.bin 时,会先运行 mysbi 程序, mysbi 再启动 benos 。调试 benos_payload.elf 时,我们可以先调试 mysbi ,等 benos 启动后再调试 benos。

2.2.3 调试准备工作

首先,启动 CKLink 的调试功能,方法为:把下图中蓝色箭头所指的拨码开关上的薄膜撕开,把所有拨码开关拨向左边(USB接口那边):

在这里插入图片描述

然后,启动调试服务软件 T-HeadDebugServer ,它会自动检测到芯片,如下图所示:

在这里插入图片描述

如果没有上图所示信息,有多种可能:

① 没有自动识别:

可以手动识别,如下图所示:

在这里插入图片描述

② 板子上的程序有 Bug ,导致板子死机了:可以让板子先进入烧录模式,再按照步骤①操作

③ 提示 1025 端口被占用:运行任务管理器,把所有 T-HeadDebugServer 杀掉,再重新运行 T-HeadDebugServer

T-HeadDebugServer 识别出芯片后,就可以调试程序了,有 2 种方式:

① 使用命令行模式调试

② 使用 TUI 模式调试

2.2.4 命令行调试示例

T-HeadDebugServer 识别出芯片后,就可以在 Git Bash 里执行 riscv64-unknown-elf-gdb benos_payload.elf 来调试程序了。

示例如下:

weidongshan@DESKTOP-TP8DH2I MINGW64 /d/abc/riscv_programming_practice/chapter_2/benos (DongShanPI_D1)
$ riscv64-unknown-elf-gdb benos_payload.elf
Reading symbols from benos_payload.elf...
(gdb) target remote 127.0.0.1:1025       // 连接调试服务软件
Remote debugging using 127.0.0.1:1025
0x000000000000a22a in ?? ()
(gdb) load   // 加载benos_payload.elf
Loading section .text.boot, size 0x44 lma 0x20000section progress: 100.0%, total progress:  0.38%
Loading section .text, size 0x538 lma 0x20044section progress: 100.0%, total progress:  7.81%
Loading section .rodata, size 0xc0 lma 0x2057csection progress: 100.0%, total progress:  8.88%
Loading section .data, size 0x1000 lma 0x21000section progress: 100.0%, total progress: 31.66%
Loading section .payload, size 0x3000 lma 0x22000section progress: 100.0%, total progress: 100.00%
Start address 0x0000000000020000, load size 17980
Transfer rate: 209 KB/sec, 1997 bytes/write.
(gdb) x /x 0x20000   // 检查0x20000是否被正确写入,
// 我们调试程序时可能因为上次的死机导致无法load
// 这时可以让板子进入烧录模式,再重新连接、重新加载
0x20000 <text_begin>:   0x0300006f
(gdb) b sbi_main   // 设置断点为sbi_main函数
Breakpoint 1 at 0x204bc: file sbi/sbi_main.c, line 80.
(gdb) c            // 执行
Continuing.Breakpoint 1, sbi_main () at sbi/sbi_main.c:80
80              sbi_set_pmp(0, 0, -1UL, PMP_RWX);
(gdb) n        // 下一步
84              val = read_csr(mstatus);
(gdb) b sbi_main.c:102    // 设置断点为sbi_main.c的102行
Breakpoint 2 at 0x20564: file sbi/sbi_main.c, line 102.
(gdb) info b    // 查看所有断点
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000000204bc in sbi_mainat sbi/sbi_main.c:80breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000020564 in sbi_mainat sbi/sbi_main.c:102
(gdb) i b    // 查看所有断点,简写的命令
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000000204bc in sbi_mainat sbi/sbi_main.c:80breakpoint already hit 1 time
2       breakpoint     keep y   0x0000000000020564 in sbi_mainat sbi/sbi_main.c:102
(gdb) c   // 继续执行
Continuing.Breakpoint 2, sbi_main () at sbi/sbi_main.c:102  // 碰到断点了
// 执行完下一句代码就会跳到benos程序
102             asm volatile("mret");
(gdb) si  // 单步执行并进入函数,每次执行一条汇编语句
0x0000000000022000 in payload_bin ()  // 现在要执行另一个程序benos了
(gdb) symbol-file benos.elf  // 读取benos.elf的符号表,否则你调试时无法知道函数、代码等信息
Load new symbol table from "benos.elf"? (y or n) [answered Y; input not from terminal]
Reading symbols from benos.elf...
Error in re-setting breakpoint 1: Function "sbi_main" not defined.
Error in re-setting breakpoint 2: No source file named sbi_main.c.
(gdb) si  // 单步执行并进入函数,每次执行一条汇编语句
9               la sp, stacks_start
(gdb) b kernel_main  // 设置断点为kernel_main函数
Breakpoint 3 at 0x22020: file src/kernel.c, line 6.
(gdb) c    // 继续执行
Continuing.Breakpoint 3, kernel_main () at src/kernel.c:6
6           sys_clock_init();
(gdb) i r   // 列出所有寄存器的值
ra             0x204d0  0x204d0
sp             0x24ff0  0x24ff0
gp             0x0      0x0
tp             0x0      0x0
t0             0x1000   4096
t1             0xfffffffffffff000       -4096
t2             0x109    265
fp             0xa00000900      0xa00000900
s1             0x0      0
a0             0x0      0
a1             0x1f     31
a2             0xffffffffffffffff       -1
a3             0x0      0
a4             0xa00000100      42949673216
a5             0x0      0
a6             0x80     128
a7             0x1c0    448
s2             0x375bff17       928775959
s3             0xff32dec        267595244
s4             0x2eebeffb       787214331
s5             0xffffffffffdf9ffd       -2121731
s6             0x355077ff       894466047
s7             0xffffffffef7eeee9       -276893975
s8             0x27034  159796
s9             0xffffffffe6376ff3       -432574477
s10            0xffffffffb9d37bfc       -1177322500
s11            0x78b47e70       2025094768
t3             0x1      1
t4             0xefe8   61416
t5             0x8001   32769
t6             0x0      0
pc             0x22020  0x22020 <kernel_main+8>
(gdb) l   // 列出代码
1       #include "clock.h"
2       #include "uart.h"
3
4       void kernel_main(void)
5       {
6           sys_clock_init();
7               uart_init();
8
9               while (1) {
10              uart_send_string("Welcome RISC-V!\r\n");
(gdb) l
11                      ;
12              }
13      }
(gdb) c     // 继续执行
Continuing.Program received signal SIGINT, Interrupt. // 按Ctrl+C停止程序
read32 (addr=38797436) at include/io.h:23
23      }
(gdb) quit  // 退出调试

上述调试过程中,用到的命令都有注释,摘抄如下:

$ riscv64-unknown-elf-gdb benos_payload.elf  // 开始调试
(gdb) target remote 127.0.0.1:1025       // 连接调试服务软件
(gdb) load   // 加载benos_payload.elf
(gdb) x /x 0x20000      // 检查0x20000是否被正确写入,
// 我们调试程序时可能因为上次的死机导致无法load
// 这时可以让板子进入烧录模式,再重新连接、重新加载
(gdb) b sbi_main   // 设置断点为sbi_main函数
(gdb) c            // 执行
(gdb) n            // 下一步
(gdb) b sbi_main.c:102    // 设置断点为sbi_main.c的102行
(gdb) info b    // 查看所有断点
(gdb) i b       // 查看所有断点,简写的命令
(gdb) c         // 继续执行
(gdb) si        // 单步执行并进入函数,每次执行一条汇编语句
(gdb) symbol-file benos.elf  // 读取benos.elf的符号表,否则你调试时无法知道函数、代码等信息
(gdb) si  // 单步执行并进入函数,每次执行一条汇编语句
(gdb) b kernel_main  // 设置断点为kernel_main函数
(gdb) c     // 继续执行
(gdb) i r   // 列出所有寄存器的值
(gdb) l     // 列出代码
(gdb) l
(gdb) c     // 继续执行
Program received signal SIGINT, Interrupt. // 按Ctrl+C停止程序
(gdb) quit  // 退出调试

benos_payload.elf 是 2 个程序的组合,调试的要点在于:

① 调试第 1 个程序时,默认从 benos_payload.elf 里得到符号表

② 执行到第 2 个程序时,需要使用 symbol-file benos.elf 命令读取 benos.elf 的符号表,否则你调试时无法知道函数、代码等信息。

③ 怎么知道执行到了第 2 个程序?可以在 sbi_main.c 里如下红框代码处设置断点(比如 b sbi_main.c:102 ),执行到断点后,再执行 si 命令就开始运行第 2 个程序了:

在这里插入图片描述

2.2.5 TUI调试示例

T-HeadDebugServer 识别出芯片后,就可以在 Powershell 里执行 riscv64-unknown-elf-gdb -tui benos_payload.elf 来调试程序了。

注意:在 Git Bash 中无法使用 TUI 功能,需要使用 Powershell 。

先启动 Powershell :进入源码目录后,按住 shift 键同时点击鼠标右键,在弹出的菜单里启动 Powershell ,如下图所示:

在这里插入图片描述

在 Powershell 窗口,执行如下命令即可开始调试:

riscv64-unknown-elf-gdb  -tui  benos_payload.elf

执行上述命令后,可以得到如下界面(源码窗口里的汉字是乱码,暂时无法解决):

在这里插入图片描述

使用 TUI 的便利在于可以方便地观看源码、反汇编码、寄存器,显示这些信息的窗口被称为 layout 。使用以下命令可以显示这些 layout :

① layout src:显示源码窗口

② layout asm:显示汇编窗口

③ layout regs:在之前的窗口上再显示寄存器窗口

④ layout split:显示源码、汇编窗口

⑤ layout next:显示下一个 layout

⑥ layout prev:显示上一个 layout

能输入各类 GDB 命令的窗口是 命令窗口 ,它总是显示的。

要同时显示源码和寄存器,可以执行如下 2 个命令:

layout src
layout regs

要同时显示反汇编码和寄存器,可以执行如下 2 个命令:

layout asm
layout regs

要同时显示源码和反汇编码,可以执行如下命令:

layout split

使用 TUI 模式时,只是方便我们观看源码、反汇编码、寄存器,具体操作还是在命令窗口输入 GDB 命令,请参考《2.2.4 命令行调试示例》。

2.2.6 gdb脚本

如果不想每次执行 riscv64-unknown-elf-gdb benos_payload.elfriscv64-unknown-elf-gdb -tui benos_payload.elf 后,都手工执行以下命令来连接调试服务软件:

(gdb) target remote 127.0.0.1:1025       // 连接调试服务软件

可以把这些命令写入一个名为 .gdbinit 的文件里,注意这个文件名的第 1 个字符是 . ,它表示在 Linux 系统下它是一个隐藏文件。在 Windows 的文件浏览器里我们可以看见它,但是在 Git Bash 里执行 ls 命令看不到它,需要执行 ls -a 命令才能看见。

你可以在 .gdbinit 里放入更多命令,下面是一个例子:

target remote 127.0.0.1:1025
load
b sbi_main.c:102

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_997932.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode HOT150

55. 跳跃游戏 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1 …

用云手机进行舆情监测有什么作用?

在信息爆炸的时代&#xff0c;舆情监测成为企业和政府决策的重要工具。通过结合云手机技术&#xff0c;舆情监测系统在品牌形象维护、市场竞争、产品研发、政府管理以及市场营销等方面发挥着关键作用&#xff0c;为用户提供更智能、高效的舆情解决方案。 1. 品牌形象维护与危机…

基于java ssm springboot女士电商平台系统

基于java ssm springboot女士电商平台系统源码文档设计 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末…

第107讲:Mycat实践指南:取模分片下的水平分表详解

文章目录 1.使用取模分片水平分表2.水平分表取模分片案例2.1.准备测试的表结构2.2.配置Mycat实现范围分片的水平分表2.2.1.配置Schema配置文件2.2.2.配置Rule分片规则配置文件2.2.3.配置Server配置文件2.2.4.重启Mycat 2.3.写入数据观察水平分表效果 1.使用取模分片水平分表 平…

2024新疆专升本考试报名教程详解

2024新疆专升本报名时间已经开始了&#xff0c;想要参加考试报名的同学可以提前准备好报名照

产品推荐 - GX-SOPC-5CEFA5-M484 FPGA核心开发板

● 核心板采用8层板精心设计 ● FPGA&#xff1a;采用Intel&#xff08;ALTERA&#xff09; Cyclone V 5CEFA5&#xff0c;Les为77K&#xff0c;内嵌存储器为4460Kb&#xff0c;硬件乘法器为300个&#xff0c;最大等效门数约2300万门&#xff1b;新增DSP Block&#xff08;150…

新版AndroidStudio的Gradle窗口显示task list not built 问题解决

在使用新版AndroidStudio时&#xff0c;会出现&#xff0c;Task List not built 的问题。如果你记得task的名字&#xff0c;当然可以 直接通过命令 gradle taskname 或者 ./gradlew taskName直接执行即可&#xff0c;但是若是记不住&#xff0c;还是把这个任务构建处理比较好用…

鸿蒙Harmony 时代的跨端方案

终端系统的数量和种类不断增长&#xff0c;开发者面临着多平台开发的挑战。以往开发者一般只需要维护iOS、android、MacOS、windows几个主流核心终端操作系统即可&#xff0c;但是随着信创化的趋势&#xff0c;统信、麒麟、鸿蒙等操作系统也开始崛起&#xff0c;后续可能还会涌…

智慧城市的新引擎:物联网技术引领城市创新与发展

目录 一、引言 二、物联网技术与智慧城市的融合 三、物联网技术在智慧城市中的应用 1、智慧交通管理 2、智慧能源管理 3、智慧环保管理 4、智慧公共服务 四、物联网技术引领城市创新与发展的价值 五、挑战与前景 六、结论 一、引言 随着科技的日新月异&#xff0c;物…

FPGA时序约束与分析--数据到达路径和数据需求路径

文章目录 前言一、定义二、时序模型三、公式推导 前言 时序约束的定义–设计者根据实际的系统功能&#xff0c;通过时序约束的方式提出时序要求&#xff1b; FPGA 编译工具根据设计者的时序要求&#xff0c;进行布局布线&#xff1b;编译完成后&#xff0c; FPGA 编译工具还需…

Java网络通信TCP

目录 TCP两个核心类 服务端 1.用ServerSocker类创建对象并且手动指定端口号 2.accept阻塞连接服务端与客户端 3.给客户端提供处理业务方法 4.处理业务 整体代码 客户端 1.创建Socket对象&#xff0c;并连接服务端的ip与端口号 2.获取Socket流对象&#xff0c;写入数据…

HAproxy

四层&#xff1a; - LVS&#xff1a;Linux Virtual Server - Nginx&#xff1a; - HAProxy&#xff1a;High Availability Proxy 七层: - HAProxy - Nginx 硬件&#xff1a; - F5 https://f5.com/zh- Netscaler https://www.citrix.com.cn/product…

能量不等式证明

波动方程初值问题能量不等式的证明 Gronwall 不等式 若非负函数 G ( τ ) G(\tau) G(τ) 在 [ 0 , T ] [0,T] [0,T] 上连续可微&#xff0c; G ( 0 ) 0 G(0)0 G(0)0&#xff0c;且对 τ ∈ [ 0 , T ] \tau\in[0,T] τ∈[0,T]满足 d G ( τ ) d τ ≤ C G ( τ ) F ( τ …

【PyQt】16-剪切板的使用

文章目录 前言一、代码疑惑快捷键 二、现象2.1 复制粘贴文本复制粘贴 2.2 复制粘贴图片复制粘贴 2.3 复制粘贴网页 总结 前言 1、剪切板的使用 2、pycharm的编译快捷键 3、类的属性和普通变量的关系 4、pyqt应该养成的编程习惯-体现在代码里了&#xff0c;自己看看。 一、代码…

Bert Encoder和Transformer Encoder有什么不同

前言&#xff1a;本篇文章主要从代码实现角度研究 Bert Encoder和Transformer Encoder 有什么不同&#xff1f;应该可以帮助你&#xff1a; 深入了解Bert Encoder 的结构实现深入了解Transformer Encoder的结构实现 本篇文章不涉及对注意力机制实现的代码研究。 注&#xff1a;…

CentOS7 利用remi yum源安装php8.1

目录 前言remi yum源remi yum源 支持的操作系统remi yum源 支持的php版本 安装epel源安装remi源安装 php8.1查看php版本查看php-fpm服务启动php-fpm服务查看php-fpm服务运行状态查看php-fpm服务占用的端口查看 php8.1 相关的应用 前言 CentOS Linux release 7.9.2009 (Core) …

maven项目引入私有jar,并打包到java.jar中

私有jar存放位置 maven依赖 <dependency><groupId>com.hikvision.ga</groupId><artifactId>artemis-http-client</artifactId><version>1.1.10</version><scope>system</scope><systemPath>${project.basedir}/s…

【ETCD】简介安装常用操作---图文并茂详细讲解

目录 一 简介 1.1 etcd是什么 1.2. 特点 1.3. 使用场景 1.4 关键字 1.5 工作原理 二 安装 2.1 etcd安装前介绍 2.2 安装 2.3 启动 2.4 创建一个etcd服务 三 常用操作 一 简介 1.1 etcd是什么 etcd是CoreOS团队于2013年6月发起的开源项目&#xff0c;它的目标是构建…

面向对象中类与对象

思考系统1000个对象逻辑结构 理解系统1000个对象物理结构 对象this 引用 类的静态变量和静态函数 静态变量和静态函数属于类本身&#xff0c;而不是类的实例。它们可以在不创建类的实例的情况下直接通过类名访问。静态变量在内存中只有一份拷贝&#xff0c;被所有实例共享&…

从一个问题开始聊聊clickhouse的物化视图

【问题】 今天有A问我一个问题&#xff0c;我明明创建了一个物化视图&#xff0c;源表是有数据的&#xff0c;为什么查询物化视图就没有数据&#xff1f; 创建物化视图的SQL示意如下&#xff1a; CREATE MATERIALIZED VIEW schema1.test_mvon cluster clusterNameTO schema1…