<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="atom.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://haoge.org/blog</id>
    <title>Hao Ge's Lab Blog</title>
    <updated>2025-11-17T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://haoge.org/blog"/>
    <subtitle>Hao Ge's Lab Blog</subtitle>
    <icon>https://haoge.org/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[博客的自动部署方案]]></title>
        <id>https://haoge.org/blog/auto-deploy-blog</id>
        <link href="https://haoge.org/blog/auto-deploy-blog"/>
        <updated>2025-11-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[本站博客采用Markdown书写，在本地编辑完成后生成静态HTML文件，经 Git 推送至部署服务器，部署服务器基于 systemd 创建服务，实现自动部署。]]></summary>
        <content type="html"><![CDATA[<p>本站博客采用Markdown书写，在本地编辑完成后生成静态HTML文件，经 Git 推送至部署服务器，部署服务器基于 systemd 创建服务，实现自动部署。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="整体工作流程">整体工作流程<a href="https://haoge.org/blog/auto-deploy-blog#%E6%95%B4%E4%BD%93%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B" class="hash-link" aria-label="整体工作流程的直接链接" title="整体工作流程的直接链接" translate="no">​</a></h2>
<!-- -->
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_BuS1"><p>为了简化部署时的拷贝操作，所有 HTML 文件存放在 <strong>build</strong> 目录下。</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="本地构建与推送">本地构建与推送<a href="https://haoge.org/blog/auto-deploy-blog#%E6%9C%AC%E5%9C%B0%E6%9E%84%E5%BB%BA%E4%B8%8E%E6%8E%A8%E9%80%81" class="hash-link" aria-label="本地构建与推送的直接链接" title="本地构建与推送的直接链接" translate="no">​</a></h2>
<p>首先，在完成文章编辑及本地测试后，执行发布脚本生成 HTML 并提交到 Release 仓库。</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">release.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">#!/bin/zsh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 1. 执行 build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "🔨 正在构建项目..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">npm run build</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">if [ $? -ne 0 ]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "❌ 构建失败"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  exit 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "✅ 构建完成"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 2. 定义发布目录</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">RELEASE_DIR="../release-haoge-org"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 3. 检查发布目录是否存在，如果不存在则创建</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">if [ ! -d "$RELEASE_DIR" ]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  mkdir -p "$RELEASE_DIR"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "📁 创建目录: $RELEASE_DIR"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 4. 清空发布目录中除了 .git 和 .gitignore 以外的所有内容</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "🧹 清理发布目录..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rm -rf "$RELEASE_DIR/build"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cd - &gt; /dev/null</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 5. 复制 build 内容到发布目录</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "📋 复制构建内容..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">if [ -d "build" ]; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  cp -a build "$RELEASE_DIR/"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "✅ 内容复制完成"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">else</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "❌ 构建目录 build 不存在"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  exit 1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 6. 添加 git commit</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "💾 提交更改到Git..."</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">cd "$RELEASE_DIR"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 添加所有更改</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">git add .</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 检查是否有更改需要提交</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">if ! git diff-index --quiet HEAD --; then</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  TIMESTAMP=$(date -Iseconds)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  git commit -m "Deploy $TIMESTAMP"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "✅ Git提交完成"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  git push origin main</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">else</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  echo "ℹ️  没有更改需要提交"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">fi</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">echo "🎉 部署流程完成！"</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="自动化部署机制">自动化部署机制<a href="https://haoge.org/blog/auto-deploy-blog#%E8%87%AA%E5%8A%A8%E5%8C%96%E9%83%A8%E7%BD%B2%E6%9C%BA%E5%88%B6" class="hash-link" aria-label="自动化部署机制的直接链接" title="自动化部署机制的直接链接" translate="no">​</a></h2>
<p>当 Release 仓库的内容被推送到部署服务器时，需要一套自动化机制来完成后续的部署工作。这里采用了基于 Git Hooks 和 systemd 的解决方案。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="git-hook-触发机制">Git Hook 触发机制<a href="https://haoge.org/blog/auto-deploy-blog#git-hook-%E8%A7%A6%E5%8F%91%E6%9C%BA%E5%88%B6" class="hash-link" aria-label="Git Hook 触发机制的直接链接" title="Git Hook 触发机制的直接链接" translate="no">​</a></h3>
<p>Git Hooks 是 Git 提供的一种机制，允许我们在特定事件发生时执行自定义脚本。其中 <code>post-receive</code> 钩子会在 Git 服务器接收到推送内容后执行，非常适合用来触发后续的部署流程。</p>
<p>在部署服务上 Git 仓库的 <strong>post-receive</strong> 钩子脚本生成触发文件：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">/var/lib/git-repository/blog.git/hooks/post-receive</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">TRIGGER_FILE="/var/lib/git-repository/blog-trigger.txt"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mkdir -p `dirname $TRIGGER_FILE`</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">date &gt; "$TRIGGER_FILE"</span><br></span></code></pre></div></div>
<p>每当有新的推送到达时，这个脚本会创建或更新一个触发文件 (<code>blog-trigger.txt</code>)，作为后续部署流程的启动信号。</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_BuS1"><p>需保证git用户有写入触发文件的权限。</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="systemd-服务监听与响应">systemd 服务监听与响应<a href="https://haoge.org/blog/auto-deploy-blog#systemd-%E6%9C%8D%E5%8A%A1%E7%9B%91%E5%90%AC%E4%B8%8E%E5%93%8D%E5%BA%94" class="hash-link" aria-label="systemd 服务监听与响应的直接链接" title="systemd 服务监听与响应的直接链接" translate="no">​</a></h3>
<p>systemd 是 Linux 系统中的一个系统和服务管理器，提供了强大的服务管理功能。我们利用它的路径监控功能来监听触发文件的变化。</p>
<p><strong>systemd.path</strong> 配置文件用于监控触发文件的变更：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">/etc/systemd/system/blog-deploy.path</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain"># /etc/systemd/system/blog-deploy.path</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[Unit]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Description=Watch Git push trigger file</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[Path]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">PathModified=/var/lib/git-repository/blog-trigger.txt</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Unit=blog-deploy.service</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[Install]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">WantedBy=multi-user.target</span><br></span></code></pre></div></div>
<p>当 <code>blog-trigger.txt</code> 文件被修改时，systemd 会自动启动关联的 <code>blog-deploy.service</code> 服务。</p>
<p>相应的 <strong>systemd.service</strong> 配置文件定义了实际要执行的部署任务：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">/etc/systemd/system/blog-deploy.service</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain"># /etc/systemd/system/blog-deploy.service</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[Unit]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Description=Deploy Git repo (release branch) to web root</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">After=network.target</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[Service]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Type=oneshot</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">ExecStart=/usr/local/bin/deploy-blog.sh</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">User=root</span><br></span></code></pre></div></div>
<p>这里的 <code>Type=oneshot</code> 表示这是一个一次性执行的任务，而非持续运行的服务。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="实际部署脚本">实际部署脚本<a href="https://haoge.org/blog/auto-deploy-blog#%E5%AE%9E%E9%99%85%E9%83%A8%E7%BD%B2%E8%84%9A%E6%9C%AC" class="hash-link" aria-label="实际部署脚本的直接链接" title="实际部署脚本的直接链接" translate="no">​</a></h3>
<p>最后，<code>deploy-blog.sh</code> 脚本负责具体的部署操作：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">/usr/local/bin/deploy-blog.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">#!/usr/bin/env bash</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">set -e</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">BARE_REPO="/var/lib/git-repository/blog.git"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">DEST_DIR="/var/www/blog"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">TMP_WORK_TREE="/var/www/blog.build"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rm -rf $TMP_WORK_TREE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mkdir -p "$TMP_WORK_TREE"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">git clone "$BARE_REPO" "$TMP_WORK_TREE" </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rm -rf  $TMP_WORK_TREE/.git</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rm -rf $DEST_DIR</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mv $TMP_WORK_TREE/build $DEST_DIR</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">rm -rf $TMP_WORK_TREE</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">chown -R www-data:www-data $DEST_DIR</span><br></span></code></pre></div></div>
<p>该脚本会克隆最新的代码到临时目录，移除 Git 相关文件，然后将构建好的内容移动到 Web 服务器目录，并设置正确的文件权限。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="启用和测试服务">启用和测试服务<a href="https://haoge.org/blog/auto-deploy-blog#%E5%90%AF%E7%94%A8%E5%92%8C%E6%B5%8B%E8%AF%95%E6%9C%8D%E5%8A%A1" class="hash-link" aria-label="启用和测试服务的直接链接" title="启用和测试服务的直接链接" translate="no">​</a></h2>
<p>在添加上述服务文件后，需要启用对应的服务使之生效：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain"># 重新加载配置</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">sudo systemctl daemon-reload</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 启用并启动</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">sudo systemctl enable --now blog-deploy.path</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"># 查看状态</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">systemctl status blog-deploy.path</span><br></span></code></pre></div></div>
<p>可以通过手动更新触发文件来测试整个部署流程是否正常工作：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">date &gt; /var/lib/git-repository/blog-trigger.txt</span><br></span></code></pre></div></div>
<p>这套自动部署方案实现了从本地编辑到线上发布的全流程自动化，大大简化了博客内容的更新流程。</p>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="Git" term="Git"/>
        <category label="Markdown" term="Markdown"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[STM32F103C8T6 开发板 PB3 引脚作为普通 GPIO 引脚]]></title>
        <id>https://haoge.org/blog/stm32f1-pb3</id>
        <link href="https://haoge.org/blog/stm32f1-pb3"/>
        <updated>2025-11-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[STM32F1xx 系列的部分引脚默认作为 JTAG/SWD 调试接口引脚。官方文档对这些引脚的功能定义如下：]]></summary>
        <content type="html"><![CDATA[<p><strong>STM32F1xx</strong> 系列的部分引脚默认作为 <strong>JTAG</strong>/<strong>SWD</strong> 调试接口引脚。官方文档对这些引脚的功能定义如下：</p>
<table><thead><tr><th style="text-align:center">SWJ_CFG [2:0]</th><th style="text-align:center"><strong>JTAG-DP</strong></th><th>SW-DP</th><th>PA13 / JTMS / SWDIO</th><th>PA14 / JTCK/SWCLK</th><th>PA15 / JTDI</th><th>PB3 / JTDO/TRACE SWO</th><th>PB4 / NJTRST</th></tr></thead><tbody><tr><td style="text-align:center">000</td><td style="text-align:center">✅</td><td>✅</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td></tr><tr><td style="text-align:center">001</td><td style="text-align:center">✅</td><td>✅</td><td>❌</td><td>❌</td><td>❌</td><td>❌</td><td>✔️</td></tr><tr><td style="text-align:center">010</td><td style="text-align:center">🚫</td><td>✅</td><td>❌</td><td>❌</td><td>✔️</td><td>✔️</td><td>✔️</td></tr><tr><td style="text-align:center">100</td><td style="text-align:center">🚫</td><td>🚫</td><td>✔️</td><td>✔️</td><td>✔️</td><td>✔️</td><td>✔️</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>备注</div><div class="admonitionContent_BuS1"><ol>
<li class="">每次 <strong>Reset</strong> 后，默认模式为 000，即 <strong>JTAG-DP</strong> 和 <strong>SW-DP</strong> 都被启用。</li>
<li class="">激活 <strong>SWD</strong> 时，仅当调试器没有激活 <strong>SWO</strong> 时，<strong>PB3</strong> 引脚才可以作为普通 <strong>GPIO</strong> 引脚使用。</li>
</ol></div></div>
<p>HAL 库提供了如下宏来设置使用的 <strong>JTAG</strong>/<strong>SWD</strong> 模式：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">stm32f1xx_hal_gpio_ex.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @brief Enable the Serial wire JTAG configuration</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @note  ENABLE: Full SWJ (JTAG-DP + SW-DP): Reset State</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @retval None</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name function" style="color:#d73a49">__HAL_AFIO_REMAP_SWJ_ENABLE</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token macro property expression" style="color:#36acaa">  </span><span class="token macro property expression function" style="color:#d73a49">AFIO_DBGAFR_CONFIG</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression" style="color:#36acaa">AFIO_MAPR_SWJ_CFG_RESET</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @brief Enable the Serial wire JTAG configuration</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @note  NONJTRST: Full SWJ (JTAG-DP + SW-DP) but without NJTRST</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @retval None</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name function" style="color:#d73a49">__HAL_AFIO_REMAP_SWJ_NONJTRST</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token macro property expression" style="color:#36acaa">  </span><span class="token macro property expression function" style="color:#d73a49">AFIO_DBGAFR_CONFIG</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression" style="color:#36acaa">AFIO_MAPR_SWJ_CFG_NOJNTRST</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @brief Enable the Serial wire JTAG configuration</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @note  NOJTAG: **JTAG-DP**Disabled and SW-DP Enabled</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @retval None</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name function" style="color:#d73a49">__HAL_AFIO_REMAP_SWJ_NOJTAG</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token macro property expression" style="color:#36acaa">  </span><span class="token macro property expression function" style="color:#d73a49">AFIO_DBGAFR_CONFIG</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression" style="color:#36acaa">AFIO_MAPR_SWJ_CFG_JTAGDISABLE</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">/**</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @brief Disable the Serial wire JTAG configuration</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @note  DISABLE: **JTAG-DP**Disabled and SW-DP Disabled</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  * @retval None</span><br></span><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">  */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token macro property directive-hash" style="color:#36acaa">#</span><span class="token macro property directive keyword" style="color:#00009f">define</span><span class="token macro property" style="color:#36acaa"> </span><span class="token macro property macro-name function" style="color:#d73a49">__HAL_AFIO_REMAP_SWJ_DISABLE</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><span class="token macro property expression" style="color:#36acaa">  </span><span class="token macro property expression function" style="color:#d73a49">AFIO_DBGAFR_CONFIG</span><span class="token macro property expression punctuation" style="color:#393A34">(</span><span class="token macro property expression" style="color:#36acaa">AFIO_MAPR_SWJ_CFG_DISABLE</span><span class="token macro property expression punctuation" style="color:#393A34">)</span><br></span></code></pre></div></div>
<p>如果使用 <strong>CubeMX</strong> 生成的项目模板，则会在<code>HAL_MspInit()</code>中设置 <strong>JTAG</strong>/<strong>SWD</strong> 模式，例如：</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">stm32f1xx_hal_msp.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">void</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">HAL_MspInit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">__HAL_RCC_AFIO_CLK_ENABLE</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">__HAL_RCC_PWR_CLK_ENABLE</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// **JTAG-DP**Disabled and SW-DP Enabled</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">__HAL_AFIO_REMAP_SWJ_NOJTAG</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>使用 <strong>SWD</strong> 调试，在关闭 <strong>SWO</strong> 功能时 <strong>PB3</strong> 引脚就可以作为普通 <strong>GPIO</strong> 引脚使用。使用 <strong>VSCode</strong> 调试时，修改启动配置文件<code>launch.json</code>，删除或关闭 <strong>swoConfig</strong> 配置项即可关闭 <strong>SWO</strong> 功能 ：</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">launch.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"showDevDebugOutput"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"raw"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"showDevDebugTimestamps"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"cwd"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"${workspaceRoot}"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"executable"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"build/Debug/${workspaceRootFolderName}.elf"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"name"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Launch STM32"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"request"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"launch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"cortex-debug"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"servertype"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"openocd"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"preLaunchTask"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"CMake: build"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"device"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"STM32F103C8"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"svdFile"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./STM32F103.svd"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"runToEntryPoint"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"main"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"configFiles"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">"openocd.cfg"</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">"swoConfig"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"enabled"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"source"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"probe"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"swoFrequency"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">115200</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"cpuFrequency"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">72000000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"decoders"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"port"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"type"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"console"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"label"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"SWO output"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token property" style="color:#36acaa">"encoding"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ascii"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>问题排查</div><div class="admonitionContent_BuS1"><p>如果按照上述配置后 <strong>PB3</strong> 仍无法作为普通 <strong>GPIO</strong> 引脚 使用，请进行以下检查：</p><ol>
<li class="">确认在调试器终端选项中 <strong>SWO</strong> 功能已确实关闭，如 <strong>VSCode</strong> 终端下确实没有 <strong>SWO</strong> 终端了</li>
<li class="">断开电源并重新上电，确保配置生效</li>
<li class="">检查代码中是否正确调用了相应的 <strong>GPIO</strong> 初始化函数</li>
</ol></div></div>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="STM32" term="STM32"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Github 网络访问疑难杂症]]></title>
        <id>https://haoge.org/blog/github-network-issue</id>
        <link href="https://haoge.org/blog/github-network-issue"/>
        <updated>2024-11-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[配置代理]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="配置代理">配置代理<a href="https://haoge.org/blog/github-network-issue#%E9%85%8D%E7%BD%AE%E4%BB%A3%E7%90%86" class="hash-link" aria-label="配置代理的直接链接" title="配置代理的直接链接" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git config --global http.proxy 192.168.10.2:20172</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">git config --global https.proxy 192.168.10.2:20172</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">git config --global http.version HTTP/1.1 </span><br></span></code></pre></div></div>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="GitHub" term="GitHub"/>
        <category label="Git" term="Git"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[基于MINGW编译arm-none-eabi-gcc 14.1]]></title>
        <id>https://haoge.org/blog/build-mingw-toolchain</id>
        <link href="https://haoge.org/blog/build-mingw-toolchain"/>
        <updated>2024-09-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[准备编译环境]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="准备编译环境">准备编译环境<a href="https://haoge.org/blog/build-mingw-toolchain#%E5%87%86%E5%A4%87%E7%BC%96%E8%AF%91%E7%8E%AF%E5%A2%83" class="hash-link" aria-label="准备编译环境的直接链接" title="准备编译环境的直接链接" translate="no">​</a></h2>
