mirror of
https://github.com/nkbai/book.git
synced 2026-09-05 22:14:54 +08:00
457 lines
26 KiB
HTML
457 lines
26 KiB
HTML
<!DOCTYPE HTML>
|
||
<html lang="en" class="sidebar-visible no-js light">
|
||
<head>
|
||
<!-- Book generated using mdBook -->
|
||
<meta charset="UTF-8">
|
||
<title>硬件 - The Embedded Rust Book</title>
|
||
|
||
|
||
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
||
<meta name="description" content="">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="theme-color" content="#ffffff" />
|
||
|
||
<link rel="shortcut icon" href="../favicon.png">
|
||
<link rel="stylesheet" href="../css/variables.css">
|
||
<link rel="stylesheet" href="../css/general.css">
|
||
<link rel="stylesheet" href="../css/chrome.css">
|
||
<link rel="stylesheet" href="../css/print.css" media="print">
|
||
|
||
<!-- Fonts -->
|
||
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
|
||
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:500" rel="stylesheet" type="text/css">
|
||
|
||
<!-- Highlight.js Stylesheets -->
|
||
<link rel="stylesheet" href="../highlight.css">
|
||
<link rel="stylesheet" href="../tomorrow-night.css">
|
||
<link rel="stylesheet" href="../ayu-highlight.css">
|
||
|
||
<!-- Custom theme stylesheets -->
|
||
|
||
|
||
|
||
</head>
|
||
<body>
|
||
<!-- Provide site root to javascript -->
|
||
<script type="text/javascript">
|
||
var path_to_root = "../";
|
||
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
|
||
</script>
|
||
|
||
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
<script type="text/javascript">
|
||
try {
|
||
var theme = localStorage.getItem('mdbook-theme');
|
||
var sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
||
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
}
|
||
|
||
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
}
|
||
} catch (e) { }
|
||
</script>
|
||
|
||
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
<script type="text/javascript">
|
||
var theme;
|
||
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
var html = document.querySelector('html');
|
||
html.classList.remove('no-js')
|
||
html.classList.remove('light')
|
||
html.classList.add(theme);
|
||
html.classList.add('js');
|
||
</script>
|
||
|
||
<!-- Hide / unhide sidebar before it is displayed -->
|
||
<script type="text/javascript">
|
||
var html = document.querySelector('html');
|
||
var sidebar = 'hidden';
|
||
if (document.body.clientWidth >= 1080) {
|
||
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
sidebar = sidebar || 'visible';
|
||
}
|
||
html.classList.remove('sidebar-visible');
|
||
html.classList.add("sidebar-" + sidebar);
|
||
</script>
|
||
|
||
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
<div class="sidebar-scrollbox">
|
||
<ol class="chapter"><li class="chapter-item expanded "><a href="../intro/index.html"><strong aria-hidden="true">1.</strong> 简介</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../intro/hardware.html"><strong aria-hidden="true">1.1.</strong> 硬件</a></li><li class="chapter-item expanded "><a href="../intro/no-std.html"><strong aria-hidden="true">1.2.</strong> no_std</a></li><li class="chapter-item expanded "><a href="../intro/tooling.html"><strong aria-hidden="true">1.3.</strong> 工具</a></li><li class="chapter-item expanded "><a href="../intro/install.html"><strong aria-hidden="true">1.4.</strong> 安装</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../intro/install/linux.html"><strong aria-hidden="true">1.4.1.</strong> Linux</a></li><li class="chapter-item expanded "><a href="../intro/install/macos.html"><strong aria-hidden="true">1.4.2.</strong> MacOS</a></li><li class="chapter-item expanded "><a href="../intro/install/windows.html"><strong aria-hidden="true">1.4.3.</strong> Windows</a></li><li class="chapter-item expanded "><a href="../intro/install/verify.html"><strong aria-hidden="true">1.4.4.</strong> 验证安装</a></li></ol></li></ol></li><li class="chapter-item expanded "><a href="../start/index.html"><strong aria-hidden="true">2.</strong> 入门</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../start/qemu.html"><strong aria-hidden="true">2.1.</strong> QEMU</a></li><li class="chapter-item expanded "><a href="../start/hardware.html" class="active"><strong aria-hidden="true">2.2.</strong> 硬件</a></li><li class="chapter-item expanded "><a href="../start/registers.html"><strong aria-hidden="true">2.3.</strong> 内存映射寄存器</a></li><li class="chapter-item expanded "><a href="../start/semihosting.html"><strong aria-hidden="true">2.4.</strong> 半主机</a></li><li class="chapter-item expanded "><a href="../start/panicking.html"><strong aria-hidden="true">2.5.</strong> 恐慌</a></li><li class="chapter-item expanded "><a href="../start/exceptions.html"><strong aria-hidden="true">2.6.</strong> 异常</a></li><li class="chapter-item expanded "><a href="../start/interrupts.html"><strong aria-hidden="true">2.7.</strong> 中断</a></li><li class="chapter-item expanded "><a href="../start/io.html"><strong aria-hidden="true">2.8.</strong> IO</a></li></ol></li><li class="chapter-item expanded "><a href="../peripherals/index.html"><strong aria-hidden="true">3.</strong> 外设</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../peripherals/a-first-attempt.html"><strong aria-hidden="true">3.1.</strong> 初试Rust</a></li><li class="chapter-item expanded "><a href="../peripherals/borrowck.html"><strong aria-hidden="true">3.2.</strong> 借用检查器</a></li><li class="chapter-item expanded "><a href="../peripherals/singletons.html"><strong aria-hidden="true">3.3.</strong> 单例</a></li></ol></li><li class="chapter-item expanded "><a href="../static-guarantees/index.html"><strong aria-hidden="true">4.</strong> 静态保证</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../static-guarantees/typestate-programming.html"><strong aria-hidden="true">4.1.</strong> 类型状态机编程</a></li><li class="chapter-item expanded "><a href="../static-guarantees/state-machines.html"><strong aria-hidden="true">4.2.</strong> 外设作为状态机</a></li><li class="chapter-item expanded "><a href="../static-guarantees/design-contracts.html"><strong aria-hidden="true">4.3.</strong> 设计合约</a></li><li class="chapter-item expanded "><a href="../static-guarantees/zero-cost-abstractions.html"><strong aria-hidden="true">4.4.</strong> 零成本抽象</a></li></ol></li><li class="chapter-item expanded "><a href="../portability/index.html"><strong aria-hidden="true">5.</strong> 可移植性</a></li><li class="chapter-item expanded "><a href="../concurrency/index.html"><strong aria-hidden="true">6.</strong> 并发</a></li><li class="chapter-item expanded "><a href="../collections/index.html"><strong aria-hidden="true">7.</strong> 容器</a></li><li class="chapter-item expanded "><a href="../c-tips/index.html"><strong aria-hidden="true">8.</strong> 嵌入式C开发人员的技巧</a></li><li class="chapter-item expanded "><a href="../interoperability/index.html"><strong aria-hidden="true">9.</strong> 互操作性</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../interoperability/c-with-rust.html"><strong aria-hidden="true">9.1.</strong> Rust中使用C代码</a></li><li class="chapter-item expanded "><a href="../interoperability/rust-with-c.html"><strong aria-hidden="true">9.2.</strong> C中使用Rust代码</a></li></ol></li><li class="chapter-item expanded "><a href="../unsorted/index.html"><strong aria-hidden="true">10.</strong> 其他主题</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../unsorted/speed-vs-size.html"><strong aria-hidden="true">10.1.</strong> 优化:速度大小的权衡</a></li><li class="spacer"></li></ol></li><li class="chapter-item expanded "><a href="../appendix/glossary.html">Appendix A: Glossary</a></li></ol>
|
||
</div>
|
||
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
||
</nav>
|
||
|
||
<div id="page-wrapper" class="page-wrapper">
|
||
|
||
<div class="page">
|
||
|
||
<div id="menu-bar-hover-placeholder"></div>
|
||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||
<div class="left-buttons">
|
||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
<i class="fa fa-bars"></i>
|
||
</button>
|
||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
<i class="fa fa-paint-brush"></i>
|
||
</button>
|
||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
</ul>
|
||
|
||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||
<i class="fa fa-search"></i>
|
||
</button>
|
||
|
||
</div>
|
||
|
||
<h1 class="menu-title">The Embedded Rust Book</h1>
|
||
|
||
<div class="right-buttons">
|
||
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||
<i id="print-button" class="fa fa-print"></i>
|
||
</a>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div id="search-wrapper" class="hidden">
|
||
<form id="searchbar-outer" class="searchbar-outer">
|
||
<input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||
</form>
|
||
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||
<div id="searchresults-header" class="searchresults-header"></div>
|
||
<ul id="searchresults">
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
<script type="text/javascript">
|
||
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
});
|
||
</script>
|
||
|
||
<div id="content" class="content">
|
||
<main>
|
||
<h1><a class="header" href="#硬件" id="硬件">硬件</a></h1>
|
||
<p>现在,您应该对工具和开发过程有所了解。在本节中,我们将切换到实际硬件,该过程将基本保持不变,让我们开始吧。</p>
|
||
<h2><a class="header" href="#了解您的硬件" id="了解您的硬件">了解您的硬件</a></h2>
|
||
<p>在我们开始之前,您需要确定目标设备的一些特征,因为这些特征将用于配置项目:</p>
|
||
<ul>
|
||
<li>
|
||
<p>ARM内核。例如Cortex-M3。</p>
|
||
</li>
|
||
<li>
|
||
<p>ARM内核是否包括FPU? Cortex-M4<strong>F</strong>和Cortex-M7<strong>F</strong>内核都有FPU。</p>
|
||
</li>
|
||
<li>
|
||
<p>目标设备有多少闪存和RAM?例如256 KiB的闪存和32 KiB的RAM。</p>
|
||
</li>
|
||
<li>
|
||
<p>闪存和RAM映射的地址空间在哪里?例如RAM通常位于地址“0x2000_0000”。</p>
|
||
</li>
|
||
</ul>
|
||
<p>通常您可以在数据手册或设备的参考手册中找到这些信息。</p>
|
||
<p>在本节中,我们将使用我们的参考硬件STM32F3DISCOVERY。该开发板包含STM32F303VCT6微控制器。该微控制器具有:</p>
|
||
<ul>
|
||
<li>
|
||
<p>一个Cortex-M4F内核,其中包括一个单精度FPU</p>
|
||
</li>
|
||
<li>
|
||
<p>闪存的256 KiB位于地址0x0800_0000。</p>
|
||
</li>
|
||
<li>
|
||
<p>位于地址0x2000_0000的40KiBRAM。 (还有另一个RAM区域,为简单起见,我们将其忽略)。</p>
|
||
</li>
|
||
</ul>
|
||
<h2><a class="header" href="#配置" id="配置">配置</a></h2>
|
||
<p>我们将从一个新的模板实例开始。如果没有<code>cargo-generate</code>工具,请参阅<a href="qemu.html">上一小节的QEMU</a>。</p>
|
||
<pre><code class="language-console">$ cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
|
||
Project Name: app
|
||
Creating project called `app`...
|
||
Done! New project created /tmp/app
|
||
|
||
$ cd app
|
||
</code></pre>
|
||
<p>第一个步是在.cargo/config中设置默认的编译目标。</p>
|
||
<pre><code class="language-console">$ tail -n5 .cargo/config
|
||
</code></pre>
|
||
<pre><code class="language-toml"># Pick ONE of these compilation targets
|
||
# target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+
|
||
# target = "thumbv7m-none-eabi" # Cortex-M3
|
||
# target = "thumbv7em-none-eabi" # Cortex-M4 and Cortex-M7 (no FPU)
|
||
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
|
||
</code></pre>
|
||
<p>这次用得是Cortex-M4F内核,所以target使用<code>thumbv7em-none-eabihf</code> 。</p>
|
||
<p>第二步是将存储区域信息输入到“memory.x”文件中。</p>
|
||
<pre><code class="language-console">$ cat memory.x
|
||
/* Linker script for the STM32F303VCT6 */
|
||
MEMORY
|
||
{
|
||
/* NOTE 1 K = 1 KiBi = 1024 bytes */
|
||
FLASH : ORIGIN = 0x08000000, LENGTH = 256K
|
||
RAM : ORIGIN = 0x20000000, LENGTH = 40K
|
||
}
|
||
</code></pre>
|
||
<p>确保<code>debug::exit()</code>调用已被注释掉或删除,因为他仅用于QEMU环境。</p>
|
||
<pre><code class="language-rust ignore">#[entry]
|
||
fn main() -> ! {
|
||
hprintln!("Hello, world!").unwrap();
|
||
|
||
// exit QEMU
|
||
// NOTE do not run this on hardware; it can corrupt OpenOCD state
|
||
// debug::exit(debug::EXIT_SUCCESS);
|
||
|
||
loop {}
|
||
}
|
||
</code></pre>
|
||
<p>现在,您可以像以前一样使用<code>cargo build</code>交叉编译程序,并使用<code>cargo-binutils</code>检查二进制文件。 <code>cortex-m-rt</code> crate可处理让您的芯片运行所需的所有魔术,几乎所有Cortex-M CPU都以相同的方式引导。</p>
|
||
<pre><code class="language-console">$ cargo build --example hello
|
||
</code></pre>
|
||
<h2><a class="header" href="#调试" id="调试">调试</a></h2>
|
||
<p>调试看起来会有所不同。实际上,根据目标设备的不同,第一步看起来可能会有所不同。在本节中,我们将介绍在STM32F3DISCOVERY上调试程序所需的步骤。有关设备的特定信息,请查看<a href="https://github.com/rust-embedded/debugonomicon">Debugonomicon</a>。</p>
|
||
<p>和以前一样,我们将进行远程调试,客户端是GDB进程,服务器将是OpenOCD。</p>
|
||
<p>$ cat openocd.cfg
|
||
按照<a href="../intro/install/verify.html">验证</a>部分的操作,将开发板连接到笔记本电脑或者PC,并检查是否插上了ST-LINK跳线帽。</p>
|
||
<p>在终端上,从模板的根目录运行“openocd”以连接到开发板上的ST-LINK。 <code>openocd</code>会根据<code>openocd.cfg</code>文件,找到要使用的接口文件和目标文件。</p>
|
||
<pre><code class="language-console">$ cat openocd.cfg
|
||
</code></pre>
|
||
<pre><code class="language-text"># Sample OpenOCD configuration for the STM32F3DISCOVERY development board
|
||
|
||
# Depending on the hardware revision you got you'll have to pick ONE of these
|
||
# interfaces. At any time only one interface should be commented out.
|
||
|
||
# Revision C (newer revision)
|
||
source [find interface/stlink-v2-1.cfg]
|
||
|
||
# Revision A and B (older revisions)
|
||
# source [find interface/stlink-v2.cfg]
|
||
|
||
source [find target/stm32f3x.cfg]
|
||
</code></pre>
|
||
<blockquote>
|
||
<p><strong>注意</strong>如果您在<a href="../intro/install/verify.html">验证</a>部分发现开发板的版本较旧,则此时应修改<code>openocd.cfg</code>文件以使用<code>interface/stlink-v2.cfg</code>。</p>
|
||
</blockquote>
|
||
<pre><code class="language-console">$ openocd
|
||
Open On-Chip Debugger 0.10.0
|
||
Licensed under GNU GPL v2
|
||
For bug reports, read
|
||
http://openocd.org/doc/doxygen/bugs.html
|
||
Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
|
||
adapter speed: 1000 kHz
|
||
adapter_nsrst_delay: 100
|
||
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
|
||
none separate
|
||
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||
Info : Unable to match requested speed 1000 kHz, using 950 kHz
|
||
Info : clock speed 950 kHz
|
||
Info : STLINK v2 JTAG v27 API v2 SWIM v15 VID 0x0483 PID 0x374B
|
||
Info : using stlink api v2
|
||
Info : Target voltage: 2.913879
|
||
Info : stm32f3x.cpu: hardware has 6 breakpoints, 4 watchpoints
|
||
</code></pre>
|
||
<p>在另一个终端上,也从模板的根目录运行GDB。</p>
|
||
<pre><code class="language-console">$ <gdb> -q target/thumbv7em-none-eabihf/debug/examples/hello
|
||
</code></pre>
|
||
<p>接下来,将GDB连接到OpenOCD,OpenOCD正在监听端口3333。</p>
|
||
<pre><code class="language-console">(gdb) target remote :3333
|
||
Remote debugging using :3333
|
||
0x00000000 in ?? ()
|
||
</code></pre>
|
||
<p>现在,使用<code>load</code>命令将程序加载到微控制器上。</p>
|
||
<pre><code class="language-console">(gdb) load
|
||
Loading section .vector_table, size 0x400 lma 0x8000000
|
||
Loading section .text, size 0x1e70 lma 0x8000400
|
||
Loading section .rodata, size 0x61c lma 0x8002270
|
||
Start address 0x800144e, load size 10380
|
||
Transfer rate: 17 KB/sec, 3460 bytes/write.
|
||
</code></pre>
|
||
<p>现在程序已加载。该程序需要半主机支持,因此在进行任何半主机调用之前,我们必须告诉OpenOCD启用半主机。您可以使用“monitor”将命令发送到OpenOCD。</p>
|
||
<pre><code class="language-console">(gdb) monitor arm semihosting enable
|
||
semihosting is enabled
|
||
</code></pre>
|
||
<blockquote>
|
||
<p>您可以通过调用<code>monitor help</code>命令来查看所有OpenOCD命令。</p>
|
||
</blockquote>
|
||
<p>像之前一样,我们可以使用断点和<code>continue</code>跳过所有跳转到<code>main</code>函数。</p>
|
||
<pre><code class="language-console">(gdb) break main
|
||
Breakpoint 1 at 0x8000d18: file examples/hello.rs, line 15.
|
||
|
||
(gdb) continue
|
||
Continuing.
|
||
Note: automatically using hardware breakpoints for read-only addresses.
|
||
|
||
Breakpoint 1, main () at examples/hello.rs:15
|
||
15 let mut stdout = hio::hstdout().unwrap();
|
||
</code></pre>
|
||
<blockquote>
|
||
<p><strong>注意</strong>如果执行<code>continue</code>命令后GDB阻塞了终端而不是停在了断点上,则可能需要仔细检查<code>memory.x</code>文件中的内存区域信息是否配置正确(起始地址和长度)。</p>
|
||
</blockquote>
|
||
<p>用<code>next</code>命令替代刚刚的<code>continue</code>,应该也会产生相同的结果。</p>
|
||
<pre><code class="language-console">(gdb) next
|
||
16 writeln!(stdout, "Hello, world!").unwrap();
|
||
|
||
(gdb) next
|
||
19 debug::exit(debug::EXIT_SUCCESS);
|
||
</code></pre>
|
||
<p>此时,您应该看到"Hello, world!" 打印在OpenOCD控制台上,等等。</p>
|
||
<pre><code class="language-console">$ openocd
|
||
(..)
|
||
Info : halted: PC: 0x08000e6c
|
||
Hello, world!
|
||
Info : halted: PC: 0x08000d62
|
||
Info : halted: PC: 0x08000d64
|
||
Info : halted: PC: 0x08000d66
|
||
Info : halted: PC: 0x08000d6a
|
||
Info : halted: PC: 0x08000a0c
|
||
Info : halted: PC: 0x08000d70
|
||
Info : halted: PC: 0x08000d72
|
||
</code></pre>
|
||
<p>发出另一个<code>next</code>将使处理器执行<code>debug::exit</code>。这会像断点一样挂起程序的执行:</p>
|
||
<pre><code class="language-console">(gdb) next
|
||
|
||
Program received signal SIGTRAP, Trace/breakpoint trap.
|
||
0x0800141a in __syscall ()
|
||
</code></pre>
|
||
<p>OpenOCD控制台将会打印如下内容:</p>
|
||
<pre><code class="language-console">$ openocd
|
||
(..)
|
||
Info : halted: PC: 0x08001188
|
||
semihosting: *** application exited ***
|
||
Warn : target not halted
|
||
Warn : target not halted
|
||
target halted due to breakpoint, current mode: Thread
|
||
xPSR: 0x21000000 pc: 0x08000d76 msp: 0x20009fc0, semihosting
|
||
</code></pre>
|
||
<p>但是,在微控制器上运行的程序尚未终止,您可以使用<code>continue</code>或类似命令将其恢复。</p>
|
||
<p>现在,您可以使用“ quit”命令退出GDB。</p>
|
||
<pre><code class="language-console">(gdb) quit
|
||
</code></pre>
|
||
<p>现在调试需要更多步骤,因此我们将所有这些步骤打包到一个名为<code>openocd.gdb</code>的GDB脚本中。</p>
|
||
<pre><code class="language-console">$ cat openocd.gdb
|
||
</code></pre>
|
||
<pre><code class="language-text">target remote :3333
|
||
|
||
# print demangled symbols
|
||
set print asm-demangle on
|
||
|
||
# detect unhandled exceptions, hard faults and panics
|
||
break DefaultHandler
|
||
break HardFault
|
||
break rust_begin_unwind
|
||
|
||
monitor arm semihosting enable
|
||
|
||
load
|
||
|
||
# start the process but immediately halt the processor
|
||
stepi
|
||
</code></pre>
|
||
<p>现在运行 <code><gdb> -x openocd.gdb $program</code>将立即将GDB连接到OpenOCD,启用半主机,加载程序并开始执行。</p>
|
||
<p>您也可以将<code><gdb> -x openocd.gdb</code>转换为自定义运行器,这样<code>cargo run</code>会自动构建程序并开始GDB会话。该运行器已包含在<code>.cargo/config</code>中,只不过现在是被注释掉的状态。</p>
|
||
<pre><code class="language-console">$ head -n10 .cargo/config
|
||
</code></pre>
|
||
<pre><code class="language-toml">[target.thumbv7m-none-eabi]
|
||
# uncomment this to make `cargo run` execute programs on QEMU
|
||
# runner = "qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -semihosting-config enable=on,target=native -kernel"
|
||
|
||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||
# uncomment ONE of these three option to make `cargo run` start a GDB session
|
||
# which option to pick depends on your system
|
||
runner = "arm-none-eabi-gdb -x openocd.gdb"
|
||
# runner = "gdb-multiarch -x openocd.gdb"
|
||
# runner = "gdb -x openocd.gdb"
|
||
</code></pre>
|
||
<pre><code class="language-console">$ cargo run --example hello
|
||
(..)
|
||
Loading section .vector_table, size 0x400 lma 0x8000000
|
||
Loading section .text, size 0x1e70 lma 0x8000400
|
||
Loading section .rodata, size 0x61c lma 0x8002270
|
||
Start address 0x800144e, load size 10380
|
||
Transfer rate: 17 KB/sec, 3460 bytes/write.
|
||
(gdb)
|
||
</code></pre>
|
||
|
||
</main>
|
||
|
||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
<!-- Mobile navigation buttons -->
|
||
|
||
<a rel="prev" href="../start/qemu.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
|
||
|
||
<a rel="next" href="../start/registers.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
|
||
|
||
<div style="clear: both"></div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
|
||
<a rel="prev" href="../start/qemu.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
<i class="fa fa-angle-left"></i>
|
||
</a>
|
||
|
||
|
||
|
||
<a rel="next" href="../start/registers.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
<i class="fa fa-angle-right"></i>
|
||
</a>
|
||
|
||
</nav>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<script type="text/javascript">
|
||
window.playpen_copyable = true;
|
||
</script>
|
||
|
||
|
||
|
||
|
||
|
||
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
||
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
|
||
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
|
||
|
||
|
||
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
|
||
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
|
||
|
||
<!-- Custom JS scripts -->
|
||
|
||
|
||
|
||
|
||
</body>
|
||
</html>
|