<p>安装必要包：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pacman -S --needed base-devel</span><br></span></code></pre></div></div>
<p>下载MINGW包仓库</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">git clone https://kkgithub.com/msys2/MINGW-packages.git</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="编译arm-none-eabi-binutils">编译arm-none-eabi-binutils<a href="https://haoge.org/blog/build-mingw-toolchain#%E7%BC%96%E8%AF%91arm-none-eabi-binutils" class="hash-link" aria-label="编译arm-none-eabi-binutils的直接链接" title="编译arm-none-eabi-binutils的直接链接" translate="no">​</a></h2>
<ol>
<li class="">修改<code>MINGW-packages/mingw-w64-arm-none-eabi-binutils/PKGBUILD</code>的<code>pkgber</code>和<code>pkgrel</code>：</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pkgver=2.42</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pkgrel=1</span><br></span></code></pre></div></div>
<ol start="2">
<li class="">修改checksum</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cd MINGW-packages/mingw-w64-arm-none-eabi-binutils</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">updpkgsums </span><br></span></code></pre></div></div>
<ol start="3">
<li class="">编译</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">makepkg-mingw --cleanbuild --syncdeps --force --install --noconfirm</span><br></span></code></pre></div></div>
<blockquote>
<p>如果提示gpg key错误，可以<code>gpg --recv-keys ${keys}</code>导入key。</p>
</blockquote>
<ol start="4">
<li class="">测试</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="编译arm-none-eabi-gcc">编译arm-none-eabi-gcc<a href="https://haoge.org/blog/build-mingw-toolchain#%E7%BC%96%E8%AF%91arm-none-eabi-gcc" class="hash-link" aria-label="编译arm-none-eabi-gcc的直接链接" title="编译arm-none-eabi-gcc的直接链接" translate="no">​</a></h2>
<ol>
<li class="">修改<code>MINGW-packages/mingw-w64-arm-none-eabi-gcc/PKGBUILD</code>的<code>pkgber</code>和<code>pkgrel</code>：</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">pkgver=14.1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">pkgrel=1</span><br></span></code></pre></div></div>
<ol start="2">
<li class="">更新checksum</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">cd MINGW-packages/mingw-w64-arm-none-eabi-gcc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">updpkgsums </span><br></span></code></pre></div></div>
<ol start="3">
<li class="">编译</li>
</ol>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">makepkg-mingw --cleanbuild --syncdeps --force --install --noconfirm</span><br></span></code></pre></div></div>
<ol start="4">
<li class="">测试</li>
</ol>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="STM32" term="STM32"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[STLink Mini刷v2固件]]></title>
        <id>https://haoge.org/blog/stlink-v2</id>
        <link href="https://haoge.org/blog/stlink-v2"/>
        <updated>2024-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[1. 解除Read Protection]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-解除read-protection">1. 解除Read Protection<a href="https://haoge.org/blog/stlink-v2#1-%E8%A7%A3%E9%99%A4read-protection" class="hash-link" aria-label="1. 解除Read Protection的直接链接" title="1. 解除Read Protection的直接链接" translate="no">​</a></h2>
<p>STLink V2的bootloader开启了Read Protection，导致起始的8KB Flash不能被修改，在刷写Flash前需要解除Read Protection。</p>
<p>可以使用<strong>openocd</strong>命令来解锁：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">openocd -f interface/stlink.cfg -f target/stm32f1x.cfg \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "init" -c "reset init" \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "stm32f1x unlock 0; reset init" \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "reset" -c "shutdown"</span><br></span></code></pre></div></div>
<p>输出如下：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Open On-Chip Debugger 0.12.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Licensed under GNU GPL v2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">For bug reports, read</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	http://openocd.org/doc/doxygen/bugs.html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &lt;transport&gt;'.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : clock speed 1000 kHz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : STLINK V2J43S7 (API v2) VID:PID 0483:3748</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : Target voltage: 3.102632</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Warn : UNEXPECTED idcode: 0x2ba01477</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Error: expected 1 of 1: 0x1ba01477</span><br></span></code></pre></div></div>
<p>看上去是手上的板子使用的仿制的mcu，在openocd安装目录(如*/usr/local/Cellar/open-ocd/0.12.0_1/share/openocd/scripts/target*)下找到target/stm32f1x.cfg，复制一份并命名为apm32f1x.cfg，将apm32f1x.cfg里的0x1ba01477修改为0x2ba01477:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#jtag scan chain</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">if { [info exists CPUTAPID] } {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   set _CPUTAPID $CPUTAPID</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">} else {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   if { [using_jtag] } {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      # See STM Document RM0008 Section 26.6.3</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      set _CPUTAPID 0x3ba00477</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   } {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      # this is the SW-DP tap id not the jtag tap id</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      set _CPUTAPID 0x2ba01477 #  &lt;== replace 0x1ba01477 with 0x2ba01477!</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span></code></pre></div></div>
<p>再次尝试使用<strong>openocd</strong>解锁flash：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">openocd -f interface/stlink.cfg -f target/apm32f1x.cfg -c "init" -c "reset init" -c "stm32f1x unlock 0; reset init" -c "reset" -c "shutdown"</span><br></span></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Open On-Chip Debugger 0.12.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Licensed under GNU GPL v2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">For bug reports, read</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	http://openocd.org/doc/doxygen/bugs.html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &lt;transport&gt;'.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : DEPRECATED target event trace-config; use TPIU events {pre,post}-{enable,disable}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : clock speed 1000 kHz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : STLINK V2J43S7 (API v2) VID:PID 0483:3748</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : Target voltage: 3.083684</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : [apm32f1x.cpu] Cortex-M3 r2p1 processor detected</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : [apm32f1x.cpu] target has 6 breakpoints, 4 watchpoints</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : starting gdb server for apm32f1x.cpu on 3333</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : Listening on port 3333 for gdb connections</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[apm32f1x.cpu] halted due to debug-request, current mode: Thread </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : device id = 0x20036410</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : flash size = 128 KiB</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[apm32f1x.cpu] halted due to debug-request, current mode: Thread </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">shutdown command invoked</span><br></span></code></pre></div></div>
<p>可以看到解锁成功，并且这个仿制的mcu是128KB的，可以刷V2.1的固件。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-备份旧固件">2. 备份旧固件<a href="https://haoge.org/blog/stlink-v2#2-%E5%A4%87%E4%BB%BD%E6%97%A7%E5%9B%BA%E4%BB%B6" class="hash-link" aria-label="2. 备份旧固件的直接链接" title="2. 备份旧固件的直接链接" translate="no">​</a></h2>
<p>openocd的flash命令可以备份固件：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">flash read_bank bank_id filename [offset [length]]</span><br></span></code></pre></div></div>
<p>确认bank_id：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">openocd -f interface/stlink.cfg -f target/apm32f1x.cfg -c "init" -c "reset init" -c "flash banks"</span><br></span></code></pre></div></div>
<p>输出如下：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Open On-Chip Debugger 0.12.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[apm32f1x.cpu] halted due to debug-request, current mode: Thread </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xPSR: 0x01000000 pc: 0x08002e0c msp: 0x20001ce0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">#0 : apm32f1x.flash (stm32f1x) at 0x08000000, size 0x00000000, buswidth 0, chipwidth 0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">openocd -f interface/stlink.cfg -f target/apm32f1x.cfg -c "init" -c "reset init" -c "flash read_bank 0 stlink-old.bin"</span><br></span></code></pre></div></div>
<p>输出如下：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Open On-Chip Debugger 0.12.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : device id = 0x20036410</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : flash size = 128 KiB</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">wrote 131072 bytes to file stlink-old.bin from flash bank 0 at offset 0x00000000 in 2.005690s (63.818 KiB/s)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-刷st-link-v2-1固�件">3. 刷ST-Link v2-1固件<a href="https://haoge.org/blog/stlink-v2#3-%E5%88%B7st-link-v2-1%E5%9B%BA%E4%BB%B6" class="hash-link" aria-label="3. 刷ST-Link v2-1固件的直接链接" title="3. 刷ST-Link v2-1固件的直接链接" translate="no">​</a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">% openocd -f interface/stlink.cfg -f target/apm32f1x.cfg \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "init" -c "reset init" \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "program STLinkV2.J28.M18_unprotection.bin 0x08000000" \</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-c "reset" -c "shutdown"</span><br></span></code></pre></div></div>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Open On-Chip Debugger 0.12.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Licensed under GNU GPL v2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">For bug reports, read</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">	http://openocd.org/doc/doxygen/bugs.html</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : auto-selecting first available session transport "hla_swd". To override use 'transport select &lt;transport&gt;'.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : DEPRECATED target event trace-config; use TPIU events {pre,post}-{enable,disable}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : clock speed 1000 kHz</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : STLINK V2J43S7 (API v2) VID:PID 0483:3748</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : Target voltage: 3.085263</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : [apm32f1x.cpu] Cortex-M3 r2p1 processor detected</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : [apm32f1x.cpu] target has 6 breakpoints, 4 watchpoints</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : starting gdb server for apm32f1x.cpu on 3333</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : Listening on port 3333 for gdb connections</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[apm32f1x.cpu] halted due to debug-request, current mode: Thread </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[apm32f1x.cpu] halted due to debug-request, current mode: Thread </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">** Programming Started **</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : device id = 0x20036410</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Info : flash size = 128 KiB</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">** Programming Finished **</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">shutdown command invoked</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-更新固件">4. 更新固件<a href="https://haoge.org/blog/stlink-v2#4-%E6%9B%B4%E6%96%B0%E5%9B%BA%E4%BB%B6" class="hash-link" aria-label="4. 更新固件的直接链接" title="4. 更新固件的直接链接" translate="no">​</a></h2>
<p>使用官方的stm32 cube programmer更新固件。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-参考资料">5. 参考资料<a href="https://haoge.org/blog/stlink-v2#5-%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99" class="hash-link" aria-label="5. 参考资料的直接链接" title="5. 参考资料的直接链接" translate="no">​</a></h2>
<ol>
<li class=""><a href="https://shequ.stmicroelectronics.cn/thread-617075-1-1.html" target="_blank" rel="noopener noreferrer" class="">廉价仿真器STLINK-V2变身V2-1，J-LINK-OB，CMSIS-DAP，DAPLink</a></li>
<li class=""><a href="https://github-wiki-see.page/m/devanlai/DAPLink/wiki/Installing-Firmware" target="_blank" rel="noopener noreferrer" class="">Installing Firmware - devanlai/DAPLink GitHub Wiki</a></li>
<li class=""><a href="https://www.st.com/en/development-tools/stm32cubeprog.html" target="_blank" rel="noopener noreferrer" class="">stm32 cube programmer</a></li>
</ol>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="STM32" term="STM32"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[VSCode STM32 Debug 问题分析]]></title>
        <id>https://haoge.org/blog/arm-gnu-toolchain-debug-issue</id>
        <link href="https://haoge.org/blog/arm-gnu-toolchain-debug-issue"/>
        <updated>2024-08-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Windows环境，使用VSCode调试STM32时，从点Debug按钮开始到板子启动需等待20s左右，这明显不太正常。当前使用的主要工具：]]></summary>
        <content type="html"><![CDATA[<p>Windows环境，使用VSCode调试STM32时，从点Debug按钮开始到板子启动需等待20s左右，这明显不太正常。当前使用的主要工具：</p>
<ul>
<li class=""><a href="https://openocd.org/" target="_blank" rel="noopener noreferrer" class="">openocd-0.12</a></li>
<li class=""><a href="https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads" target="_blank" rel="noopener noreferrer" class="">arm-gnu-toolchain-13.2.rel1</a></li>
<li class=""><a href="https://github.com/Marus/cortex-debug" target="_blank" rel="noopener noreferrer" class="">cortex-debug-1.12.1</a></li>
</ul>
<p>先将Cortex-Debug的Debug Timestamps选项打开：</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">.vscode/launch.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token property" style="color:#36acaa">"configurations"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token property" style="color:#36acaa">"showDevDebugOutput"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"raw"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            </span><span class="token property" style="color:#36acaa">"showDevDebugTimestamps"</span><span class="token operator" style="color:#393A34">:</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div>
<p>按<strong>F5</strong>开启Debug，打开底部<strong>gdb-server</strong>终端，发现openocd启动很快，查看底部<strong>调试</strong>控制台，发现在<a href="https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-File-Commands.html" target="_blank" rel="noopener noreferrer" class="">file-exec-and-symbols</a>卡住10多秒：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">10-file-exec-and-symbols</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-&gt; 10^done</span><br></span></code></pre></div></div>
<p>此处应该就是问题所在了，对应的<a href="https://github.com/Marus/cortex-debug/blob/master/src/gdb.ts#L904" target="_blank" rel="noopener noreferrer" class="">Cortex-Debug源代码</a>：</p>
<div class="language-type-script codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">src/gdb.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-type-script codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">private startGdb(response: DebugProtocol.LaunchResponse): Promise&lt;void&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    } else {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">        this.gdbInitCommands.push(`file-exec-and-symbols "${this.args.executable}"`);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    const ret = this.miDebugger.start(this.args.cwd, this.gdbInitCommands);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    return ret;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span></code></pre></div></div>
<p>Cortex-Debug是以<a href="https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI.html" target="_blank" rel="noopener noreferrer" class="">mi2</a>方式调用的gdb，先试试手动调用gdb：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">arm-none-eabi-gdb  --interpreter=mi2</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(gdb)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">-file-exec-and-symbols ${efi-file}</span><br></span></code></pre></div></div>
<p>同样会卡住10多秒，可以确认是gdb解析符号时出问题了。换了几个不同版本的工具链测试对比测试下结果如下：</p>
<table><thead><tr><th>Toolchain</th><th>结果</th></tr></thead><tbody><tr><td>Windows arm-gnu-toolchain-13.2.rel1</td><td>卡</td></tr><tr><td>Windows arm-gnu-toolchain-12.3.rel1</td><td>卡</td></tr><tr><td>Windows MSYS2 gdb</td><td>不卡</td></tr><tr><td>Windows MSYS2 gdb-multiarch</td><td>不卡</td></tr><tr><td>MacOS Brew arm-none-eabi-gdb</td><td>不卡</td></tr><tr><td>Windows xPack arm-none-eabi-gdb</td><td>不卡</td></tr></tbody></table>
<p>只有ARM家的工具链有这个问题，改用xPack提供的工具链完美解决此问题。</p>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="STM32" term="STM32"/>
        <category label="VSCode" term="VSCode"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[MacOS npm 网络访问疑难杂症]]></title>
        <id>https://haoge.org/blog/npm-network-issue</id>
        <link href="https://haoge.org/blog/npm-network-issue"/>
        <updated>2024-08-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[镜像]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="镜像">镜像<a href="https://haoge.org/blog/npm-network-issue#%E9%95%9C%E5%83%8F" class="hash-link" aria-label="镜像的直接链接" title="镜像的直接链接" translate="no">​</a></h2>
<p>npm一般需要通过镜像来访问，国内常见的镜像有:</p>
<ul>
<li class="">yarn <a href="https://registry.yarnpkg.com/" target="_blank" rel="noopener noreferrer" class="">https://registry.yarnpkg.com/</a></li>
<li class="">tencent <a href="https://mirrors.cloud.tencent.com/npm/" target="_blank" rel="noopener noreferrer" class="">https://mirrors.cloud.tencent.com/npm/</a></li>
<li class="">cnpm <a href="https://r.cnpmjs.org/" target="_blank" rel="noopener noreferrer" class="">https://r.cnpmjs.org/</a></li>
<li class="">taobao <a href="https://registry.npmmirror.com/" target="_blank" rel="noopener noreferrer" class="">https://registry.npmmirror.com/</a></li>
<li class="">npmMirror <a href="https://skimdb.npmjs.com/registry/" target="_blank" rel="noopener noreferrer" class="">https://skimdb.npmjs.com/registry/</a></li>
<li class="">ustc <a href="https://npmreg.proxy.ustclug.org/" target="_blank" rel="noopener noreferrer" class="">https://npmreg.proxy.ustclug.org/</a></li>
</ul>
<p>推荐使用nrm管理要使用的镜像:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">npm --registry https://registry.npmmirror.com install nrm</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">nrm use tencent</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ca证书问题">CA证书问题<a href="https://haoge.org/blog/npm-network-issue#ca%E8%AF%81%E4%B9%A6%E9%97%AE%E9%A2%98" class="hash-link" aria-label="CA证书问题的直接链接" title="CA证书问题的直接链接" translate="no">​</a></h2>
<p>在通过镜像使用<code>npm install</code>时，大概率会提示<code>unable to get local issuer certificate</code>，这需要配置好npm使用的CA证书。</p>
<p>安装必要CA证书：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">brew install ca-certificates</span><br></span></code></pre></div></div>
<p>设置npm使用的CA证书：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">npm config set cafile /usr/local/share/ca-certificates/cacert.pem</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="其它问题">其它问题<a href="https://haoge.org/blog/npm-network-issue#%E5%85%B6%E5%AE%83%E9%97%AE%E9%A2%98" class="hash-link" aria-label="其它问题的直接链接" title="其它问题的直接链接" translate="no">​</a></h2>
<p><code>node-gyp</code>需要本地机场的辅助访问，方式如下：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">node-gyp install --proxy=&lt;http://proxy_addr:port&gt; --cafile=/usr/local/share/ca-certificates/cacert.pem</span><br></span></code></pre></div></div>]]></content>
        <author>
            <name>Hale Chan</name>
            <uri>https://github.com/halechan</uri>
        </author>
        <category label="node" term="node"/>
        <category label="npm" term="npm"/>
    </entry>
</feed>