<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Laning's Blog</title><link>https://blog.laning.org/</link><description>Recent content on Laning's Blog</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Tue, 10 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.laning.org/index.xml" rel="self" type="application/rss+xml"/><item><title>Hello World</title><link>https://blog.laning.org/posts/2026-11-10-hello-world/</link><pubDate>Tue, 10 Nov 2026 00:00:00 +0000</pubDate><guid>https://blog.laning.org/posts/2026-11-10-hello-world/</guid><description>我的第一篇 Hugo 博客文章</description></item><item><title>异步函数async和await</title><link>https://blog.laning.org/posts/wp-0446/</link><pubDate>Thu, 10 Apr 2025 15:34:47 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0446/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;最近在回头看&lt;a href="https://github.com/laningya/nfd/blob/main/worker.js"&gt;nfd项目&lt;/a&gt; 的源码，看到了使用async和await的js代码，因此想了解一下代码运行的机制。&lt;/p&gt;
&lt;h2 id="一个例子"&gt;一个例子&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function SicBo() {
return new Promise((resolve, reject) =&amp;gt; {
console.log(&amp;#34;开始摇&amp;#34;)
setTimeout(() =&amp;gt; {
let n = parseInt(Math.random() * 6 + 1, 10)
resolve(n)
}, 1000)
})
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="上述代码的执行过程如下"&gt;上述代码的执行过程如下：&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;立即执行 &lt;code&gt;console.log(&amp;quot;开始摇&amp;quot;)&lt;/code&gt;&lt;/strong&gt; —— ✅ 马上输出。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;启动一个“1秒后执行的任务”&lt;/strong&gt; —— 通过 &lt;code&gt;setTimeout(...)&lt;/code&gt; 注册了一个回调，1 秒后执行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;返回一个 Promise 对象&lt;/strong&gt;，这个 Promise 会在 1 秒后变成“完成状态”并给出点数。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="如果直接调用这个函数"&gt;如果直接调用这个函数：&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function test() {
const result = SicBo()
console.log(&amp;#39;骰子结果:&amp;#39;, result)
}
test()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;调用输出如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;开始摇
骰子结果: Promise { &amp;lt;pending&amp;gt; }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;显然并不是我们想要的结果&lt;/p&gt;
&lt;h3 id="异步函数的一般调用"&gt;异步函数的一般调用：&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SicBo().then(result =&amp;gt; {
console.log(&amp;#39;骰子结果:&amp;#39;, result)
})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这种写法最大的弊端是会产生回调地狱，即调用多个异步函数产生嵌套，导致代码可读性变差。&lt;/p&gt;</description></item><item><title>TG机器人通知IP地址</title><link>https://blog.laning.org/posts/wp-0442/</link><pubDate>Wed, 09 Apr 2025 18:38:01 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0442/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;公网IPv4政策的收紧，包括不限于不能使用DDNS服务解析到未备案域名，因此使用TG机器人API服务，定时检测IP地址，若IP变化则自动更新&lt;/p&gt;
&lt;h2 id="项目地址"&gt;项目地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/telegram-ip-bot.sh"&gt;Raspberry-Pi/shell/telegram-ip-bot.sh at master · laningya/Raspberry-Pi · GitHub&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="部署过程"&gt;部署过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;获取ChatID&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;API_TOKEN=&amp;#34;YOUR_BOT_TOKEN&amp;#34;
curl -s &amp;#34;https://api.telegram.org/bot$API_TOKEN/getUpdates&amp;#34; | jq &amp;#39;.result[0].message.chat.id&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;脚本填入Bot的API Token，以及自行判断需要设置代理&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加crontab定时任务&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;*/30 * * * * /bin/bash /root/telegram-ip-bot.sh &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="参考文档"&gt;参考文档&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://core.telegram.org/bots/api"&gt;Telegram Bot API&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Emby反代及HTTPS配置教程</title><link>https://blog.laning.org/posts/wp-0433/</link><pubDate>Sat, 01 Mar 2025 12:18:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0433/</guid><description>&lt;h2 id="nginx配置"&gt;Nginx配置&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;server {
listen 443 ssl;
server_name your.domain.com;
# Security / XSS Mitigation Headers
add_header X-Frame-Options &amp;#34;SAMEORIGIN&amp;#34;;
add_header X-XSS-Protection &amp;#34;1; mode=block&amp;#34;;
add_header X-Content-Type-Options &amp;#34;nosniff&amp;#34;;
# ssl的设置
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_session_timeout 5m;
# 禁止ip访问
if ($host ~ ^\d+\.\d+\.\d+\.\d+$) {
return 404;
}
# 防止爬虫获取header，直接访问/就返回502，其他的路径才行，app观看不影响，不用这个
location = / {
return 502;
}
location / {
resolver 1.1.1.1 ipv6=off;
if ($host != $server_name) {
return 403;
}
proxy_pass https://www.emby.com;
# ssl pass相关的设置
proxy_ssl_name www.emby.com;
proxy_ssl_server_name on;
proxy_set_header Host www.emby.com;
set $magpiecdn &amp;#34;$scheme://$server_name:$server_port&amp;#34;;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header MagpieCDN $magpiecdn;
proxy_buffering off;
}
location /***cdn {
resolver 1.1.1.1 ipv6=off;
proxy_pass https://$arg_load.emby.com;
# ssl pass相关的设置
proxy_ssl_name $arg_load.emby.com;
proxy_ssl_server_name on;
proxy_set_header Host $arg_load.emby.com;
proxy_buffering on;
proxy_max_temp_file_size 50m;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>通过LangBot将大模型接入到Telergram</title><link>https://blog.laning.org/posts/wp-0430/</link><pubDate>Fri, 14 Feb 2025 13:05:18 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0430/</guid><description>&lt;h2 id="项目地址"&gt;项目地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/RockChinQ/LangBot"&gt;GitHub - RockChinQ/LangBot: 😎丰富生态、🧩支持扩展、🦄多模态 - 大模型原生即时通信机器人平台 | 适配 QQ / 微信（企业微信、个人微信）/ 飞书 / 钉钉 / Discord / Telegram 等消息平台 | 支持 ChatGPT、DeepSeek、Dify、Claude、Gemini、xAI Grok、Ollama、LM Studio、阿里云百炼、火山方舟、SiliconFlow、Qwen、Moonshot、ChatGLM、SillyTraven、MCP 等 LLM 的机器人 / Agent | LLM-based instant messaging bots platform, supports Discord, Telegram, WeChat, Lark, DingTalk, QQ&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="部署过程"&gt;部署过程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Git 克隆项目：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/RockChinQ/LangBot
cd LangBot
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;启动容器：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;在 LangBot 中填写信息并启动&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;将Telegram Bot的API Token 填写到platform.json中。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; {
&amp;#34;adapter&amp;#34;: &amp;#34;telegram&amp;#34;,
&amp;#34;enable&amp;#34;: true,
&amp;#34;token&amp;#34;: &amp;#34;xxxxxxx&amp;#34;
},
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;填写完成后启动 LangBot，若成功配置，日志中会出现&lt;code&gt;[02-02 16:48:15.263] manager.py (68) - [INFO] : 初始化平台适配器 1: telegram&lt;/code&gt;的字样，保持 LangBot 运行。&lt;/p&gt;</description></item><item><title>Cloudflare和阿里云DDNS的Shell实现</title><link>https://blog.laning.org/posts/wp-0426/</link><pubDate>Thu, 06 Feb 2025 11:24:47 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0426/</guid><description>&lt;h2 id="下一步开发计划"&gt;下一步开发计划&lt;/h2&gt;
&lt;p&gt;接入Telegram机器人，IP变化时自动通知&lt;/p&gt;
&lt;h2 id="脚本地址"&gt;脚本地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/cfddns.sh"&gt;raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/cfddns.sh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/aliddns.sh"&gt;raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/aliddns.sh&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用说明"&gt;使用说明&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Cloudflare&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;proxy=false/true，是否开始Cloudflare小黄云选项&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ZONE_ID，API_TOKEN，Cloudflare 域ID和API令牌，API需对应域名的DNS编辑和读取权限&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;IPv4Domain，需要填写全写，如&amp;quot;test.yourdomain.com&amp;quot;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;阿里云&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;accessKeyId,accessSecret，需要在阿里云控制台获取，并赋予DNS编辑和读取权限&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;与Cloudflare不同，子域名和主域名分开&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>使用 Telegram 作为存储后端的图床程序</title><link>https://blog.laning.org/posts/wp-0421/</link><pubDate>Wed, 04 Dec 2024 16:18:29 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0421/</guid><description>&lt;h2 id="项目地址"&gt;项目地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/nodeseeker/goImage"&gt;GitHub - nodeseeker/goImage: 基于 Go 开发的图片托管服务，使用 Telegram 作为存储后端。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/laningya/goImage"&gt;GitHub - laningya/goImage: 基于 Go 开发的图片托管服务，使用 Telegram 作为存储后端。&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="部署流程"&gt;部署流程&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;拉取Dockerfile并本地构建镜像&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/laningya/goImage/refs/heads/main/Dockerfile
docker build -t image .
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;拉取docker-compose.yml文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/laningya/goImage/refs/heads/main/docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;拉取config.json文件&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/laningya/goImage/refs/heads/main/config.json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;config.json文件说明如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
&amp;#34;telegram&amp;#34;: {
&amp;#34;token&amp;#34;: &amp;#34;1234567890:ABCDEFG_ab1-asdfghjkl12345&amp;#34;,
&amp;#34;chatId&amp;#34;: -123456789
},
&amp;#34;admin&amp;#34;: {
&amp;#34;username&amp;#34;: &amp;#34;nodeseeker&amp;#34;,
&amp;#34;password&amp;#34;: &amp;#34;nodeseeker@123456&amp;#34;
},
&amp;#34;site&amp;#34;: {
&amp;#34;name&amp;#34;: &amp;#34;NodeSeek&amp;#34;,
&amp;#34;maxFileSize&amp;#34;: 10,
&amp;#34;port&amp;#34;: 18080,
&amp;#34;host&amp;#34;: &amp;#34;127.0.0.1&amp;#34;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;telegram.token&lt;/code&gt;：电报机器人的Bot Token&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;telegram.chatId&lt;/code&gt;：频道的Chat ID&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;admin.username&lt;/code&gt;：网站管理员用户名&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;admin.password&lt;/code&gt;：网站管理员密码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;site.name&lt;/code&gt;：网站名称&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;site.maxFileSize&lt;/code&gt;：最大上传文件大小（单位：MB），建议10MB&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;site.port&lt;/code&gt;：服务端口，默认18080&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;site.host&lt;/code&gt;：服务监听地址，默认127.0.0.0本地监听；如果需要调试或外网访问，可修改为0.0.0.0&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上参数获取方式：&lt;/p&gt;</description></item><item><title>基于Cloudflare Worker的Telegram传信机器人</title><link>https://blog.laning.org/posts/wp-0424/</link><pubDate>Thu, 05 Sep 2024 17:20:01 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0424/</guid><description>&lt;h2 id="项目原因"&gt;项目原因&lt;/h2&gt;
&lt;p&gt;Telegram是很注重隐私的聊天软件，受到很多人的青睐。但是，如果经常和陌生人聊天很容易触发风控，因此一款好用的传信机器人十分有必要。&lt;/p&gt;
&lt;h2 id="项目特色"&gt;项目特色&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在nfdv1项目的基础上增加提示对方ID（TG账户唯一标识）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;美化输出UI，以及封禁逻辑&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持构建欺诈数据库，有不良记录的用户及时提醒&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="部署方法"&gt;部署方法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;从&lt;a href="https://t.me/BotFather"&gt;@BotFather&lt;/a&gt;获取token，并且可以发送&lt;code&gt;/setjoingroups&lt;/code&gt;来禁止此Bot被添加到群组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从&lt;a href="https://www.uuidgenerator.net/"&gt;uuidgenerator&lt;/a&gt;获取一个随机uuid作为secret&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从&lt;a href="https://t.me/username_to_id_bot"&gt;@username_to_id_bot&lt;/a&gt;获取你的用户id&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;登录&lt;a href="https://workers.cloudflare.com/"&gt;cloudflare&lt;/a&gt;，创建一个worker&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置worker的变量&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;增加一个&lt;code&gt;ENV_BOT_TOKEN&lt;/code&gt;变量，数值为从步骤1中获得的token&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;增加一个&lt;code&gt;ENV_BOT_SECRET&lt;/code&gt;变量，数值为从步骤2中获得的secret&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;增加一个&lt;code&gt;ENV_ADMIN_UID&lt;/code&gt;变量，数值为从步骤3中获得的用户id&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;绑定kv数据库，创建一个Namespace Name为&lt;code&gt;nfd&lt;/code&gt;的kv数据库，在setting -&amp;gt; variable中设置&lt;code&gt;KV Namespace Bindings&lt;/code&gt;：nfd -&amp;gt; nfd&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击&lt;code&gt;Quick Edit&lt;/code&gt;，复制&lt;a href="worker.js"&gt;这个文件&lt;/a&gt;到编辑器中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过打开&lt;code&gt;https://xxx.workers.dev/registerWebhook&lt;/code&gt;来注册websoket&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="使用方法"&gt;使用方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;当其他用户给bot发消息，会被转发到bot创建者&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户回复普通文字给转发的消息时，会回复到原消息发送者&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;用户回复&lt;code&gt;/block&lt;/code&gt;, &lt;code&gt;/unblock&lt;/code&gt;, &lt;code&gt;/checkblock&lt;/code&gt;等命令会执行相关指令，&lt;strong&gt;不会&lt;/strong&gt;回复到原消息发送者&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>服务备份与同步脚本实现</title><link>https://blog.laning.org/posts/wp-0428/</link><pubDate>Tue, 06 Aug 2024 14:21:25 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0428/</guid><description>&lt;h2 id="脚本地址"&gt;脚本地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/back.sh"&gt;raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/back.sh&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/rsync.sh"&gt;raw.githubusercontent.com/laningya/Raspberry-Pi/refs/heads/master/shell/rsync.sh&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用说明"&gt;使用说明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;为防止服务器宕机开发，需要配合crontab等服务实现定时备份&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;针对采用docker-compose部署的服务编写，如为其他方式部署的服务，此脚本并不使用&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Armbian/build脚本分析</title><link>https://blog.laning.org/posts/wp-0380/</link><pubDate>Thu, 06 Jun 2024 13:44:10 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0380/</guid><description>&lt;h2 id="1-脚本目录检测和代码健壮性保证"&gt;1. 脚本目录检测和代码健壮性保证&lt;/h2&gt;
&lt;h3 id="11-程序报错退出脚本"&gt;1.1 程序报错退出脚本&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#set -o pipefail # trace ERR through pipes - will be enabled &amp;#34;soon&amp;#34;
#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled
set -e
set -o errtrace # trace ERR through - enabled
set -o errexit ## set -e : exit the script if any statement returns a non-true return value - enabled
# Important, go read http://mywiki.wooledge.org/BashFAQ/105 NOW!
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="12-compilesh脚本目录检测"&gt;1.2. ./compile.sh脚本目录检测&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SRC=&amp;#34;$(dirname &amp;#34;$(realpath &amp;#34;${BASH_SOURCE[0]}&amp;#34;)&amp;#34;)&amp;#34;
cd &amp;#34;${SRC}&amp;#34; || exit
# check for whitespace in ${SRC} and exit for safety reasons
grep -q &amp;#34;[[:space:]]&amp;#34; &amp;lt;&amp;lt;&amp;lt; &amp;#34;${SRC}&amp;#34; &amp;amp;&amp;amp; {
echo &amp;#34;\&amp;#34;${SRC}\&amp;#34; contains whitespace. Not supported. Aborting.&amp;#34; &amp;gt;&amp;amp;2
exit 1
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="2-singlesh-文件加载位于lib"&gt;2. single.sh 文件加载（位于./lib）&lt;/h2&gt;
&lt;h3 id="21-检查bash版本是否高于5x"&gt;2.1 检查bash版本是否高于5.x&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# The Armbian functions require Bash 5.x.
if [[ &amp;#34;${BASH_VERSINFO:-0}&amp;#34; -lt 5 ]]; then
echo &amp;#34;Armbian build scripts require Bash 5.x. Go get it...&amp;#34; &amp;gt;&amp;amp;2
if [[ &amp;#34;${OSTYPE}&amp;#34; == &amp;#34;darwin&amp;#34;* ]]; then
echo &amp;#34;Armbian build scripts require brew to be installed and working on macOS. (old Bash version)&amp;#34; &amp;gt;&amp;amp;2
echo &amp;#34;Please install brew, *restart your terminal*.&amp;#34; &amp;gt;&amp;amp;2
echo &amp;#34;Then run &amp;#39;brew install bash coreutils git&amp;#39;, *restart your terminal* and then try again.&amp;#34; &amp;gt;&amp;amp;2
exit 51
fi
exit 50
fi
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="22-macos系统检查"&gt;2.2 macOS系统检查&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;是否以root运行脚本&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Homebrew 包管理器已安装并正常工作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过 Homebrew 的 &lt;code&gt;coreutils&lt;/code&gt; 安装的 &lt;code&gt;realpath&lt;/code&gt; 命令是否可用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;更新 &lt;code&gt;PATH&lt;/code&gt; 环境变量以包含由 Homebrew 安装的 GNU &lt;code&gt;coreutils&lt;/code&gt; 二进制文件。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;确保 &lt;code&gt;${SRC}&lt;/code&gt; 变量（应指向构建脚本的源目录）位于用户的主目录中。这对于 macOS 上的 Docker 兼容性很重要。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>玩客云刷Openwrt/Armbian</title><link>https://blog.laning.org/posts/wp-0378/</link><pubDate>Sat, 01 Jun 2024 10:56:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0378/</guid><description>&lt;h2 id="玩客云配置"&gt;玩客云配置&lt;/h2&gt;
&lt;p&gt;SOC为晶晨S805，ARM 4核1.5GHz，1G(DDR3)+8G(eMMC)，两个USB 2.0，HDMI接口，一个千兆网口（RJ45 ），一个SD卡槽。&lt;/p&gt;
&lt;h2 id="刷机工具下载"&gt;刷机工具下载&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://pan.baidu.com/share/init?surl=CSKqhwEIOBXXi1-2-oG0dw&amp;amp;pwd=pirb"&gt;百度网盘 请输入提取码 (baidu.com)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.right.com.cn/forum/thread-8275843-1-1.html"&gt;更新 2024.04.15 OPENWRT高内核直刷 玩客云ws1608/赚钱宝三代和赚钱宝2代WS1508-PCDN、玩客云、京东云等各种云设备-恩山无线论坛 (right.com.cn)&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://github.com/hzyitc/armbian-onecloud"&gt;GitHub - hzyitc/armbian-onecloud: Armbian for onecloud. 玩客云用armbian&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="刷入openwrtarmbian"&gt;刷入Openwrt/Armbian&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;打开USB_Burning_Tool软件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;短接触点上电，进入刷机模式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;刷写系统到emmc&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="参考文档"&gt;参考文档&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://www.cnblogs.com/ban1234/p/17083431.html"&gt;玩客云刷软路由保姆教程 - 流云1 - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/p&gt;</description></item><item><title>sing-box TUN模式透明代理</title><link>https://blog.laning.org/posts/wp-0372/</link><pubDate>Sat, 27 Apr 2024 01:16:33 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0372/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;你的软路由到底是用来做旁路由还是主路由？如果是旁路由的话，只用科学上网不妨试试Linux旁路由网关&lt;/p&gt;
&lt;h2 id="docker镜像构建"&gt;docker镜像构建&lt;/h2&gt;
&lt;p&gt;原本是64位的处理器，可惜之前装的32位操作系统，所以只能从Dockerfile自己构建喽&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;拉源码&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone https://github.com/SagerNet/sing-box.git
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;构建镜像&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker build --no-cache -t laningya/sing-box:v1 .
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="docker-composeyml文件"&gt;docker-compose.yml文件&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;version: &amp;#34;3.3&amp;#34;
services:
sing-box:
image: laningya/sing-box:v1
container_name: sing-box
restart: always
network_mode: &amp;#34;host&amp;#34;
volumes:
- ./conf:/etc/sing-box/
devices:
- /dev/net/tun:/dev/net/tun
cap_add:
- ALL
command: -D /var/lib/sing-box -C /etc/sing-box/ run
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要开启tun模式，devices和cap_add字段非常重要&lt;/p&gt;
&lt;h2 id="一个不错的sing-box配置模板"&gt;一个不错的sing-box配置模板&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
&amp;#34;dns&amp;#34;: {
&amp;#34;servers&amp;#34;: [
{
&amp;#34;tag&amp;#34;: &amp;#34;dns_proxy&amp;#34;,
&amp;#34;address&amp;#34;: &amp;#34;https://1.1.1.1/dns-query&amp;#34;,
&amp;#34;address_resolver&amp;#34;: &amp;#34;dns_resolver&amp;#34;,
&amp;#34;strategy&amp;#34;: &amp;#34;ipv4_only&amp;#34;,
&amp;#34;detour&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;tag&amp;#34;: &amp;#34;dns_direct&amp;#34;,
&amp;#34;address&amp;#34;: &amp;#34;h3://dns.alidns.com/dns-query&amp;#34;,
&amp;#34;address_resolver&amp;#34;: &amp;#34;dns_resolver&amp;#34;,
&amp;#34;strategy&amp;#34;: &amp;#34;ipv4_only&amp;#34;,
&amp;#34;detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;tag&amp;#34;: &amp;#34;dns_block&amp;#34;,
&amp;#34;address&amp;#34;: &amp;#34;rcode://refused&amp;#34;
},
{
&amp;#34;tag&amp;#34;: &amp;#34;dns_resolver&amp;#34;,
&amp;#34;address&amp;#34;: &amp;#34;223.5.5.5&amp;#34;,
&amp;#34;strategy&amp;#34;: &amp;#34;ipv4_only&amp;#34;,
&amp;#34;detour&amp;#34;: &amp;#34;direct&amp;#34;
}
],
&amp;#34;rules&amp;#34;: [
{
&amp;#34;outbound&amp;#34;: &amp;#34;any&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;dns_resolver&amp;#34;
},
{
&amp;#34;clash_mode&amp;#34;: &amp;#34;direct&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;dns_direct&amp;#34;
},
{
&amp;#34;clash_mode&amp;#34;: &amp;#34;global&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
},
{
&amp;#34;process_name&amp;#34;: [
&amp;#34;TencentMeeting&amp;#34;,
&amp;#34;NemoDesktop&amp;#34;,
&amp;#34;ToDesk&amp;#34;,
&amp;#34;ToDesk_Service&amp;#34;,
&amp;#34;WeChat&amp;#34;,
&amp;#34;Tailscale&amp;#34;,
&amp;#34;wireguard-go&amp;#34;,
&amp;#34;Tunnelblick&amp;#34;,
&amp;#34;softwareupdated&amp;#34;,
&amp;#34;kubectl&amp;#34;
],
&amp;#34;server&amp;#34;: &amp;#34;dns_direct&amp;#34;
},
{
&amp;#34;domain_suffix&amp;#34;: [
&amp;#34;icloudnative.io&amp;#34;,
&amp;#34;fuckcloudnative.io&amp;#34;,
&amp;#34;sealos.io&amp;#34;,
&amp;#34;cdn.jsdelivr.net&amp;#34;
],
&amp;#34;server&amp;#34;: &amp;#34;dns_direct&amp;#34;
},
{
&amp;#34;process_name&amp;#34;: [
&amp;#34;DropboxMacUpdate&amp;#34;,
&amp;#34;Dropbox&amp;#34;
],
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
},
{
&amp;#34;package_name&amp;#34;: [
&amp;#34;com.google.android.youtube&amp;#34;,
&amp;#34;com.android.vending&amp;#34;,
&amp;#34;org.telegram.messenger&amp;#34;,
&amp;#34;org.telegram.plus&amp;#34;
],
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;geosite-geolocation-!cn&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;Global&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: [
&amp;#34;YouTube&amp;#34;,
&amp;#34;Telegram&amp;#34;,
&amp;#34;Netflix&amp;#34;,
&amp;#34;geoip-google&amp;#34;,
&amp;#34;geoip-telegram&amp;#34;,
&amp;#34;geoip-twitter&amp;#34;,
&amp;#34;geoip-netflix&amp;#34;
],
&amp;#34;server&amp;#34;: &amp;#34;dns_proxy&amp;#34;
}
],
&amp;#34;final&amp;#34;: &amp;#34;dns_direct&amp;#34;
},
&amp;#34;ntp&amp;#34;: {
&amp;#34;enabled&amp;#34;: true,
&amp;#34;server&amp;#34;: &amp;#34;time.apple.com&amp;#34;,
&amp;#34;server_port&amp;#34;: 123,
&amp;#34;interval&amp;#34;: &amp;#34;30m0s&amp;#34;,
&amp;#34;detour&amp;#34;: &amp;#34;direct&amp;#34;
},
&amp;#34;inbounds&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;tun&amp;#34;,
&amp;#34;inet4_address&amp;#34;: &amp;#34;198.18.0.1/16&amp;#34;,
&amp;#34;auto_route&amp;#34;: true,
&amp;#34;exclude_package&amp;#34;: [
&amp;#34;cmb.pb&amp;#34;,
&amp;#34;cn.gov.pbc.dcep&amp;#34;,
&amp;#34;com.MobileTicket&amp;#34;,
&amp;#34;com.adguard.android&amp;#34;,
&amp;#34;com.ainemo.dragoon&amp;#34;,
&amp;#34;com.alibaba.android.rimet&amp;#34;,
&amp;#34;com.alicloud.databox&amp;#34;,
&amp;#34;com.amazing.cloudisk.tv&amp;#34;,
&amp;#34;com.autonavi.minimap&amp;#34;,
&amp;#34;com.bilibili.app.in&amp;#34;,
&amp;#34;com.bishua666.luxxx1&amp;#34;,
&amp;#34;com.cainiao.wireless&amp;#34;,
&amp;#34;com.chebada&amp;#34;,
&amp;#34;com.chinamworld.main&amp;#34;,
&amp;#34;com.cmbchina.ccd.pluto.cmbActivity&amp;#34;,
&amp;#34;com.coolapk.market&amp;#34;,
&amp;#34;com.ctrip.ct&amp;#34;,
&amp;#34;com.dianping.v1&amp;#34;,
&amp;#34;com.douban.frodo&amp;#34;,
&amp;#34;com.eg.android.AlipayGphone&amp;#34;,
&amp;#34;com.farplace.qingzhuo&amp;#34;,
&amp;#34;com.hanweb.android.zhejiang.activity&amp;#34;,
&amp;#34;com.leoao.fitness&amp;#34;,
&amp;#34;com.lucinhu.bili_you&amp;#34;,
&amp;#34;com.mikrotik.android.tikapp&amp;#34;,
&amp;#34;com.moji.mjweather&amp;#34;,
&amp;#34;com.motorola.cn.calendar&amp;#34;,
&amp;#34;com.motorola.cn.lrhealth&amp;#34;,
&amp;#34;com.netease.cloudmusic&amp;#34;,
&amp;#34;com.sankuai.meituan&amp;#34;,
&amp;#34;com.sina.weibo&amp;#34;,
&amp;#34;com.smartisan.notes&amp;#34;,
&amp;#34;com.sohu.inputmethod.sogou.moto&amp;#34;,
&amp;#34;com.sonelli.juicessh&amp;#34;,
&amp;#34;com.ss.android.article.news&amp;#34;,
&amp;#34;com.ss.android.lark&amp;#34;,
&amp;#34;com.ss.android.ugc.aweme&amp;#34;,
&amp;#34;com.tailscale.ipn&amp;#34;,
&amp;#34;com.taobao.idlefish&amp;#34;,
&amp;#34;com.taobao.taobao&amp;#34;,
&amp;#34;com.tencent.mm&amp;#34;,
&amp;#34;com.tencent.mp&amp;#34;,
&amp;#34;com.tencent.soter.soterserver&amp;#34;,
&amp;#34;com.tencent.wemeet.app&amp;#34;,
&amp;#34;com.tencent.weread&amp;#34;,
&amp;#34;com.tencent.wework&amp;#34;,
&amp;#34;com.ttxapps.wifiadb&amp;#34;,
&amp;#34;com.unionpay&amp;#34;,
&amp;#34;com.unnoo.quan&amp;#34;,
&amp;#34;com.wireguard.android&amp;#34;,
&amp;#34;com.xingin.xhs&amp;#34;,
&amp;#34;com.xunmeng.pinduoduo&amp;#34;,
&amp;#34;com.zui.zhealthy&amp;#34;,
&amp;#34;ctrip.android.view&amp;#34;,
&amp;#34;io.kubenav.kubenav&amp;#34;,
&amp;#34;org.geekbang.geekTime&amp;#34;,
&amp;#34;tv.danmaku.bili&amp;#34;
],
&amp;#34;stack&amp;#34;: &amp;#34;mixed&amp;#34;,
&amp;#34;sniff&amp;#34;: true
},
{
&amp;#34;type&amp;#34;: &amp;#34;socks&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;socks-in&amp;#34;,
&amp;#34;listen&amp;#34;: &amp;#34;::&amp;#34;,
&amp;#34;listen_port&amp;#34;: 5353
}
],
&amp;#34;outbounds&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;selector&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;select&amp;#34;,
&amp;#34;outbounds&amp;#34;: [
&amp;#34;trojan-out&amp;#34;
],
&amp;#34;default&amp;#34;: &amp;#34;trojan-out&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;selector&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;openai&amp;#34;,
&amp;#34;outbounds&amp;#34;: [
&amp;#34;trojan-out&amp;#34;
],
&amp;#34;default&amp;#34;: &amp;#34;trojan-out&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;selector&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;tiktok&amp;#34;,
&amp;#34;outbounds&amp;#34;: [
&amp;#34;trojan-out&amp;#34;
],
&amp;#34;default&amp;#34;: &amp;#34;trojan-out&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;trojan&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;trojan-out&amp;#34;,
&amp;#34;server&amp;#34;: &amp;#34;199.180.115.155&amp;#34;,
&amp;#34;server_port&amp;#34;: 9443,
&amp;#34;password&amp;#34;: &amp;#34;5iFHKMrn9Ez//VKh6zChTA==&amp;#34;,
&amp;#34;tls&amp;#34;: {
&amp;#34;enabled&amp;#34;: true,
&amp;#34;server_name&amp;#34;: &amp;#34;ss.icloudnative.io&amp;#34;,
&amp;#34;insecure&amp;#34;: true,
&amp;#34;utls&amp;#34;: {
&amp;#34;fingerprint&amp;#34;: &amp;#34;chrome&amp;#34;
}
},
&amp;#34;multiplex&amp;#34;: {
&amp;#34;protocol&amp;#34;: &amp;#34;h2mux&amp;#34;,
&amp;#34;max_connections&amp;#34;: 4,
&amp;#34;min_streams&amp;#34;: 4
},
&amp;#34;transport&amp;#34;: {
&amp;#34;type&amp;#34;: &amp;#34;grpc&amp;#34;,
&amp;#34;service_name&amp;#34;: &amp;#34;TunService&amp;#34;
}
},
{
&amp;#34;type&amp;#34;: &amp;#34;direct&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;block&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;block&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;dns&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;dns-out&amp;#34;
}
],
&amp;#34;route&amp;#34;: {
&amp;#34;rules&amp;#34;: [
{
&amp;#34;protocol&amp;#34;: &amp;#34;dns&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;dns-out&amp;#34;
},
{
&amp;#34;clash_mode&amp;#34;: &amp;#34;direct&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;clash_mode&amp;#34;: &amp;#34;global&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;domain_suffix&amp;#34;: [
&amp;#34;icloudnative.io&amp;#34;,
&amp;#34;fuckcloudnative.io&amp;#34;,
&amp;#34;sealos.io&amp;#34;,
&amp;#34;cdn.jsdelivr.net&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;process_name&amp;#34;: [
&amp;#34;TencentMeeting&amp;#34;,
&amp;#34;NemoDesktop&amp;#34;,
&amp;#34;ToDesk&amp;#34;,
&amp;#34;ToDesk_Service&amp;#34;,
&amp;#34;WeChat&amp;#34;,
&amp;#34;OpenLens&amp;#34;,
&amp;#34;Tailscale&amp;#34;,
&amp;#34;wireguard-go&amp;#34;,
&amp;#34;Tunnelblick&amp;#34;,
&amp;#34;softwareupdated&amp;#34;,
&amp;#34;kubectl&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;protocol&amp;#34;: &amp;#34;quic&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;block&amp;#34;
},
{
&amp;#34;inbound&amp;#34;: &amp;#34;socks-in&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: [
&amp;#34;WeChat&amp;#34;,
&amp;#34;Bilibili&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;OpenAI&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;openai&amp;#34;
},
{
&amp;#34;domain_suffix&amp;#34;: [
&amp;#34;openai.com&amp;#34;,
&amp;#34;oaistatic.com&amp;#34;,
&amp;#34;oaiusercontent.com&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;openai&amp;#34;
},
{
&amp;#34;package_name&amp;#34;: &amp;#34;com.openai.chatgpt&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;openai&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;TikTok&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;tiktok&amp;#34;
},
{
&amp;#34;package_name&amp;#34;: &amp;#34;com.zhiliaoapp.musically&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;tiktok&amp;#34;
},
{
&amp;#34;domain_suffix&amp;#34;: [
&amp;#34;depay.one&amp;#34;,
&amp;#34;orbstack.dev&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;process_name&amp;#34;: [
&amp;#34;DropboxMacUpdate&amp;#34;,
&amp;#34;Dropbox&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;package_name&amp;#34;: [
&amp;#34;com.google.android.youtube&amp;#34;,
&amp;#34;com.android.vending&amp;#34;,
&amp;#34;org.telegram.messenger&amp;#34;,
&amp;#34;org.telegram.plus&amp;#34;,
&amp;#34;com.google.android.googlequicksearchbox&amp;#34;,
&amp;#34;app.rvx.android.youtube&amp;#34;,
&amp;#34;com.mudvod.video&amp;#34;,
&amp;#34;com.fox2code.mmm&amp;#34;,
&amp;#34;com.twitter.android&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;domain&amp;#34;: &amp;#34;accounts.google.com&amp;#34;,
&amp;#34;domain_suffix&amp;#34;: [
&amp;#34;sourceforge.net&amp;#34;,
&amp;#34;fhjasokiwq.com&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;domain_suffix&amp;#34;: &amp;#34;cloud.sealos.io&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;logical&amp;#34;,
&amp;#34;mode&amp;#34;: &amp;#34;and&amp;#34;,
&amp;#34;rules&amp;#34;: [
{
&amp;#34;rule_set&amp;#34;: &amp;#34;geosite-geolocation-!cn&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;geoip-cn&amp;#34;,
&amp;#34;invert&amp;#34;: true
}
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;Global&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: &amp;#34;geoip-cn&amp;#34;,
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;ip_is_private&amp;#34;: true,
&amp;#34;outbound&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;rule_set&amp;#34;: [
&amp;#34;YouTube&amp;#34;,
&amp;#34;Telegram&amp;#34;,
&amp;#34;Netflix&amp;#34;,
&amp;#34;geoip-google&amp;#34;,
&amp;#34;geoip-telegram&amp;#34;,
&amp;#34;geoip-twitter&amp;#34;,
&amp;#34;geoip-netflix&amp;#34;
],
&amp;#34;outbound&amp;#34;: &amp;#34;select&amp;#34;
}
],
&amp;#34;rule_set&amp;#34;: [
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geosite-geolocation-!cn&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geoip-cn&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-cn.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geoip-google&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-google.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geoip-telegram&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-telegram.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geoip-twitter&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-twitter.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;geoip-netflix&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;binary&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-netflix.srs&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;Global&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Global.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;YouTube&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/YouTube.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;OpenAI&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/OpenAI.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;TikTok&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/TikTok.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;Telegram&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Telegram.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;Netflix&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Netflix.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;WeChat&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/WeChat.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
},
{
&amp;#34;type&amp;#34;: &amp;#34;remote&amp;#34;,
&amp;#34;tag&amp;#34;: &amp;#34;Bilibili&amp;#34;,
&amp;#34;format&amp;#34;: &amp;#34;source&amp;#34;,
&amp;#34;url&amp;#34;: &amp;#34;https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Bilibili.json&amp;#34;,
&amp;#34;download_detour&amp;#34;: &amp;#34;direct&amp;#34;
}
],
&amp;#34;final&amp;#34;: &amp;#34;direct&amp;#34;,
&amp;#34;find_process&amp;#34;: true,
&amp;#34;auto_detect_interface&amp;#34;: true
},
&amp;#34;experimental&amp;#34;: {
&amp;#34;cache_file&amp;#34;: {
&amp;#34;enabled&amp;#34;: true
},
&amp;#34;clash_api&amp;#34;: {
&amp;#34;external_controller&amp;#34;: &amp;#34;0.0.0.0:9090&amp;#34;,
&amp;#34;external_ui&amp;#34;: &amp;#34;metacubexd&amp;#34;,
&amp;#34;external_ui_download_url&amp;#34;: &amp;#34;https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip&amp;#34;,
&amp;#34;external_ui_download_detour&amp;#34;: &amp;#34;select&amp;#34;,
&amp;#34;default_mode&amp;#34;: &amp;#34;rule&amp;#34;
}
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="开启内核转发并关闭防火墙"&gt;开启内核转发并关闭防火墙&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;echo 1 &amp;gt; /proc/sys/net/ipv4/ip_forward
ufw disable
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="参考地址"&gt;参考地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://icloudnative.io/posts/sing-box-tutorial/"&gt;icloudnative.io&lt;/a&gt;&lt;/p&gt;</description></item><item><title>甲骨文防火墙设置</title><link>https://blog.laning.org/posts/wp-0370/</link><pubDate>Fri, 26 Apr 2024 10:50:59 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0370/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;甲骨文啊，你真狗！甲骨文除了与其他云厂商一样有防火墙面板，额外在系统镜像上也默认配置了防火墙，这直接导致开机更换ssh端口从而机器失联。。。&lt;/p&gt;
&lt;h2 id="面板防火墙设置"&gt;面板防火墙设置&lt;/h2&gt;
&lt;p&gt;不多说，与其他云厂商没有多大区别&lt;/p&gt;
&lt;h2 id="系统镜像关闭防火墙"&gt;系统镜像关闭防火墙&lt;/h2&gt;
&lt;h3 id="开放所有端口ubuntudebian"&gt;开放所有端口（Ubuntu、Debian）&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -F
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="关闭防火墙"&gt;关闭防火墙&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apt-get purge netfilter-persistent &amp;amp;&amp;amp; reboot
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="参考文章"&gt;参考文章&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://isedu.top/index.php/archives/33/"&gt;Oracle开放全部端口并关闭防火墙 - 清~幽殇 (isedu.top)&lt;/a&gt;&lt;/p&gt;</description></item><item><title>哪吒监控部署</title><link>https://blog.laning.org/posts/wp-0363/</link><pubDate>Mon, 22 Apr 2024 20:03:20 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0363/</guid><description>&lt;h2 id="演示站点"&gt;演示站点&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://dash.laning.org/"&gt;laning&amp;rsquo;s dashboard&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="项目起因"&gt;项目起因&lt;/h2&gt;
&lt;p&gt;手上的vps逐渐多了起来，还是可以玩一下监控面板&lt;/p&gt;
&lt;h2 id="主要特性"&gt;主要特性&lt;/h2&gt;
&lt;p&gt;cloudflare CDN + caddy反代&lt;/p&gt;
&lt;h2 id="部署过程"&gt;部署过程&lt;/h2&gt;
&lt;h3 id="官方参考文档"&gt;官方参考文档&lt;/h3&gt;
&lt;h4 id="文档地址"&gt;文档地址&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://nezha.wiki/guide/dashboard.html"&gt;哪吒监控 | 哪吒监控 (nezha.wiki)&lt;/a&gt;&lt;/p&gt;
&lt;h4 id="主要步骤"&gt;主要步骤&lt;/h4&gt;
&lt;p&gt;参考文档拉取源码并docker部署，接入github作为管理账号，配置cf的cdn代理&lt;/p&gt;
&lt;h3 id="docker部署caddy反代"&gt;docker部署caddy反代&lt;/h3&gt;
&lt;h4 id="docker-composeyml"&gt;docker-compose.yml&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;version: &amp;#39;3.3&amp;#39;
services:
caddy:
image: caddy
container_name: caddy
hostname: caddy
restart: always
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
- ./caddy/config:/config
network_mode: host
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="caddyfile"&gt;Caddyfile&lt;/h4&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cdn.example.com
encode gzip
reverse_proxy 127.0.0.1:8008
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="icmptcp-公用ip探针"&gt;ICMP/TCP 公用IP探针&lt;/h3&gt;
&lt;h4 id="文档地址-1"&gt;文档地址&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.nodeseek.com/post-68572-1"&gt;【存】全国 34 省份 TCPING v4 IP (nodeseek.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/nxtrace/NTrace-V1/blob/main/fast_trace/basic.go"&gt;NTrace-V1/fast_trace/basic.go at main · nxtrace/NTrace-V1 (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="故障通知机器人配置"&gt;故障通知机器人配置&lt;/h3&gt;
&lt;h4 id="文档地址-2"&gt;文档地址&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://nezha.wiki/guide/notifications.html"&gt;哪吒监控 | 哪吒监控 (nezha.wiki)&lt;/a&gt;&lt;/p&gt;</description></item><item><title>VPS测试脚本</title><link>https://blog.laning.org/posts/wp-0305/</link><pubDate>Sun, 14 Apr 2024 11:08:01 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0305/</guid><description>&lt;h2 id="三网回程测试脚本"&gt;三网回程测试脚本&lt;/h2&gt;
&lt;h3 id="脚本地址"&gt;脚本地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/zhanghanyun/backtrace"&gt;zhanghanyun/backtrace: 三网回程路由测试 (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="命令行"&gt;命令行&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl https://raw.githubusercontent.com/zhanghanyun/backtrace/main/install.sh -sSf | sh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="流媒体gpt解锁测试脚本"&gt;流媒体/GPT解锁测试脚本&lt;/h2&gt;
&lt;h3 id="脚本地址-1"&gt;脚本地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/lmc999/RegionRestrictionCheck"&gt;lmc999/RegionRestrictionCheck: A bash script to check the status of your IP on various geo-restricted services. (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="命令行-1"&gt;命令行&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;bash &amp;lt;(curl -L -s check.unlock.media)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="bbr加速"&gt;BBR加速&lt;/h2&gt;
&lt;h3 id="脚本地址-2"&gt;脚本地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/Chikage0o0/Linux-NetSpeed"&gt;Chikage0o0/Linux-NetSpeed: 将Linux现常用的网络加速集成在一起 (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="命令行-2"&gt;命令行&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wget -N --no-check-certificate &amp;#34;https://raw.githubusercontent.com/chiakge/Linux-NetSpeed/master/tcp.sh&amp;#34; &amp;amp;&amp;amp; chmod +x tcp.sh &amp;amp;&amp;amp; ./tcp.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="缝合怪"&gt;缝合怪&lt;/h2&gt;
&lt;h3 id="脚本地址-3"&gt;脚本地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/spiritLHLS/ecs/blob/main/README.md"&gt;ecs/README.md at main · spiritLHLS/ecs (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="命令行-3"&gt;命令行&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl -L https://gitlab.com/spiritysdx/za/-/raw/main/ecs.sh -o ecs.sh &amp;amp;&amp;amp; chmod +x ecs.sh &amp;amp;&amp;amp; bash ecs.sh
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="xraycli安装脚本"&gt;XrayCLI安装脚本&lt;/h2&gt;
&lt;h3 id="脚本地址-4"&gt;脚本地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/233boy/Xray/wiki/Xray%E4%B8%80%E9%94%AE%E5%AE%89%E8%A3%85%E8%84%9A%E6%9C%AC"&gt;Xray一键安装脚本 · 233boy/Xray Wiki (github.com)&lt;/a&gt;&lt;/p&gt;</description></item><item><title>cloudflare 科学环境</title><link>https://blog.laning.org/posts/wp-0299/</link><pubDate>Thu, 04 Apr 2024 17:19:15 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0299/</guid><description>&lt;p&gt;2024/11/24更新：项目已失效&lt;/p&gt;
&lt;h2 id="warp"&gt;warp+&lt;/h2&gt;
&lt;h3 id="流量获取"&gt;流量获取&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://t.me/generatewarpplusbot"&gt;tg机器人&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="windows客户端"&gt;windows客户端&lt;/h3&gt;
&lt;p&gt;设置代理端口+Proxy SwitchyOmega分流&lt;/p&gt;
&lt;h3 id="订阅转clash等订阅链接"&gt;订阅转clash等订阅链接&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker pull vvbbnn00/warp-clash-api
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="https://github.com/vvbbnn00/WARP-Clash-API"&gt;vvbbnn00/WARP-Clash-API: 该项目可以让你通过订阅的方式使用Cloudflare WARP+，自动获取流量。This project enables you to use Cloudflare WARP+ through subscription, automatically acquiring traffic. (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="展示地址"&gt;展示地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://blog.laning.ltd:21001/"&gt;click here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="cloudflare-反向代理"&gt;cloudflare 反向代理&lt;/h2&gt;
&lt;h3 id="开源项目"&gt;开源项目&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/3Kmfi6HP/EDtunnel"&gt;3Kmfi6HP/EDtunnel: Use Cloudflare pages and worker serverless to implement VLESS protocol (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="参考文章"&gt;参考文章&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://jdssl.top/index.php/2023/08/02/newvless/"&gt;免费翻墙，批量vless节点，反代伪装网页，轻松跑满本地宽带 (jdssl.top)&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="展示地址-1"&gt;展示地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://helloworld.610524250.workers.dev/785f7047-3c97-47c5-a63f-e1b408386baa"&gt;click here&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Jellyfin on NanoPC-T4</title><link>https://blog.laning.org/posts/wp-0290/</link><pubDate>Tue, 19 Mar 2024 14:40:38 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0290/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;受限于jellyfin对rk3399等ARM处理器视频硬件解码的支持，搭建的Jellyfin服务都采用客户端解码。&lt;/p&gt;
&lt;h2 id="docker部署jellifin"&gt;docker部署Jellifin&lt;/h2&gt;
&lt;h3 id="docker-composeyml文件"&gt;docker-compose.yml文件&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;version: &amp;#39;3.3&amp;#39;
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
network_mode: &amp;#39;host&amp;#39;
volumes:
- ./config:/config
- ./cache:/cache
- ./media:/media
# - /path/to/media2:/media2:ro
restart: &amp;#39;unless-stopped&amp;#39;
# Optional - alternative address used for autodiscovery
environment:
- JELLYFIN_PublishedServerUrl=http://example.com
#- http_proxy=http://127.0.0.1:7890
#- https_proxy=http://127.0.0.1:7890
# Optional - may be necessary for docker healthcheck to pass if running in host network mode
# extra_hosts:
# - &amp;#39;host.docker.internal:host-gateway&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;一些说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;采用了host模式，无需进行端口映射&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;https端口8920，http端口8096&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可通过环境变量配置http和https代理&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="部署https证书"&gt;部署https证书&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;阿里云申请免费证书，有效期3个月，服务器类型选IIS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;上传证书到./config文件夹中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在Jellyfin页面中配置证书文件地址和密码&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>gitea服务安装配置</title><link>https://blog.laning.org/posts/wp-0283/</link><pubDate>Sat, 27 May 2023 02:53:51 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0283/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;关于gitea是什么，以及基本的配置可以参考&lt;a href="https://docs.gitea.com/zh-cn/"&gt;官方文档&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="特性"&gt;特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;此为内网使用，因而没有配置caddy或nginx等代理&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="配置"&gt;配置&lt;/h2&gt;
&lt;h3 id="1启动docker服务"&gt;1.启动docker服务&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2ipport通过浏览器配置"&gt;2.IP:port通过浏览器配置&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-05-27-gitea%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/Gitea%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E7%AB%99%E7%82%B9%E5%88%9D%E5%A7%8B%E5%8C%96%E9%85%8D%E7%BD%AE.png"&gt;&lt;img alt="Gitea数据库与站点初始化配置" loading="lazy" src="https://blog.laning.org/images/2023-05-27-gitea%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/Gitea%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8E%E7%AB%99%E7%82%B9%E5%88%9D%E5%A7%8B%E5%8C%96%E9%85%8D%E7%BD%AE.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-05-27-gitea%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/Gitea%E6%9C%8D%E5%8A%A1%E4%B8%8E%E7%AE%A1%E7%90%86%E5%91%98%E9%85%8D%E7%BD%AE.png"&gt;&lt;img alt="Gitea服务与管理员配置" loading="lazy" src="https://blog.laning.org/images/2023-05-27-gitea%E6%9C%8D%E5%8A%A1%E5%AE%89%E8%A3%85%E9%85%8D%E7%BD%AE/Gitea%E6%9C%8D%E5%8A%A1%E4%B8%8E%E7%AE%A1%E7%90%86%E5%91%98%E9%85%8D%E7%BD%AE.png"&gt;&lt;/a&gt;&lt;/p&gt;</description></item><item><title>vscode-web服务与配置</title><link>https://blog.laning.org/posts/wp-0268/</link><pubDate>Sat, 27 May 2023 01:59:14 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0268/</guid><description>&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-05-27-vscode-web%E6%9C%8D%E5%8A%A1%E4%B8%8E%E9%85%8D%E7%BD%AE/VSCode-Web%E6%B5%8F%E8%A7%88%E5%99%A8%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2.png"&gt;&lt;img alt="VSCode-Web浏览器开发界面" loading="lazy" src="https://blog.laning.org/images/2023-05-27-vscode-web%E6%9C%8D%E5%8A%A1%E4%B8%8E%E9%85%8D%E7%BD%AE/VSCode-Web%E6%B5%8F%E8%A7%88%E5%99%A8%E5%BC%80%E5%8F%91%E7%95%8C%E9%9D%A2.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;如果需要在多台设备之间来进行开发工作，频繁的配置开发环境无疑是很消耗精力的事情。而vscode-web提供了通过浏览器来编写代码的环境，因而理论上，你可以在任何一台机器上继续你的工作。&lt;/p&gt;
&lt;h2 id="配置过程"&gt;配置过程&lt;/h2&gt;
&lt;h3 id="1启动docker服务"&gt;1.启动docker服务&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2进入容器查看密钥"&gt;2.进入容器查看密钥&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#进入容器
docker exec -it code-server bash
#查看密钥
cat ~/.config/code-server/config.yaml
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="3更换容器的apt源"&gt;3.更换容器的apt源&lt;/h3&gt;
&lt;p&gt;参考文档：&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/help/debian/"&gt;清华开源软件镜像站Debian Help&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;#换源完成后执行
apt update
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="4安装cc环境"&gt;4.安装C/C++环境&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;apt install build-essential
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="5解决python命令找不到"&gt;5.解决python命令找不到&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ln -s /usr/bin/python3 /usr/bin/python
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="6安装rust开发环境"&gt;6.安装Rust开发环境&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf https://sh.rustup.rs | sh
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="7进入web界面自行安装喜欢的插件"&gt;7.进入web界面，自行安装喜欢的插件&lt;/h3&gt;</description></item><item><title>bingAI本地部署</title><link>https://blog.laning.org/posts/wp-0263/</link><pubDate>Sat, 27 May 2023 00:35:44 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0263/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;自从chatGPT3.0问世以后，新一轮的人工智能浪潮深刻改变了我们的生活。相比于深蓝击败人类象棋冠军以及阿尔法狗击败人类围棋冠军，chatGPT更能称为划时代的人工智能产品，因为它太接近我们的生活了（通用人工智能）。关于它能干什么以及它与newbing的关系这里不多介绍，感兴趣的可以自己寻找这方面的科普视频。本文主要分享如何通过docker部署newbing，从而达到无需魔法访问newbing的目的。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-05-27-bingAI%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2/NewBing%E8%81%8A%E5%A4%A9%E9%A6%96%E9%A1%B5.png"&gt;&lt;img alt="NewBing聊天首页" loading="lazy" src="https://blog.laning.org/images/2023-05-27-bingAI%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2/NewBing%E8%81%8A%E5%A4%A9%E9%A6%96%E9%A1%B5.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;开源项目地址&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/adams549659584/go-proxy-bingai"&gt;go-proxy-bingai&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="特性"&gt;特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用caddy来进行反向代理，自动配置域名证书&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="实践过程"&gt;实践过程&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;拉取&lt;a href="https://github.com/laningya/Raspberry-Pi/tree/develop/bingAI"&gt;本目录&lt;/a&gt;下的文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;替换caddy文件下的Caddyfile文件中的yourdomain.com字段为自己的域名&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;命令行执行&lt;code&gt;docker-compose up -d&lt;/code&gt;畅享服务吧。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>NanoPC-T4开发记录</title><link>https://blog.laning.org/posts/wp-0258/</link><pubDate>Sat, 27 May 2023 00:21:02 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0258/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;咸鱼200块淘了块RK3399的T4开发板（裸板），4GRAM，16GBemmc，比起树莓派，价格算很香的了&lt;/p&gt;
&lt;h2 id="制作外壳"&gt;制作外壳&lt;/h2&gt;
&lt;p&gt;因为没有外壳，官方的外壳售价一言难尽，并且没有预留GPIO的空间，尝试自己画亚克力外壳。先是用了3DMAX，可惜商家需要dwg格式（即需要autoCAD），简单学习就能上手，需要学习rec，dli等命令的使用。同时经过测量需要M3的六角铜柱，以及M3螺丝，螺母，具体规格可以参考&lt;a href="https://github.com/laningya/Raspberry-Pi/tree/master/NanoPC-T4"&gt;Raspberry-Pi/NanoPC-T4 at master · laningya/Raspberry-Pi (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="烧录系统"&gt;烧录系统&lt;/h2&gt;
&lt;p&gt;常用的烧录方式有两种（直接将系统安装在SD卡，读写速度有点慢，且步骤相对简单，不作记录）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;从windows或者linux烧录到emmc&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从sd卡烧录到emmc&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上两种方式,&lt;a href="https://wiki.friendlyelec.com/wiki/index.php/NanoPC-T4"&gt;官方文档&lt;/a&gt;都提供了详细的步骤。 主要记录&lt;strong&gt;在emmc中安装armbian系统&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;下载或自己编译Armbian的镜像文件。此处推荐内核版本为4.4或4.19，至于原因后续会讲到，如果不想编译，可以直接在官方提供的&lt;a href="https://stpete-mirror.armbian.com/archive/nanopct4/archive/"&gt;链接&lt;/a&gt;下载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将镜像写入sd卡。windows平台下推荐使用win32Diskimage，linux平台下推荐使用dd命令，它看起来是这样&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo dd if=imagePath of=/dev/sdx bs=4M status=progress&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将Armbian系统写入到emmc中。Armbian提供了 armbian-config的工具，命令行执行：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;sudo armbian-config&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;依次选择System&amp;mdash;&amp;gt;Install&amp;mdash;&amp;gt;Boot from eMMC - system on eMMC&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="基本初始化"&gt;基本初始化&lt;/h2&gt;
&lt;h3 id="apt换源以及armbian换源"&gt;apt换源以及armbian换源&lt;/h3&gt;
&lt;p&gt;参考清华大学开源软件镜像站帮助文档&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/help/debian/"&gt;Debian apt换源参考文档&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/help/armbian/"&gt;Armbian换源参考文档&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ifconfig普通用户无法执行问题"&gt;ifconfig普通用户无法执行问题&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vim ~/.bashrc
#在文件末尾添加
export PATH=$PATH:/sbin:/usr/sbin
#保存后命令行执行
source ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="wiringpi-for-rk3399-安装"&gt;WiringPI for RK3399 安装&lt;/h2&gt;
&lt;p&gt;参考&lt;a href="https://wiki.friendlyelec.com/wiki/index.php/WiringPi_for_RK3399/zh"&gt;官方文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;说明：&lt;/strong&gt; 官方的wiringpi for rk3399 的.deb文件通过解包可以发现，官方只为NanoPC-T4开发板适配了4.x内核，这也是为什么推荐安装4.4内核的armbian系统。&lt;/p&gt;
&lt;h2 id="pwm风扇配置"&gt;PWM风扇配置&lt;/h2&gt;
&lt;p&gt;rk3399真的太热了，只配置散热片的情况下，待机状态下，cpu温度都有40摄氏度，所以还是推荐购买官方的PWM风扇，12V供电且开发板预留了接口，有了散热风扇后，cpu35摄氏度左右，除了贵没啥缺点，。以下脚本也只支持4.x内核版本&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; class=&amp;#34;wp-block-preformatted&amp;#34;&amp;gt;#文件路径：/usr/bin
#文件名称：start-rk3399-pwm-fan.sh
#以下为文件内容：
#!/bin/bash
echo $$ &amp;gt; /var/run/fan.pid echo 0 &amp;gt; /sys/class/pwm/pwmchip1/export
echo 0 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/enable
echo 50000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/period
echo 1 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/enable
while true
do
temp=$(cat /sys/class/thermal/thermal_zone0/temp)
if [ $temp -gt 48000 ]; then
echo 1000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/duty_cycle;
elif [ $temp -gt 43000 ]; then
echo 20000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/duty_cycle;
elif [ $temp -gt 38000 ]; then
echo 30000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/duty_cycle;
elif [ $temp -gt 33000 ]; then
echo 40000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/duty_cycle;
else
echo 50000 &amp;gt; /sys/class/pwm/pwmchip1/pwm0/duty_cycle;
fi
sleep 1s;
done
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;#文件路径：/lib/systemd/system
#文件名称：pwm-fan.service
#以下为文件内容
[Unit]Description=pwm-fan
After=rc.local.service
[Service]
Type=oneshot
KillMode=control-group
WorkingDirectory=/tmp
ExecStart=/usr/bin/start-rk3399-pwm-fan.sh
[Install]
WantedBy=multi-user.target
Alias=pwm-fan.service
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;配置开机自启动&lt;/p&gt;</description></item><item><title>数字集成电路设计实验——FIR滤波器</title><link>https://blog.laning.org/posts/wp-0246/</link><pubDate>Fri, 21 Apr 2023 14:33:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0246/</guid><description>&lt;h2 id="1-课程信息"&gt;1. 课程信息&lt;/h2&gt;
&lt;p&gt;■&lt;strong&gt;实验地点&lt;/strong&gt;：清水河校区KB239&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;■ **实验时间：**2021.04.16&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;■ **实验时长：**3小时（4节课）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="2-实验要求"&gt;2. 实验要求&lt;/h2&gt;
&lt;p&gt;1. The fir filter input sampling rate is &lt;strong&gt;100kHz&lt;/strong&gt;, the filter passband single-sideband bandwidth is &lt;strong&gt;20kHz&lt;/strong&gt;, the out-of-band suppression is &lt;strong&gt;90dB&lt;/strong&gt;, and the in-band ripple is &lt;strong&gt;1dB&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;2. The filter coefficient needs to be &lt;strong&gt;fixed-point&lt;/strong&gt;, and the effective number of ADCs is &lt;strong&gt;24bit&lt;/strong&gt;. The filter coefficient bit width is self-defined.&lt;/p&gt;
&lt;p&gt;思考（加分项）：&lt;/p&gt;
&lt;p&gt;1. The relationship between filter passband, stopband, out-of-band rejection and filter order&lt;/p&gt;</description></item><item><title>数字集成电路设计实验——时钟</title><link>https://blog.laning.org/posts/wp-0243/</link><pubDate>Sat, 15 Apr 2023 14:30:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0243/</guid><description>&lt;h1 id="1-课程信息"&gt;1. 课程信息&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实验地点&lt;/strong&gt;：清水河校区KB239&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**实验时间：**2021.04.9&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实验时长:&lt;/strong&gt; 3小时（4节课）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="2-实验要求"&gt;2. 实验要求&lt;/h1&gt;
&lt;p&gt;驱动板上数码管显示当前时间（包含时、分、秒）&lt;/p&gt;
&lt;p&gt;①建议定义n个按键，如用于功能切换 (tab)、校时+1(up)及确认(ok)&lt;/p&gt;
&lt;p&gt;②整点报时: 7:00~23:00间每个整点蜂鸣器响1s&lt;/p&gt;
&lt;p&gt;思考（加分项）：&lt;/p&gt;
&lt;p&gt;1. 如何添加闹钟功能？&lt;/p&gt;
&lt;p&gt;2. 如何添加定时器功能？&lt;/p&gt;
&lt;p&gt;3. 设计模N计数器的测试向量集，撰写testbench进行验证测试&lt;/p&gt;
&lt;h1 id="3-设计与实现"&gt;3. 设计与实现&lt;/h1&gt;
&lt;h2 id="31-电路功能说明"&gt;3.1 电路功能说明&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;（包括各个模块功能、关键代码分析，可以使用文字、框图、功能表、状态图等进行说明）&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="311-顶层设计"&gt;3.1.1 顶层设计&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-04-15-%E6%95%B0%E5%AD%97%E9%9B%86%E6%88%90%E7%94%B5%E8%B7%AF%E8%AE%BE%E8%AE%A1%E5%AE%9E%E9%AA%8C%E2%80%94%E2%80%94%E6%97%B6%E9%92%9F/%E6%95%B0%E5%AD%97%E6%97%B6%E9%92%9F%E9%A1%B6%E5%B1%82%E6%A8%A1%E5%9D%97%E8%BF%9E%E6%8E%A5.png"&gt;&lt;img alt="数字时钟顶层模块连接" loading="lazy" src="https://blog.laning.org/images/2023-04-15-%E6%95%B0%E5%AD%97%E9%9B%86%E6%88%90%E7%94%B5%E8%B7%AF%E8%AE%BE%E8%AE%A1%E5%AE%9E%E9%AA%8C%E2%80%94%E2%80%94%E6%97%B6%E9%92%9F/%E6%95%B0%E5%AD%97%E6%97%B6%E9%92%9F%E9%A1%B6%E5%B1%82%E6%A8%A1%E5%9D%97%E8%BF%9E%E6%8E%A5.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="312-timing_module"&gt;3.1.2 timing_module&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-04-15-%E6%95%B0%E5%AD%97%E9%9B%86%E6%88%90%E7%94%B5%E8%B7%AF%E8%AE%BE%E8%AE%A1%E5%AE%9E%E9%AA%8C%E2%80%94%E2%80%94%E6%97%B6%E9%92%9F/%E8%AE%A1%E6%97%B6%E6%A8%A1%E5%9D%97%E4%B8%8E%E6%A0%A1%E6%97%B6%E6%A8%A1%E5%9D%97%E7%BB%93%E6%9E%84.png"&gt;&lt;img alt="计时模块与校时模块结构" loading="lazy" src="https://blog.laning.org/images/2023-04-15-%E6%95%B0%E5%AD%97%E9%9B%86%E6%88%90%E7%94%B5%E8%B7%AF%E8%AE%BE%E8%AE%A1%E5%AE%9E%E9%AA%8C%E2%80%94%E2%80%94%E6%97%B6%E9%92%9F/%E8%AE%A1%E6%97%B6%E6%A8%A1%E5%9D%97%E4%B8%8E%E6%A0%A1%E6%97%B6%E6%A8%A1%E5%9D%97%E7%BB%93%E6%9E%84.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接收PLL多次分频得到的1Hz时钟信号作为模块的时钟信号，设置17位数据用来存储当前时间（[5:0]表示秒，[11:6]表示分，[16:12]表示小时），当秒达到59时，则下一次操作为秒位置0，同时分位加1，分钟与小时的关系依次类推。同时当load信号使能时，即设置时间功能打开时，数据位数据将被加载进来的数据覆盖。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-verilog" data-lang="verilog"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// timing_module.v
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;`timescale&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;ns &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;ps
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//////////////////////////////////////////////////////////////////////////////////
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Company: UESTC
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Engineer: Qy_Ley
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Create Date: 2021/03/14 15:06:37
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Design Name: Digital Clock for EES331
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Module Name: timing_module
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Project Name: Digital Clock
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Target Devices: EES331
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Tool Versions: Vivado 18.3
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Description:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Dependencies:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Revision:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Revision 0.01 - File Created
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Additional Comments:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//////////////////////////////////////////////////////////////////////////////////
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;module&lt;/span&gt; timing_module(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;input&lt;/span&gt; i_clk_1Hz,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;input&lt;/span&gt; i_load,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;input&lt;/span&gt; i_rstn,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;input&lt;/span&gt; i_ena,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;input&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] i_load_hms, &lt;span style="color:#75715e"&gt;// [5:0] for sec, [11:6] for min, [16:12] for hour, BCD coding
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;output&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] o_hms &lt;span style="color:#75715e"&gt;// [5:0] for sec, [11:6] for min, [16:12] for hour, BCD coding
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// wire m_co_sec, m_co_min; // Carry output from second &amp;amp; minute counter
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;reg&lt;/span&gt; ld;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;reg&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] ld_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;reg&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] hour_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;reg&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] min_cnt,sec_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;always&lt;/span&gt; @(&lt;span style="color:#66d9ef"&gt;posedge&lt;/span&gt; i_clk_1Hz) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ld &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; i_load;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ld_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; i_load_hms;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt; &lt;span style="color:#75715e"&gt;//clock cross-domain buffer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;always&lt;/span&gt; @(&lt;span style="color:#66d9ef"&gt;posedge&lt;/span&gt; i_clk_1Hz &lt;span style="color:#66d9ef"&gt;or&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;negedge&lt;/span&gt; i_rstn) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#f92672"&gt;!&lt;/span&gt;i_rstn) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hour_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; min_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sec_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(ld) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {hour_cnt, min_cnt, sec_cnt} &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; ld_cnt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(i_ena) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(sec_cnt &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#39;d59&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sec_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(min_cnt &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#39;d59&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; min_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(hour_cnt &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;&amp;#39;d23&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hour_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hour_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; hour_cnt&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; min_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; min_cnt&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sec_cnt &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; sec_cnt&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;/* Complete the counter for second, minute, hour */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;assign&lt;/span&gt; o_hms &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {hour_cnt, min_cnt, sec_cnt};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;endmodule&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="313-control_module"&gt;3.1.3 control_module&lt;/h2&gt;
&lt;p&gt;为系统控制的模块，采用有限状态机的描述方式，如图：&lt;/p&gt;</description></item><item><title>校园电信宽带自动连接脚本</title><link>https://blog.laning.org/posts/wp-0211/</link><pubDate>Thu, 06 Apr 2023 15:28:16 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0211/</guid><description>&lt;h2 id="项目起因"&gt;项目起因&lt;/h2&gt;
&lt;p&gt;校园电信宽带一大痛点是在路由器断电后，需要手动进行身份认证。在外面遇到寝室断电或者早上赶早八，而没有连接网络，当需要远程宿舍网络时，就会很崩溃。前不久看到有人在朋友圈分享自己写的脚本，今天自己实践一下。&lt;/p&gt;
&lt;h2 id="脚本地址"&gt;脚本地址&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;作者提供的地址&lt;/strong&gt;：&lt;a href="https://gist.github.com/learnerLj/e327816e735ac8f12a62d18029bb45f0"&gt;https://gist.github.com/learnerLj/e327816e735ac8f12a62d18029bb45f0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在此基础上，我修改了部分代码，更便于后续的部署实践&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修改后的地址&lt;/strong&gt;：&lt;a href="https://github.com/laningya/UESTC-WORK/blob/master/%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E7%94%B5%E4%BF%A1%E7%BD%91%E7%BB%9C/autoConnectNetwork.py"&gt;https://github.com/laningya/UESTC-WORK/blob/master/%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E7%94%B5%E4%BF%A1%E7%BD%91%E7%BB%9C/autoConnectNetwork.py&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;先看一下脚本需要提供的信息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;post_url中的IP地址&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;post_data中userId，password，queryString&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="实践过程"&gt;实践过程&lt;/h2&gt;
&lt;h3 id="获取脚本需要的信息"&gt;获取脚本需要的信息&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;获取post_url中的IP地址和post_data中的queryString字段&lt;img alt="电信认证页面IP与queryString参数" loading="lazy" src="https://blog.laning.org/images/2023-04-06-%E6%A0%A1%E5%9B%AD%E7%94%B5%E4%BF%A1%E5%AE%BD%E5%B8%A6%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E8%84%9A%E6%9C%AC/%E7%94%B5%E4%BF%A1%E8%AE%A4%E8%AF%81%E9%A1%B5%E9%9D%A2IP%E4%B8%8EqueryString%E5%8F%82%E6%95%B0.png"&gt;&lt;/p&gt;
&lt;p&gt;（原文图片未随备份提供：&lt;code&gt;images/1.png&lt;/code&gt;）&lt;/p&gt;
&lt;p&gt;如图，在电信宽带认证界面的url中，172.25.249.64即为posturl中需要的IP地址；index.jsp? 之后的所有内容为post_data中queryString需要的信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获取post_data中的userId和password&lt;img alt="浏览器开发者工具获取认证参数" loading="lazy" src="https://blog.laning.org/images/2023-04-06-%E6%A0%A1%E5%9B%AD%E7%94%B5%E4%BF%A1%E5%AE%BD%E5%B8%A6%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E8%84%9A%E6%9C%AC/%E6%B5%8F%E8%A7%88%E5%99%A8%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7%E8%8E%B7%E5%8F%96%E8%AE%A4%E8%AF%81%E5%8F%82%E6%95%B0.png"&gt; 如图，需要打开在浏览器打开f12开发者工具，如图为Google Chrome的调试页面。点击网络，保留日志，双击InterFace.do?method=login选项，选择载荷，找到其中的userId和password字段，并填入代码中，**注意：**pasaword字段后面还有个queryString字段，在步骤1中我们也有一个相同名称的字段，而程序需要的是步骤1中的字段。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;至此，我们就获取到脚本需要的所有信息，即可以运行脚本。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="在树莓派等设备上部署自动执行脚本"&gt;在树莓派等设备上部署自动执行脚本&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;树莓派部署自动执行脚本的形式有很多，本次采用crontab服务，在pi用户下，命令行执行以下命令&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd &amp;amp;&amp;amp; mkdir .script &amp;amp;&amp;amp; cd .script &amp;amp;&amp;amp; touch autoConnectNetwork.py
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过vim或者nano编辑器将脚本内容添加到 &lt;strong&gt;autoConnectNetwork.py&lt;/strong&gt;中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加crontab任务，在命令行执行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;crontab -e
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在文件末尾添加&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;* * * * * /usr/bin/python /home/pi/.script/autoConnectNetwork.py &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="通过docker部署脚本"&gt;通过Docker部署脚本&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载项目文件和Docker环境以及填写配置文件。Docker的安装方法可以参考&lt;a href="https://docs.docker.com/engine/install/"&gt;官方文档&lt;/a&gt;，Docker部署文件地址为：&lt;a href="https://github.com/laningya/UESTC-WORK/tree/master/%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E7%94%B5%E4%BF%A1%E7%BD%91%E7%BB%9C/Docker"&gt;https://github.com/laningya/UESTC-WORK/tree/master/%E8%87%AA%E5%8A%A8%E8%BF%9E%E6%8E%A5%E7%94%B5%E4%BF%A1%E7%BD%91%E7%BB%9C/Docker&lt;/a&gt; 需要的配置与前面一致，配置文件路径为Docker/config/config.txt，填入必要的信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;构建镜像。如果你是Linux用户，在Docker文件夹下，命令行执行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker build --no-cache -t laningya/uestc_auto_connect_network:v1 .
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;不要忘记复制后面的点&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;说明： build:docker构建镜像的命令 --no-cache:忽略缓存 -t:指定构建后的镜像名
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;（原文图片未随备份提供：&lt;code&gt;images/docker_build.png&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;运行镜像。还是在/Docker目录下，命令行执行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -itd --restart=always --net=host --name autoConnectNetwork laningya/uestc_auto_connect_network:v1
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;说明： run:docker运行容器的命令 -itd：可以简单理解为在后台执行 --restart=always:容器运行出现错误时，自动尝试重启，关键参数，不能轻易取消 --net=host:指定容器网络为host模式，便于直接访问路由器 --name utoConnectNetwork 指定容器名，便于后续管理 laningya/uestc_auto_connect_network:v1 我们前面构建的镜像名称
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;（原文图片未随备份提供：&lt;code&gt;images/docker_run_ps.png&lt;/code&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>ESP8266开发记录</title><link>https://blog.laning.org/posts/wp-0160/</link><pubDate>Wed, 05 Apr 2023 00:49:23 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0160/</guid><description>&lt;hr&gt;
&lt;h2 id="项目材料"&gt;项目材料&lt;/h2&gt;
&lt;p&gt;ESP8266-12E开发板一块&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ESP8266是一款物联网WiFi芯片(MCU)，常见型号有ESP-01到ESP-13等，每个型号的引脚和功能不同。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SSD1306屏幕一块&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I2C接口的显示屏幕，在Github上有开源驱动的驱动程序&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="效果图"&gt;效果图&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/OLED%E5%A4%A9%E6%B0%94%E6%97%B6%E9%92%9F%E5%AE%9E%E7%89%A9%E6%95%88%E6%9E%9C.jpg"&gt;&lt;img alt="OLED天气时钟实物效果" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/OLED%E5%A4%A9%E6%B0%94%E6%97%B6%E9%92%9F%E5%AE%9E%E7%89%A9%E6%95%88%E6%9E%9C.jpg"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="项目功能介绍"&gt;项目功能介绍&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;连接指定WIFI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过NTP服务获取时间并在屏幕上显示&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过心知天气提供的API，获取本地实时天气并显示&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="开发环境及配置"&gt;开发环境及配置&lt;/h2&gt;
&lt;p&gt;ESP8266常见开发环境有Arduino IDE和ESP8266 SDK两种。项目使用Arduino IDE这一集成开发环境，优点在于Arduino IDE在安装ESP8266函数库以及串口调试都更为容易。而ESP8266 SDK是乐鑫科技提供的开发工具，需要在Linux下编译开发套件并且需要单独下载串口调试工具等软件，配置相对麻烦。&lt;/p&gt;
&lt;h3 id="arduino-ide配置"&gt;Arduino IDE配置&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载 &lt;a href="https://www.arduino.cc/en/software"&gt;Arduino IDE&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开软件-&amp;gt;文件-&amp;gt;首选项-&amp;gt;附加开发板管理器地址，添加&lt;code&gt;http://arduino.esp8266.com/stable/package_esp8266com_index.json&lt;/code&gt;添加完成后，点击好。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img alt="Arduino附加开发板管理地址" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/Arduino%E9%99%84%E5%8A%A0%E5%BC%80%E5%8F%91%E6%9D%BF%E7%AE%A1%E7%90%86%E5%9C%B0%E5%9D%80.png"&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在Arduino IDE中点击工具-&amp;gt;开发板-&amp;gt;开发板管理器,在开发板管理器里面搜索esp8266并进行安装 &lt;img alt="ESP8266开发板支持包安装" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/ESP8266%E5%BC%80%E5%8F%91%E6%9D%BF%E6%94%AF%E6%8C%81%E5%8C%85%E5%AE%89%E8%A3%85.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在Arduino IDE的开发板菜单中找到“NodeMCU开发板”，选择ESP8266-12E &lt;img alt="NodeMCU开发板选择" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/NodeMCU%E5%BC%80%E5%8F%91%E6%9D%BF%E9%80%89%E6%8B%A9.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将esp8266通过数据线接入电脑，右键此电脑-&amp;gt;管理-&amp;gt;设备管理器-&amp;gt;端口，查找到开发板的端口号 &lt;img alt="Windows设备管理器查看串口" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/Windows%E8%AE%BE%E5%A4%87%E7%AE%A1%E7%90%86%E5%99%A8%E6%9F%A5%E7%9C%8B%E4%B8%B2%E5%8F%A3.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在Arduino IDE中点击工具-&amp;gt;端口，选择上面的端口 &lt;img alt="Arduino串口选择" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/Arduino%E4%B8%B2%E5%8F%A3%E9%80%89%E6%8B%A9.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过Blink实例程序，验证是否搭建完成开发环境 点击文件-&amp;gt;示例-&amp;gt;Basics-&amp;gt;Blink 点击上传按钮，等待一分钟左右，可以观察到esp8266开发板上的led闪烁证明开发环境搭建完成。&lt;img alt="Arduino串口选择" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/Arduino%E4%B8%B2%E5%8F%A3%E9%80%89%E6%8B%A9.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="依赖的第三方库"&gt;依赖的第三方库&lt;/h2&gt;
&lt;p&gt;在Arduino IDE中点击工具-&amp;gt;管理库，添加NTP库与SSD1306库 &lt;img alt="NTPClient时间同步库安装" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/NTPClient%E6%97%B6%E9%97%B4%E5%90%8C%E6%AD%A5%E5%BA%93%E5%AE%89%E8%A3%85.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="SSD1306显示屏库安装" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/SSD1306%E6%98%BE%E7%A4%BA%E5%B1%8F%E5%BA%93%E5%AE%89%E8%A3%85.png"&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="配置项目"&gt;配置项目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;配置WiFi信息，用你的WiFiSSID和密码替换*** &lt;img alt="WiFi名称与密码配置" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/WiFi%E5%90%8D%E7%A7%B0%E4%B8%8E%E5%AF%86%E7%A0%81%E9%85%8D%E7%BD%AE.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;配置心知天气相关信息,用你的私钥替换***,location替换为你所在城市，如上海为shanghai，北京为beijing等，具体可参考&lt;a href="https://docs.seniverse.com/api/start/common.html#%E5%9C%B0%E7%82%B9-location"&gt;心知天气官方开发者文档&lt;/a&gt;** 注意：如果你不关心代码是的问题，至此可以直接在Arduino IDE中点击上传按钮了**&lt;img alt="心知天气API密钥与城市配置" loading="lazy" src="https://blog.laning.org/images/2023-04-05-ESP8266%E5%BC%80%E5%8F%91%E8%AE%B0%E5%BD%95/%E5%BF%83%E7%9F%A5%E5%A4%A9%E6%B0%94API%E5%AF%86%E9%92%A5%E4%B8%8E%E5%9F%8E%E5%B8%82%E9%85%8D%E7%BD%AE.png"&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;hr&gt;
&lt;h2 id="weathernow类"&gt;WeatherNow类&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class WeatherNow
{
public:
//配置心知天气相关信息
void config(String ,String ,String ,String);
//获取天气信息
void getData();
public:
//天气
String text;
//温度
String temperature;
//体感温度
String feels_like;
//气压
String pressure;
//相对湿度
String humidity;
//能见度
String visibility;
//风向
String wind_direction;
//风向角度
String wind_direction_degree;
//风速
String wind_speed;
//风力等级
String wind_scale;
//云量
String clouds;
//露点温度
String dew_point;
//日期
String date;
private:
int getPayload();
String _url;
String _payload;
};
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="weatherday类"&gt;WeatherDay类&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class WeatherDay
{
public:
void config(String ,String ,String ,String);
void getData();
public:
String date0;
String date1;
String date2;
String text_day0;
String text_day1;
String text_day2;
String text_night0;
String text_night1;
String text_night2;
String code_night0;
String code_night1;
String code_night2;
String high0;
String high1;
String high2;
String low0;
String low1;
String low2;
String precip0;
String precip1;
String precip2;
String wind_direction0;
String wind_direction1;
String wind_direction2;
String wind_direction_degree0;
String wind_direction_degree1;
String wind_direction_degree2;
String wind_speed0;
String wind_speed1;
String wind_speed2;
String wind_scale0;
String wind_scale1;
String wind_scale2;
String rainfall0;
String rainfall1;
String rainfall2;
String humidity0;
String humidity1;
String humidity2;
private:
int getPayload();
String _url;
String _payload;
};
&lt;/code&gt;&lt;/pre&gt;&lt;hr&gt;
&lt;h2 id="进一步开发计划"&gt;进一步开发计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;受限于ssd1306显示内容有限，因而考虑更换屏幕，显示未来天气等信息。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>数字集成电路设计实验——流水灯</title><link>https://blog.laning.org/posts/wp-0173/</link><pubDate>Mon, 27 Mar 2023 00:56:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0173/</guid><description>&lt;h1 id="1-课程信息"&gt;1. 课程信息&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实验地点&lt;/strong&gt;：******&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;**实验时间：**2021.03.25&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;实验时长:&lt;/strong&gt; 3小时（4节课）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="2-实验要求"&gt;2. 实验要求&lt;/h1&gt;
&lt;p&gt;驱动板上LED1 ~LED8按如下2个模式循环闪烁：&lt;/p&gt;
&lt;p&gt;① 每个灯亮1s灭1s，从右至左依次闪烁，共8次&lt;/p&gt;
&lt;p&gt;② 每个灯亮1s灭0.5s，从左至右间隔闪烁，共4次&lt;/p&gt;
&lt;p&gt;思考（加分项）：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如何使用按键控制流水灯的闪烁时间？&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如：按一次亮1s，再按一次变为亮0.5s。&lt;/p&gt;
&lt;p&gt;2. 如何使用按键控制流水模式？&lt;/p&gt;
&lt;p&gt;如：按一次8个灯依次闪烁，再按一次LED2/4/6/8间隔闪烁&lt;/p&gt;
&lt;h1 id="3-设计与实现"&gt;3. 设计与实现&lt;/h1&gt;
&lt;h2 id="31-实验步骤"&gt;3.1 实验步骤&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;在Vivado中创建工程，并添加.v文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;阅读实验提供的源码文件并完善部分代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加testbeach文件，做仿真分析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;添加.xdc文件（将模块引脚与开发板引脚绑定），并下板验证&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="32-电路功能说明"&gt;3.2 电路功能说明&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;（包括各个模块功能、关键代码分析，可以使用文字、框图、功能表、状态图等进行说明）&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="321-关键代码分析"&gt;3.2.1 关键代码分析&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;计数器模块
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
counter1 &amp;lt;= 32&amp;#39;d0;
else if(!led_control)//led_control==0为状态1
if (counter1 &amp;lt; 32&amp;#39;d200_000_000)//系统时钟100M，计数器计200M次即2s
counter1 &amp;lt;= counter1 + 1&amp;#39;b1;
else
counter1 &amp;lt;= 32&amp;#39;d0;
else
counter1 &amp;lt;= 32&amp;#39;d0; //状态2时，counter1置零不计数
end
//通过led_control信号来控制计数器2秒或1.5秒,并分别记为counter1和counter2
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;模式控制模块
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
cnt&amp;lt;=32&amp;#39;d0;
else if(cnt&amp;lt;32&amp;#39;d2200_000_000)
cnt&amp;lt;=cnt+1;
else
cnt&amp;lt;=0;
end
//cnt计数器来记录一轮循环，cnt&amp;lt;1600_000_000,即小于16秒为左移，cnt&amp;gt;1600_000_000时为右移。
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;led移动
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
led1&amp;lt;=8&amp;#39;b00000001;
else if (!led_control) begin
if (counter1 == 32&amp;#39;d200_000_000)
led1 &amp;lt;= led1&amp;lt;&amp;lt;1; //左移1位
else
led1 &amp;lt;= led1;
end
else led1 &amp;lt;= 8&amp;#39;b00000001;//状态2时led1就在led2基础上左移，状态转换时即可无缝衔接
end
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n)
led &amp;lt;= 8&amp;#39;b00000001;
else case (led_control)
0 : if(counter1 &amp;lt; 32&amp;#39;d100_000_000) led = led1; else led = 8&amp;#39;b0; //进入状态1时，先让灯亮1s，再将移位寄存器led1的值赋值给led
1 : if(counter2 &amp;lt; 32&amp;#39;d100_000_000) led = led2; else led = 8&amp;#39;b0; //进入状态2时，先让灯亮1s，再将移位寄存器led2的值赋值给led
default : led &amp;lt;= led;
endcase
end
//分别用led1和led2来表示两种状态下的led状态，led_control为0时，当达到2秒时，led1进行左移。通过counter1的值判断是否达到1秒，未达到时，将led1的值赋给led，否则led置为8’b0。led_control为1同理
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="322-系统级表示"&gt;3.2.2 系统级表示&lt;/h3&gt;
&lt;p&gt;&lt;img alt="流水灯系统功能框图" loading="lazy" src="https://blog.laning.org/images/2023-03-27-%E6%95%B0%E5%AD%97%E9%9B%86%E6%88%90%E7%94%B5%E8%B7%AF%E8%AE%BE%E8%AE%A1%E5%AE%9E%E9%AA%8C%E2%80%94%E2%80%94%E6%B5%81%E6%B0%B4%E7%81%AF/%E6%B5%81%E6%B0%B4%E7%81%AF%E7%B3%BB%E7%BB%9F%E5%8A%9F%E8%83%BD%E6%A1%86%E5%9B%BE.jpg"&gt;&lt;/p&gt;</description></item><item><title>GPU在并行信息处理中的应用</title><link>https://blog.laning.org/posts/wp-0116/</link><pubDate>Mon, 19 Dec 2022 16:36:26 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0116/</guid><description>&lt;p&gt;摘要&lt;/p&gt;
&lt;p&gt;随着前端数据采集设备精度的不断提高，对信息处理系统的实时性、准确性提出更高的要求。而从日趋完善的计算机体系结构中，半导体工艺难以取得重大突破的情况下，想要获取更高的计算性能（信息处理能力），我们就必须探索另外一条道路——并行处理。GPU在应用于图像处理领用，其CUDA平台的支持，对于浮点运算的高效，因而作为并行信息处理的技术被广泛应用。&lt;/p&gt;
&lt;p&gt;关键词&lt;/p&gt;
&lt;p&gt;GPU，CUDA ，并行信息处理&lt;/p&gt;
&lt;h3 id="1-并行处理技术"&gt;1. 并行处理技术&lt;/h3&gt;
&lt;h4 id="11-并行处理技术介绍"&gt;1.1 并行处理技术介绍&lt;/h4&gt;
&lt;p&gt;并行处理或并行计算是指利用多台计算机或处理器同时执行运算任务，从而减少解决问题所需要的时间。一般可分为时间并行计算和空间并行计算。&lt;/p&gt;
&lt;p&gt;时间上的并行计算叫做流水线处理，即多个处理器按照处理时间的先后顺序执行计算；空间上的并行是指多个处理器同时执行计算，各处理器在时间上相互独立。并行处理技术主要研究空间上的并行，即通过总线方式将多个计算机或处理器并联，从而获得更快的处理速度。&lt;/p&gt;
&lt;p&gt;并行计算根据规模不同，分为一下几个层次。如图所示，最底层是单核指令级并行（ILP），即单个处理器，但可同时执行多条指令；其上为多核并行，即单芯片拥有多个处理器核心；再往上是多处理器并行，即通过多个芯片之间分工协作做到并行处理；最上层为集群或分布式并行，通过网络互联实现超大规模并行运算，可参考大型数据中心。&lt;/p&gt;
&lt;p&gt;&lt;img alt="并行计算层次结构" loading="lazy" src="https://blog.laning.org/images/2022-12-19-GPU%E5%9C%A8%E5%B9%B6%E8%A1%8C%E4%BF%A1%E6%81%AF%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/%E5%B9%B6%E8%A1%8C%E8%AE%A1%E7%AE%97%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84.png"&gt;&lt;/p&gt;
&lt;h4 id="12-flynn计算机体系分类"&gt;1.2 Flynn计算机体系分类&lt;/h4&gt;
&lt;p&gt;1966年，Flynn根据指令流和数据流的多倍性对计算机体系结构进行了分类。分为单指令流单数据流模式（SISD），单指令流多数据流模式（SIMD），多指令流单数据流模式（MISD），多指令流多数据流模式（MIMD）。其中SIMD和MIMD属于并行处理器。&lt;/p&gt;
&lt;p&gt;SIMD和MIMD处理器结构示意图如图所示。SIMD只有一个控制单元，这个控制单元控制多个计算处理单元，这些处理单元共享存储器或信号进行通信。MIMD处理器拥有多个控制单元，每个控制单元控制自己的计算单元，通过共享存储器或信号进行通信。&lt;/p&gt;
&lt;p&gt;&lt;img alt="SIMD与MIMD处理器结构对比" loading="lazy" src="https://blog.laning.org/images/2022-12-19-GPU%E5%9C%A8%E5%B9%B6%E8%A1%8C%E4%BF%A1%E6%81%AF%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/SIMD%E4%B8%8EMIMD%E5%A4%84%E7%90%86%E5%99%A8%E7%BB%93%E6%9E%84%E5%AF%B9%E6%AF%94.png"&gt;&lt;/p&gt;
&lt;h3 id="2cuda-gpu并行架构"&gt;2.CUDA GPU并行架构&lt;/h3&gt;
&lt;p&gt;CUDA是设备计算统一框架的简称（Compute Unified Device Architecture）。其目的是为了用C语言再GPU上进行编程，而无需关注图形API和GPU编程的知识。它可以运行和访问GPU设备的指令和存储空间，从而可以非常快速入门并且从GPU的并行计算中获利。再此之前，GPGPU编程需要针对特定的处理器，而不是标准的API，不能在不同GPU之间进行移植。在CUDA并行架构中，GPU被当作CPU的协处理器来运作，一些数据并行独立且计算密集的函数适合放入GPU中运行。&lt;/p&gt;
&lt;p&gt;&lt;img alt="CUDA软件架构与GPU计算层次" loading="lazy" src="https://blog.laning.org/images/2022-12-19-GPU%E5%9C%A8%E5%B9%B6%E8%A1%8C%E4%BF%A1%E6%81%AF%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/CUDA%E8%BD%AF%E4%BB%B6%E6%9E%B6%E6%9E%84%E4%B8%8EGPU%E8%AE%A1%E7%AE%97%E5%B1%82%E6%AC%A1.png"&gt;&lt;/p&gt;
&lt;p&gt;图为CUDA并行架构框图。底层为CUDA的组成部件，其包括：支持CUDA并行计算的GPU、支持CUDA的操作系统内核、用户模式驱动、PTX并行计算指令集。&lt;/p&gt;
&lt;p&gt;在软件层次，CUDA提供了完备的软件开发环境，包括编译器、调试器、性能测评工具及基础库。并且支持C语言编程，从而可以支持其他高级语言，比如Java和Python。CUDA提供了两种编程接口：设备级编程接口和语言集成编程接口。&lt;/p&gt;
&lt;h3 id="3-cuda-硬件原理"&gt;3. CUDA 硬件原理&lt;/h3&gt;
&lt;p&gt;CUDA 硬件基础结构由一组多线程流处理器（SM，Multitreaded Stream Multiprocessors）的单元组成。如图所示，SM中又有多个SP（Stream Processors）负责具体运算。多线程流处理器SM被设计成拥有可以同时执行上百个线程的能力。为了获得同时执行这么多线程的能力，CUDA从SIMD结构上发展出单指令流多线程（SIMT, Single Instruction Multiple Thread）结构。&lt;/p&gt;
&lt;p&gt;&lt;img alt="GPU流多处理器SM与SP结构" loading="lazy" src="https://blog.laning.org/images/2022-12-19-GPU%E5%9C%A8%E5%B9%B6%E8%A1%8C%E4%BF%A1%E6%81%AF%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/GPU%E6%B5%81%E5%A4%9A%E5%A4%84%E7%90%86%E5%99%A8SM%E4%B8%8ESP%E7%BB%93%E6%9E%84.png"&gt;&lt;/p&gt;
&lt;p&gt;SM多线程处理器负责创建、调度和执行线程，这些线程以32个为一组，成为一个Warp。组成同一个Warp的单独线程从同一个程序地址执行。但是他们拥有单独的指令地址计数器和独立的存储器。所以他们可以互不干扰的运行各自的指令及分支。&lt;/p&gt;
&lt;p&gt;当多线程处理器执行一个或多个线程块时，它把他们分为独立的Warp，之后由Warp调度器进行调度。线程块中的线程根据线程号线性的分组为Warp，即前32个线程号的线程为第一个Warp，接下来32个线程号为第二个Warp，以此类推。一个Warp内的线程每次执行一条指令，所以如果Warp里的32个线程在执行时执行相同的指令路径可以使效率最大化。如果一个Warp中的线程在执行过程中产生了分支，则Warp顺序执行完每个分支，直到所有分支都执行完毕后会和到同一个指令开始执行。不同的Warp各自独立运行，在一个Warp内产生的分支不影响其他的Warp。对于一个特定的线程块，它只能在一个多线程处理器（SM）中执行。但是一个多线程处理器可以执行多个线程块。&lt;/p&gt;</description></item><item><title>FPGA工程应用开发综合实验报告二</title><link>https://blog.laning.org/posts/wp-0148/</link><pubDate>Mon, 19 Dec 2022 00:31:00 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0148/</guid><description>&lt;p&gt;&lt;strong&gt;基于FPGA的BPSK信号产生器设计&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2022年12月19日&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;摘 要&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本次基于FPGA的计时器设计，在熟悉Quartus基本操作、Verilog编程语言的基本规则、SignalTap的基本应用，在前两次PN码序列产生器和DDS设计的基础上，通过分模块设计后进行连接的方式，完成基于FPGA的BPSK信号产生器设计。&lt;/p&gt;
&lt;p&gt;本次设计分为PLL分频模块、自动复位模块、PN码生成模块、DDS模块以及IP核实现方式的NCO模块。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;实验需求分析&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;技术指标分析&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能指标分析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PN码（Gold码）产生器模块需对传输数据进行扩频；DDS模块生成所需频率的载波信号；通过相位选择法（2选1数据选择器）来实现调制。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;性能指标分析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;减少信息传输延迟，调制后的信号应尽量与原数据一致。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;系统方案设计&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;顶层设计&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;项目实现所要用到的时钟问题分析&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;时钟频率控制是FPGA设计的重要组成部分。通过上面功能指标分析，我们不难发现，实现BPSK的调制，我们需要三个时钟来完成我们的设计。一是我们需要一个时钟来控制我们的DDS模块来产生我们需要的频率的载波信号；二是我们需要一个时钟来控制PN码（Gold）码的产生；三是我们需要一个调制信息的时钟&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DDS的两种实现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们通过调用IP核和查找表法两种方法实现DDS。调用IP的好处在于设计简单，但其中的延迟为随机确定的数，在设计未完成前，我们很难确定其值为多少，而当通过查找表来实现DDS，我们能够很好的控制这个延迟，从而提升系统的性能。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PN码序列生成器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将两个PN码进行异或运算（模2加法）生成Gold码。&lt;/p&gt;
&lt;p&gt;具体顶层设计文件截图：&lt;/p&gt;
&lt;p&gt;&lt;img alt="BPSK信号产生器顶层设计" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/BPSK%E4%BF%A1%E5%8F%B7%E4%BA%A7%E7%94%9F%E5%99%A8%E9%A1%B6%E5%B1%82%E8%AE%BE%E8%AE%A1.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="BPSK信号产生器模块连接" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/BPSK%E4%BF%A1%E5%8F%B7%E4%BA%A7%E7%94%9F%E5%99%A8%E6%A8%A1%E5%9D%97%E8%BF%9E%E6%8E%A5.png"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;模块设计&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;例如：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1）PLL分频模块&lt;/p&gt;
&lt;p&gt;由上文中对系统时钟分析可知，我们需要250MHz 、5MHz、10KHz分别作为DDS系统钟、PN码生成器码钟和产生调制信息的码钟，如图1所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="PLL多路时钟分频模块" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/PLL%E5%A4%9A%E8%B7%AF%E6%97%B6%E9%92%9F%E5%88%86%E9%A2%91%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图1 PLL模块&lt;/p&gt;
&lt;p&gt;2）自动复位模块&lt;/p&gt;
&lt;p&gt;本模块接收PLL分频后所得的250MHz时钟信号，如图2：&lt;/p&gt;
&lt;p&gt;&lt;img alt="系统自动复位模块" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/%E7%B3%BB%E7%BB%9F%E8%87%AA%E5%8A%A8%E5%A4%8D%E4%BD%8D%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图2 自动复位模块&lt;/p&gt;
&lt;p&gt;3）PN码生成器模块&lt;/p&gt;
&lt;p&gt;本模块接收250MHz的c0和5MHz的c1，如图3：&lt;/p&gt;
&lt;p&gt;&lt;img alt="PN码生成器模块" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/PN%E7%A0%81%E7%94%9F%E6%88%90%E5%99%A8%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图3 PN码生成器模块&lt;/p&gt;
&lt;p&gt;&lt;img alt="m序列移位寄存器结构" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/m%E5%BA%8F%E5%88%97%E7%A7%BB%E4%BD%8D%E5%AF%84%E5%AD%98%E5%99%A8%E7%BB%93%E6%9E%84.png"&gt;&lt;/p&gt;
&lt;p&gt;图5.1023位m序列产生器原理框图&lt;/p&gt;
&lt;p&gt;如图5：为1023位m序列产生器的原理图，&lt;/p&gt;
&lt;p&gt;{a&lt;sub&gt;n&lt;/sub&gt;}=c&lt;sub&gt;1&lt;/sub&gt;a&lt;sub&gt;n-1&lt;/sub&gt;+c&lt;sub&gt;2&lt;/sub&gt;a&lt;sub&gt;n-2&lt;/sub&gt;+……+c&lt;sub&gt;n&lt;/sub&gt;a&lt;sub&gt;0&lt;/sub&gt;&lt;/p&gt;
&lt;p&gt;由于m序列自相关良好但是互相关特性不好且可用于产生&lt;/p&gt;
&lt;p&gt;&lt;img alt="Gold码生成逻辑图" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/Gold%E7%A0%81%E7%94%9F%E6%88%90%E9%80%BB%E8%BE%91%E5%9B%BE.png"&gt;&lt;/p&gt;
&lt;p&gt;图6：Gold序列产生原理框图&lt;/p&gt;
&lt;p&gt;m序列的本原多项式较少，在一些要求地址码多的系统钟m序列很难满足要求，因而引入Gold码。产生Gold码序列可以将两个m序列的移位寄存器并联再进行模2加法，如图6为生成Gold码的逻辑图。图7为顶层文件的Gold码实现。&lt;/p&gt;
&lt;p&gt;&lt;img alt="Gold码顶层电路实现" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/Gold%E7%A0%81%E9%A1%B6%E5%B1%82%E7%94%B5%E8%B7%AF%E5%AE%9E%E7%8E%B0.png"&gt;&lt;/p&gt;
&lt;p&gt;图7：生成Gold码的顶层文件&lt;/p&gt;
&lt;p&gt;4）DDS模块&lt;/p&gt;
&lt;p&gt;本模块接收c0和频率控制字作为输入，32位相位信息作为输出，结构如图8所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="DDS相位累加器模块" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/DDS%E7%9B%B8%E4%BD%8D%E7%B4%AF%E5%8A%A0%E5%99%A8%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图8：DDS模块&lt;/p&gt;
&lt;p&gt;由DDS原理我们可知：K=f&lt;sub&gt;0&lt;/sub&gt;/f&lt;sub&gt;c&lt;/sub&gt;*2&lt;sup&gt;N&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;其中f&lt;sub&gt;c&lt;/sub&gt;为250MHz，f&lt;sub&gt;0&lt;/sub&gt;为25MHz，N为32，计算出K值约为429496730，输出相位信息后，通过查表的方式我们得到最终结果。&lt;/p&gt;
&lt;p&gt;IP核加二选一数据选择器实现方式，如图9所示**：**&lt;/p&gt;
&lt;p&gt;&lt;img alt="DDS波形IP核与数据选择器" loading="lazy" src="https://blog.laning.org/images/2022-12-19-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%BA%8C/DDS%E6%B3%A2%E5%BD%A2IP%E6%A0%B8%E4%B8%8E%E6%95%B0%E6%8D%AE%E9%80%89%E6%8B%A9%E5%99%A8.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;图9：IP核加二选一数据选择器实现&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;二.基于SignalTap分析重点时序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本次实验，我们理论上应该看到经过自己设计的DDS模块与调用IP核相比延迟更低。BPSK调制的基本流程如下：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;调制信息与通过PN码发生器进行扩频，通过扩频操作可以降低我们调制信息的峰值，减少信息被检测的概率。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DDS模块产生我们所需频率的载波信号，将经过扩频的调制信息通过调相的方式，0和1选择相反相位，即相差为pi的，从而实现BPSK的全过程。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;三.反思与总结&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1.关于系统时钟c0（250MHz）难以达到&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为我们的FPGA的默认时钟频率为50MHz，想要达到250MHz对我们开发板有一些困难，所以我们可以适当降低c0的时钟频率，比如可以选择200MHz作为系统时钟。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.总结反思&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本次基于FPGA的BPSK设计实验，从了解PN码这种扩频通信的理念，到通过查找表的方式，实现直接数字频率合成技术，得到我们所需频率的载波信号，到最后通过调相的方式，将我们的信号调制到载波信号钟，从而实现BPSK。进一步熟悉了FPGA开发的整体流程以及模块化的复用思想，了解数字通信调制信息的过程。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;四.参考文献&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>FPGA工程应用开发综合实验报告一</title><link>https://blog.laning.org/posts/wp-0122/</link><pubDate>Wed, 30 Nov 2022 00:28:28 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0122/</guid><description>&lt;p&gt;基于LCD的显示系统设计&lt;/p&gt;
&lt;p&gt;2022年11月30日&lt;/p&gt;
&lt;p&gt;摘 要&lt;br&gt;
本次基于FPGA的LCD显示系统设计，在熟悉Quartus基本操作、Verilog编程语言的基本规则、SignalTap的基本应用后，通过自顶向下、分模块设计后进行连接的方式，完成控制FPGA在LCD屏幕显示内容。&lt;br&gt;
本次设计分为PLL分频模块、上电复位模块、显示控制模块、显示驱动模块组成。通过分功能分模块的设计方式，便于调试，较好地完成了本次设计任务。&lt;/p&gt;
&lt;p&gt;一、 实验需求分析&lt;br&gt;
技术指标分析&lt;br&gt;
（1） 功能指标分析&lt;br&gt;
通过FPGA控制LCD，实现在LCD上显示自己姓名英文书写，对外提供良好的接口，可实现修改源代码来显示不同内容。&lt;br&gt;
（2） 性能指标分析&lt;/p&gt;
&lt;p&gt;二、 系统方案设计&lt;br&gt;
顶层设计&lt;br&gt;
图1：Cyclone IV E FPGA芯片和 LCD模块间连接示意图&lt;/p&gt;
&lt;p&gt;&lt;img alt="Cyclone-IV与LCD模块连接示意" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/Cyclone-IV%E4%B8%8ELCD%E6%A8%A1%E5%9D%97%E8%BF%9E%E6%8E%A5%E7%A4%BA%E6%84%8F.png"&gt;&lt;/p&gt;
&lt;p&gt;表1：LCD模块引脚配置说明&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD模块引脚配置表" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%A8%A1%E5%9D%97%E5%BC%95%E8%84%9A%E9%85%8D%E7%BD%AE%E8%A1%A8.png"&gt;&lt;/p&gt;
&lt;p&gt;分析图1、表1，我们能得到FPGA与LCD模块之间是8根数据线、5根控制线，为了简化我们程序内部的逻辑，经过分析，在本次实验中，我们只对LCD进行写操作，而误差控制我们通过增大每次写数据后的延时来减小，所以LCD_RW可以始终置0；LCD_ON始终置1；LCD_BLON可始终置1或0。&lt;br&gt;
进而我们得到了下面的顶层设计&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示系统顶层框图" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E7%B3%BB%E7%BB%9F%E9%A1%B6%E5%B1%82%E6%A1%86%E5%9B%BE.png"&gt;&lt;/p&gt;
&lt;p&gt;三、 模块设计&lt;br&gt;
例如：&lt;br&gt;
1）PLL分频模块&lt;br&gt;
由于实验板载FPGA提供50MHz晶振，通过Quartus自带的PLL模块，为了更快实现在LCD上显示所需内容，设置参数，产生50MHz的时钟，作为本次设计的系统时钟，如图1所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="PLL系统时钟模块" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/PLL%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%92%9F%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图1 PLL模块&lt;/p&gt;
&lt;p&gt;2）上电复位模块&lt;br&gt;
本模块接收PLL分频后所得的50MHz时钟信号，通过Cont变量进行计数计时，便于后续模块使用，框图如图2：&lt;/p&gt;
&lt;p&gt;&lt;img alt="上电复位模块" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/%E4%B8%8A%E7%94%B5%E5%A4%8D%E4%BD%8D%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图2 计数器模块&lt;br&gt;
3）显示驱动模块&lt;br&gt;
本模块接收系统时钟与上电复位模块输出以及显示控制模块的输出mLCD_Done；产生mLCD_Start信号、8位数据线内容和LCD_RS信号,如图3所示：&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示驱动模块" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E9%A9%B1%E5%8A%A8%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图3 显示驱动模块&lt;/p&gt;
&lt;p&gt;在此显示之前，我们需要位LCD进行初始化操作，分析图4，我们需要配置LCD的基本功能，具体代码与分析如下：&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD初始化指令代码" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E5%88%9D%E5%A7%8B%E5%8C%96%E6%8C%87%E4%BB%A4%E4%BB%A3%E7%A0%81.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD控制指令功能表" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%8E%A7%E5%88%B6%E6%8C%87%E4%BB%A4%E5%8A%9F%E8%83%BD%E8%A1%A8.png"&gt;&lt;/p&gt;
&lt;p&gt;图4 1602LCD控制指令&lt;br&gt;
有限状态机分析（如图5）：&lt;br&gt;
S0：写内容，将数据内容送给数据线，并自动跳转状态S1；&lt;br&gt;
S1：等待mLCD_done信号，有效时跳转到状态S2；&lt;br&gt;
S2：计数延时，为了简化程序，我们通过延迟来保证数据正确写入到LCD中，当延时结束，计数归零，并跳转到状态S3；&lt;br&gt;
S3：当S2的延时后，S3在LCD显示屏上自动向后移位，并跳转到状态S0&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示驱动有限状态机" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E9%A9%B1%E5%8A%A8%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA.png"&gt;&lt;/p&gt;
&lt;p&gt;图5 有限状态机示意图&lt;br&gt;
由编码表找到需要的字符对应的二进制表示，代码如下，映射表如图6：&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示字符编码代码" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%E4%BB%A3%E7%A0%81.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD字符编码映射表" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81%E6%98%A0%E5%B0%84%E8%A1%A8.png"&gt;&lt;/p&gt;
&lt;p&gt;图6 字符映射表&lt;br&gt;
4）显示控制模块&lt;br&gt;
本模块接收系统时钟与上电复位模块输出以及mLCD_start作为输入，输出为LCD_EN与mLCD_done信号，如图7：&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示控制模块" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E6%8E%A7%E5%88%B6%E6%A8%A1%E5%9D%97.png"&gt;&lt;/p&gt;
&lt;p&gt;图7 显示控制模块&lt;/p&gt;
&lt;p&gt;&lt;img alt="LCD显示控制有限状态机" loading="lazy" src="https://blog.laning.org/images/2022-11-30-FPGA%E5%B7%A5%E7%A8%8B%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91%E7%BB%BC%E5%90%88%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A%E4%B8%80/LCD%E6%98%BE%E7%A4%BA%E6%8E%A7%E5%88%B6%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA.png"&gt;&lt;/p&gt;</description></item><item><title>CSAPP学习笔记</title><link>https://blog.laning.org/posts/wp-0105/</link><pubDate>Thu, 14 Jul 2022 13:45:10 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0105/</guid><description>&lt;h1 id="深入理解计算机系统c语言数据结构微嵌编译原理数电模电"&gt;深入理解计算机系统（C语言、数据结构、微嵌、编译原理、数电、模电）&lt;/h1&gt;
&lt;h2 id="第一章计算机系统漫游"&gt;第一章：计算机系统漫游&lt;/h2&gt;
&lt;p&gt;编译系统&lt;/p&gt;
&lt;p&gt;hello.c-&amp;gt;hello.i&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -E hello.c -o hello.i
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;hello.i-&amp;gt;hello.s&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -S hello.i -o hello.s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;hello.s-&amp;gt;hello.o&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -c hello.s -o hello.o
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;hello.o-&amp;gt;hello&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc hello.o -o hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="第二章信息的表示和处理"&gt;第二章：信息的表示和处理&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//数据在不同架构处理器下的表示
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;typedef&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;unsigned&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; byte_pointer;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show_bytes&lt;/span&gt;(byte_pointer start, &lt;span style="color:#66d9ef"&gt;size_t&lt;/span&gt; led)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;size_t&lt;/span&gt; i;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; (i &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; ;i &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; led; i&lt;span style="color:#f92672"&gt;++&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%.2x&amp;#34;&lt;/span&gt;,start[i]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show_int&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;show_bytes&lt;/span&gt;((byte_pointer)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x,&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show_float&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt; x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;show_bytes&lt;/span&gt;((byte_pointer)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x,&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;float&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;show_pointer&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;show_bytes&lt;/span&gt;((byte_pointer)&lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x,&lt;span style="color:#66d9ef"&gt;sizeof&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; i &lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;12345&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;show_int&lt;/span&gt;(i);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="整数浮点数在计算机内部的表示与运算"&gt;整数、浮点数在计算机内部的表示与运算&lt;/h3&gt;
&lt;h2 id="第三章程序的机器级表示"&gt;第三章：程序的机器级表示&lt;/h2&gt;
&lt;h3 id="whiledo-whilefor性能分析"&gt;while、do-while、for性能分析&lt;/h3&gt;
&lt;p&gt;三种都是通过条件测试和跳转指令实现的。&lt;/p&gt;</description></item><item><title>OpenStick折腾日记</title><link>https://blog.laning.org/posts/wp-0103/</link><pubDate>Mon, 11 Jul 2022 01:37:34 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0103/</guid><description>&lt;h2 id="项目起因"&gt;项目起因&lt;/h2&gt;
&lt;p&gt;最近网上火起了用淘宝8.8购买随身WIFI,其处理器为msm8916，这是一款4核ARMV8架构的64位处理器，酷安&lt;/p&gt;
&lt;p&gt;社区有大佬通过逆向工程为其编译了Debian、OpenWRT镜像，本次安装的是Debian11的镜像。&lt;/p&gt;
&lt;h2 id="环境准备"&gt;环境准备&lt;/h2&gt;
&lt;p&gt;一台Windows电脑&lt;/p&gt;
&lt;p&gt;随身Wifi&lt;/p&gt;
&lt;h2 id="安装过程"&gt;安装过程&lt;/h2&gt;
&lt;h3 id="备份原系统"&gt;备份原系统&lt;/h3&gt;
&lt;p&gt;为了防止我们操作失误将Stick刷成砖，我们需要先备份Stick原系统。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;备份工具&lt;a href="https://pan.baidu.com/s/1ocF7B79xgsXr5KquIx8cDg?pwd=4w5h"&gt;下载地址&lt;/a&gt; 提取码：4w5h&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装9008驱动，按住随身WIFI上的按钮插入电脑USB口，在电脑设备管理器-端口设备里能看到 9008 的 COM 设备就说明连接上了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装miko，打开文件夹MiKo_Pro，双击安装miko并将 Loader 粘贴到安装的路径下面（默认在 C:\Program Files (x86)\miko_service_tool_pro\miko_service_tool_pro），打开 Loader&lt;/p&gt;
&lt;p&gt;然后在 miko 里依次选择 Read – Partition Backup/Earese – 点击左下角 Load Partition Structure 看到右边有系统信息的输出就说明连上了。&lt;/p&gt;
&lt;p&gt;然后点击 Read Full Image 选个路径，取个名字就开始全量备份救砖能用的 .bin 文件。过程会比较慢，可能要十几分钟。等到跑完进度条 100% 右边的输出显示 success 就备份好了，我们就能开始随意折腾。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;进入fastboot模式，备份完后重新插拔（这次重启不需要按随身wifi上的按钮），然后打开搞机工具箱，（注意此处应该显示有一台设备）选择线刷专区，重启到 Fastboot，一般重启 fastboot 后随身 Wi-Fi 会亮红灯。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="刷入新系统"&gt;刷入新系统&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;下载&lt;a href="https://github.com/OpenStick/OpenStick/releases/download/v1/base.zip"&gt;base.zip&lt;/a&gt; 并解压；下载&lt;a href="https://github.com/OpenStick/OpenStick/releases/download/v1/debian.zip"&gt;debian.zip&lt;/a&gt; 并解压&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在base文件夹下双击执行flash.bat，注意期间可能需要几次回车，完成后关闭窗口。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在debian文件夹下双击执行flash.bat，同样注意需要几次回车，完成后关闭窗口即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;刷机完成。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="基本使用"&gt;基本使用&lt;/h2&gt;
&lt;h3 id="windows通过ssh连接stick"&gt;Windows通过ssh连接Stick&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;大佬提供的系统镜像默认开启了ssh服务，但是我们需要通过NDIS来为Stick分配网络地址，此时我们可能会遇到驱动问题，此处我建议看看&lt;a href="https://www.kancloud.cn/handsomehacker/openstick/2636506"&gt;OpenStick Wiki&lt;/a&gt; 提供的解决方案，此处我做一点补充说明，安装上面的操作后，我们会在设备管理器中发现一个未知设备，为次设备添加NDIS驱动即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stick默认的IP地址为192.168.68.1 默认用户为user 密码为1&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh user@192.168.68.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="为stick连接wifi"&gt;为Stick连接Wifi&lt;/h3&gt;
&lt;p&gt;虽然随身WIFI在购买时可能厂商提供了免费的流量套餐，但是，这种免费一般都是限额的，所以我们此处考虑使用nmcli工具在命令行为OpenStick连接我们的WIFI&lt;/p&gt;</description></item><item><title>Python正则化</title><link>https://blog.laning.org/posts/wp-0102/</link><pubDate>Fri, 08 Jul 2022 10:42:23 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0102/</guid><description>&lt;h3 id="python正则化"&gt;Python正则化&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;符号&lt;/th&gt;
&lt;th&gt;解释&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;.&lt;/td&gt;
&lt;td&gt;匹配任意字符&lt;/td&gt;
&lt;td&gt;b.t&lt;/td&gt;
&lt;td&gt;可以匹配bat / but / b#t / b1t等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\w&lt;/td&gt;
&lt;td&gt;匹配字母/数字/下划线&lt;/td&gt;
&lt;td&gt;b\wt&lt;/td&gt;
&lt;td&gt;可以匹配bat / b1t / b_t等 但不能匹配b#t&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\s&lt;/td&gt;
&lt;td&gt;匹配空白字符（包括\r、\n、\t等）&lt;/td&gt;
&lt;td&gt;love\syou&lt;/td&gt;
&lt;td&gt;可以匹配love you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\d&lt;/td&gt;
&lt;td&gt;匹配数字&lt;/td&gt;
&lt;td&gt;\d\d&lt;/td&gt;
&lt;td&gt;可以匹配01 / 23 / 99等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\b&lt;/td&gt;
&lt;td&gt;匹配单词的边界&lt;/td&gt;
&lt;td&gt;\bThe\b&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;^&lt;/td&gt;
&lt;td&gt;匹配字符串的开始&lt;/td&gt;
&lt;td&gt;^The&lt;/td&gt;
&lt;td&gt;可以匹配The开头的字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;匹配字符串的结束&lt;/td&gt;
&lt;td&gt;.exe$&lt;/td&gt;
&lt;td&gt;可以匹配.exe结尾的字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\W&lt;/td&gt;
&lt;td&gt;匹配非字母/数字/下划线&lt;/td&gt;
&lt;td&gt;b\Wt&lt;/td&gt;
&lt;td&gt;可以匹配b#t / b@t等 但不能匹配but / b1t / b_t等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\S&lt;/td&gt;
&lt;td&gt;匹配非空白字符&lt;/td&gt;
&lt;td&gt;love\Syou&lt;/td&gt;
&lt;td&gt;可以匹配love#you等 但不能匹配love you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\D&lt;/td&gt;
&lt;td&gt;匹配非数字&lt;/td&gt;
&lt;td&gt;\d\D&lt;/td&gt;
&lt;td&gt;可以匹配9a / 3# / 0F等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;\B&lt;/td&gt;
&lt;td&gt;匹配非单词边界&lt;/td&gt;
&lt;td&gt;\Bio\B&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[]&lt;/td&gt;
&lt;td&gt;匹配来自字符集的任意单一字符&lt;/td&gt;
&lt;td&gt;[aeiou]&lt;/td&gt;
&lt;td&gt;可以匹配任一元音字母字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[^]&lt;/td&gt;
&lt;td&gt;匹配不在字符集中的任意单一字符&lt;/td&gt;
&lt;td&gt;[^aeiou]&lt;/td&gt;
&lt;td&gt;可以匹配任一非元音字母字符&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;匹配0次或多次&lt;/td&gt;
&lt;td&gt;\w*&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+&lt;/td&gt;
&lt;td&gt;匹配1次或多次&lt;/td&gt;
&lt;td&gt;\w+&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;匹配0次或1次&lt;/td&gt;
&lt;td&gt;\w?&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{N}&lt;/td&gt;
&lt;td&gt;匹配N次&lt;/td&gt;
&lt;td&gt;\w{3}&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{M,}&lt;/td&gt;
&lt;td&gt;匹配至少M次&lt;/td&gt;
&lt;td&gt;\w{3,}&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{M,N}&lt;/td&gt;
&lt;td&gt;匹配至少M次至多N次&lt;/td&gt;
&lt;td&gt;\w{3,6}&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;|&lt;/td&gt;
&lt;td&gt;分支&lt;/td&gt;
&lt;td&gt;foo|bar&lt;/td&gt;
&lt;td&gt;可以匹配foo或者bar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?#)&lt;/td&gt;
&lt;td&gt;注释&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(exp)&lt;/td&gt;
&lt;td&gt;匹配exp并捕获到自动命名的组中&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?&amp;lt;name&amp;gt;exp)&lt;/td&gt;
&lt;td&gt;匹配exp并捕获到名为name的组中&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?:exp)&lt;/td&gt;
&lt;td&gt;匹配exp但是不捕获匹配的文本&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?=exp)&lt;/td&gt;
&lt;td&gt;匹配exp前面的位置&lt;/td&gt;
&lt;td&gt;\b\w+(?=ing)&lt;/td&gt;
&lt;td&gt;可以匹配I&amp;rsquo;m dancing中的danc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?&amp;lt;=exp)&lt;/td&gt;
&lt;td&gt;匹配exp后面的位置&lt;/td&gt;
&lt;td&gt;(?&amp;lt;=\bdanc)\w+\b&lt;/td&gt;
&lt;td&gt;可以匹配I love dancing and reading中的第一个ing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?!exp)&lt;/td&gt;
&lt;td&gt;匹配后面不是exp的位置&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;(?&amp;lt;!exp)&lt;/td&gt;
&lt;td&gt;匹配前面不是exp的位置&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*?&lt;/td&gt;
&lt;td&gt;重复任意次，但尽可能少重复&lt;/td&gt;
&lt;td&gt;a.&lt;em&gt;b a.&lt;/em&gt;?b&lt;/td&gt;
&lt;td&gt;将正则表达式应用于aabab，前者会匹配整个字符串aabab，后者会匹配aab和ab两个字符串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+?&lt;/td&gt;
&lt;td&gt;重复1次或多次，但尽可能少重复&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;??&lt;/td&gt;
&lt;td&gt;重复0次或1次，但尽可能少重复&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{M,N}?&lt;/td&gt;
&lt;td&gt;重复M到N次，但尽可能少重复&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{M,}?&lt;/td&gt;
&lt;td&gt;重复M次以上，但尽可能少重复&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="python对正则表达式的支持"&gt;Python对正则表达式的支持&lt;/h3&gt;
&lt;p&gt;Python提供了re模块来支持正则表达式相关操作，下面是re模块中的核心函数。&lt;/p&gt;</description></item><item><title>华迪实习</title><link>https://blog.laning.org/posts/wp-0101/</link><pubDate>Wed, 06 Jul 2022 16:06:47 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0101/</guid><description>&lt;hr&gt;
&lt;h2 id="6月24日"&gt;&lt;mark&gt;6月24日&lt;/mark&gt;&lt;/h2&gt;
&lt;h3 id="pc与嵌入式计算机"&gt;PC与嵌入式计算机&lt;/h3&gt;
&lt;p&gt;参考微处理器与嵌入式系统设计课程内容。介绍计算机的体系结构、组成等。&lt;/p&gt;
&lt;h3 id="开发环境及配置"&gt;开发环境及配置&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;介绍了在VMware中安装Ubuntu20.04LTS的方法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;介绍通过运维三大神器之一sed来实现CLI换源操作，对sudo apt update命令作用做了分析介绍&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装openssh服务端，通过xshell、secureCRT、CMD、powershell等工具来实现对linux的访问，此处也介绍了systemctl命令的常用用法status、enabled、start等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;介绍cd ls mkdir rm 等文件操作命令及参数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;介绍文件权限管理命令chmod以及文件类型判断、文件权限修改等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;介绍环境变量的概念，以及影响环境变量的多个配置文件，有系统级和用户级配置文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;介绍tar的归档打包与解包&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="总结"&gt;总结&lt;/h3&gt;
&lt;p&gt;第一天实习主要工作是配置Linux（Ubuntu）环境，学习并实践Linux常用命令（主要针对的是文件管理的命令）。因为有Linux基础，学习起来相对轻松。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="6月25日"&gt;&lt;mark&gt;6月25日&lt;/mark&gt;&lt;/h2&gt;
&lt;h3 id="vivim的安装与使用"&gt;vi/vim的安装与使用&lt;/h3&gt;
&lt;p&gt;vim是Linux命令行最强大的编辑器之一，快捷键操作是它最大的特点。拥有Linux基础不再过多描述这一部分&lt;/p&gt;
&lt;h3 id="交叉编译环境的搭建"&gt;交叉编译环境的搭建&lt;/h3&gt;
&lt;p&gt;交叉编译是指在x86的平台上从源代码开始编译适用于arm架构的程序，甚至是x86_64编译arm32的程序。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ubuntu20.04最小安装缺少基本的C的编译环境，我们可以从apt包管理器下载安装基本的编译环境&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#安装为64位的环境&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install build-essential
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#若需要32位的函数库支持&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install lib32stdc++6
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#为gcc编译32位程序做准备&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo dpkg --add-architecture i386
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt install gcc-multilib g++-multilib
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="2"&gt;
&lt;li&gt;至此，我们搭建了Ubuntu上编译x86和x86_64位C程序的环境，接下来我们通过SecureFX、winSCP等软件上传开发板的arm下的C语言编译器，并进行如下操作&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#此为归档文件，我们用tar命令解包,注意此为绿色软件（已经编译好的二进制文件），为了Linux的使用规范，我们将其解包到/usr/local下，而/usr/local是root用户的目录，普通用户需要sudo权限才能进行写的操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo tar jxvf arm-2014.05-29-arm-none-linux-gnueabi-i686-pc-linuxgnu.tar.bz2 -C /usr/local
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#检查是否安装完成&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/arm-2014.05/bin/arm-none-linux-gnueabi-gcc -V
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;至此，我们完成了检查编译环境的搭建，我们使用此环境简单编译hello world程序&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/usr/local/arm-2014.05/bin/arm-none-linux-gnueabi-gcc hello.c -o hello
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="4"&gt;
&lt;li&gt;
&lt;p&gt;添加环境变量&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo vim /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;添加以下内容
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/usr/local/arm-2014.05/bin:$PATH
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#使上面修改生效&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;source /etc/profile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id="6月24日-1"&gt;&lt;mark&gt;6月24日&lt;/mark&gt;&lt;/h2&gt;
&lt;h3 id="通过内核控制lde亮灭"&gt;通过内核控制LDE亮灭&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/stat.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/ioctl.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; fd;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; ret;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/dev/leds&amp;#34;&lt;/span&gt;,O_RDWR);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;fd)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;打开设备失败&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;exit&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/types.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/stat.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;sys/ioctl.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; fd;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; ret;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/dev/leds&amp;#34;&lt;/span&gt;,O_RDWR);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;==&lt;/span&gt;fd)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;打开设备失败&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;exit&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ioctl&lt;/span&gt;(fd,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="linux内核编译"&gt;Linux内核编译&lt;/h3&gt;
&lt;p&gt;Linux内核编译的重点是.config文件的修改，即自己需要选择适合自己机器（开发板）的套件，而我们为了简化难度，.config文件老师已经给出，我们执行下面的命令&lt;/p&gt;</description></item><item><title>Markdown学习笔记</title><link>https://blog.laning.org/posts/wp-0097/</link><pubDate>Sat, 28 May 2022 19:32:57 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0097/</guid><description>&lt;h2 id="什么是markdown"&gt;什么是Markdown？&lt;/h2&gt;
&lt;p&gt;Markdown是一种轻量标记语言，可以转换为HTML文本，Github的README.md一般遵循Markdown语法规范。&lt;/p&gt;
&lt;h2 id="typora编辑器"&gt;Typora编辑器&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Typora支持&lt;em&gt;&lt;strong&gt;跨平台&lt;/strong&gt;&lt;/em&gt;，支持Windows、MacOS、Linux&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Typora支持多种导出模式，可导出为多种PDF、Latex等&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="markdown基本语法"&gt;Markdown基本语法&lt;/h2&gt;
&lt;h3 id="标题"&gt;标题&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;# 标题名&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;#个数表示不同层级标题&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="文字"&gt;文字&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;*内容*或_内容_表示斜体文字&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;**内容**或__内容__表示加粗字体&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;***内容***或__内容___表示斜体加粗字体&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~~内容~~表示删除线&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;u&amp;gt;内容&amp;lt;/u&amp;gt;表示下划线&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;***或---或___表示分割线&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;==内容==表示高亮&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;H~2~O 下标表示&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;面积 m^2^ 上标表示&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="表情"&gt;表情&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;:smile :china&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="列表"&gt;列表&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;*或+或-创建无序列表&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;1.+空格创建有序列表&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="表格"&gt;表格&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;name | price
:--- | :---:
chicken | 5
coco | 3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;lsquo;:&amp;mdash;表示左对齐:&amp;mdash;:表示居中对齐&amp;rsquo;&lt;/p&gt;
&lt;h3 id="引用"&gt;引用&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; 表示引用&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;支持嵌套引用如&amp;gt;&amp;gt;表示二级引用&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="代码"&gt;代码&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;`内容`表示行内代码
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;```语言类型 表示代码块
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="跳转"&gt;跳转&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;[link text](link)为外部跳转&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[link text](#目的名称)为内部跳转&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;url&amp;gt;表示超链接&lt;/code&gt;&lt;/p&gt;
&lt;h3 id="图片"&gt;图片&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;![link text](link)&lt;/code&gt;&lt;/p&gt;</description></item><item><title>多平台挂载Webdav</title><link>https://blog.laning.org/posts/wp-0094/</link><pubDate>Fri, 20 May 2022 11:33:30 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0094/</guid><description>&lt;h2 id="webdav有什么用"&gt;webdav有什么用？&lt;/h2&gt;
&lt;p&gt;在日常工作应用中，我们常常有下面的需求场景：在公司没有完成的工作，可能需要在家继续办公，而我们需要同步在公司的工作进度，最朴素的解决方法就是用U盘进行拷贝，但如果你有webdav等文件传输工具，我们可以完全省去这个繁琐的过程。webdav通过挂载云盘服务到本地，在不同设备都开启webdav,即可实现资源共享；webdav是基于http的文本传输协议，这意味着如果你能接入互联网，就能实现文本共享；同时webdav可以跨平台挂载在本地使用，这意味着你不需要考虑从Linux到Windows对于中文编码方式而出现乱码不同的尴尬；同时，例如阿里云盘、群晖NAS、Google云盘等都提供了webdav服务，这意味着你可以像使用本地硬盘一样访问你的云盘资源。&lt;/p&gt;
&lt;h3 id="声明本人拥有群晖nas所以下文的配置等可能会以群晖nas配置作为示例但配置方法与其他云盘区别不大有需求的可以作为参考"&gt;声明：本人拥有群晖NAS,所以下文的配置等可能会以群晖NAS配置作为示例，但配置方法与其他云盘区别不大，有需求的可以作为参考。&lt;/h3&gt;
&lt;h2 id="windows"&gt;Windows：&lt;/h2&gt;
&lt;p&gt;Windows平台一直以其丰富的图像化软件，在这里我推荐一款好用的webdav客户端软件:&lt;/p&gt;
&lt;p&gt;RaiDrive&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href="https://www.raidrive.com/download"&gt;https://www.raidrive.com/download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;RaiDrive提供可视化操作和中文界面，具体配置可自行摸索。&lt;/p&gt;
&lt;h2 id="linux"&gt;Linux：&lt;/h2&gt;
&lt;p&gt;图像化操作：&lt;/p&gt;
&lt;p&gt;如果你是将Linux作为主力机的用户，并且安装了KDE、GNOME这类桌面环境，我们可以使用桌面环境的文档管理器在网络、其他位置这些地方选择挂载Webdav。&lt;/p&gt;
&lt;p&gt;关于GNOME桌面，我的系统环境为ArchLinux+GNOME桌面，在挂载基于https的davs服务失败，但是挂载http的dav服务成功，出于安全考虑，我舍去了这种挂载方法。&lt;/p&gt;
&lt;p&gt;命令行操作：&lt;/p&gt;
&lt;p&gt;命令行需要安装davfs2工具：&lt;/p&gt;
&lt;p&gt;安装：&lt;/p&gt;
&lt;p&gt;Ubuntu/Debian：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt install davfs2&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Arch/Manjaro：（pacman不提供这个工具，我们需要AUR来下载）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;yay -S davfs2&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;配置：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/davfs2/davfs2.conf &lt;/code&gt; 删掉前面的注释符号并修改为：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;use_locks 0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ignore_dav_header 1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/davfs2/secrets&lt;/code&gt; 在文件末尾添加：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://damain:port/path username userpassword&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;说明：需要指定域名、端口、群晖NAS文件路径、用户名、密码&lt;/p&gt;
&lt;p&gt;配置开机自动挂载：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/fstab&lt;/code&gt; 在文件末尾添加：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://damain:port/path /mnt/webdav davfs rw,user,uid=username,noauto 0 0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;p&gt;username为系统用户名&lt;/p&gt;</description></item><item><title>local</title><link>https://blog.laning.org/posts/wp-0084/</link><pubDate>Fri, 22 Apr 2022 15:54:22 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0084/</guid><description>&lt;h1 id="pip换源"&gt;&lt;strong&gt;pip换源&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;配置文件地址：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;~/.config/pip/pip.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;文件内容：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;命令行操作：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;附清华大学开源镜像站pypi帮助：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/help/pypi/"&gt;https://mirrors.tuna.tsinghua.edu.cn/help/pypi/&lt;/a&gt;&lt;/p&gt;
&lt;h1 id="vimrc"&gt;&lt;strong&gt;.vimrc&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;Github项目地址：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/amix/vimrc"&gt;https://github.com/amix/vimrc&lt;/a&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone --depth=1 https://github.com/amix/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_awesome_vimrc.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;~/.vim_runtime/vimrcs/extended.vim中 可以禁用主题和背景色，搭配终端配置透明终端&lt;/p&gt;
&lt;h1 id="zshrc"&gt;&lt;strong&gt;.zshrc&lt;/strong&gt;&lt;/h1&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r &amp;#34;${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh&amp;#34; ]]; then
source &amp;#34;${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh&amp;#34;
fi
if [[ ! -f $HOME/.zi/bin/zi.zsh ]]; then
print -P &amp;#34;%F{33}▓▒░ %F{160}Installing (%F{33}z-shell/zi%F{160})…%f&amp;#34;
command mkdir -p &amp;#34;$HOME/.zi&amp;#34; &amp;amp;&amp;amp; command chmod g-rwX &amp;#34;$HOME/.zi&amp;#34;
command git clone -q --depth=1 --branch &amp;#34;main&amp;#34; https://github.com/z-shell/zi &amp;#34;$HOME/.zi/bin&amp;#34; &amp;amp;&amp;amp; \
print -P &amp;#34;%F{33}▓▒░ %F{34}Installation successful.%f%b&amp;#34; || \
print -P &amp;#34;%F{160}▓▒░ The clone has failed.%f%b&amp;#34;
fi
source &amp;#34;$HOME/.zi/bin/zi.zsh&amp;#34;
autoload -Uz _zi
(( ${+_comps} )) &amp;amp;&amp;amp; _comps[zi]=_zi
# examples here -&amp;gt; https://z-shell.pages.dev/docs/gallery/collection
zicompinit # &amp;lt;- https://z-shell.pages.dev/docs/gallery/collection#minimal zi light-mode for \ z-shell/z-a-meta-plugins \ @annexes @molovo zi light romkatv/powerlevel10k zi light zsh-users/zsh-syntax-highlighting zi load zsh-users/zsh-completions # To customize prompt, run `p10k configure` or edit ~/.p10k.zsh. [[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh alias ls=&amp;#34;ls --color&amp;#34; alias ll=&amp;#34;ls -al&amp;#34; eval $(thefuck --alias) alias proxy=&amp;#39;http_proxy=&amp;#34;127.0.0.1:10809&amp;#34; https_proxy=&amp;#34;127.0.0.1:10809&amp;#34;&amp;#39; alias vi=vim # &amp;gt;&amp;gt;&amp;gt; conda initialize &amp;gt;&amp;gt;&amp;gt;
# !! Contents within this block are managed by &amp;#39;conda init&amp;#39; !!
__conda_setup=&amp;#34;$(&amp;#39;/usr/bin/conda&amp;#39; &amp;#39;shell.zsh&amp;#39; &amp;#39;hook&amp;#39; 2&amp;gt; /dev/null)&amp;#34;
if [ $? -eq 0 ]; then
eval &amp;#34;$__conda_setup&amp;#34;
else
if [ -f &amp;#34;/usr/etc/profile.d/conda.sh&amp;#34; ]; then
. &amp;#34;/usr/etc/profile.d/conda.sh&amp;#34;
else
export PATH=&amp;#34;/usr/bin:$PATH&amp;#34;
fi
fi
unset __conda_setup
# &amp;lt;&amp;lt;&amp;lt; conda initialize &amp;lt;&amp;lt;&amp;lt;
alias s=sudo
alias sv=&amp;#34;sudo vim&amp;#34;
alias spm=&amp;#34;sudo pacman&amp;#34;
alias sc=&amp;#34;sudo cat&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id="debianubunturaspbianarmbian换源"&gt;&lt;strong&gt;Debian/Ubuntu/Raspbian/Armbian换源&lt;/strong&gt;&lt;/h1&gt;
&lt;p&gt;软件源配置文件地址：&lt;/p&gt;</description></item><item><title>WireGuard配置</title><link>https://blog.laning.org/posts/wp-0078/</link><pubDate>Tue, 19 Apr 2022 20:34:22 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0078/</guid><description>WireGuard配置的一些示例</description></item><item><title>通信协议原理实验</title><link>https://blog.laning.org/posts/wp-0075/</link><pubDate>Sun, 03 Apr 2022 12:45:55 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0075/</guid><description>UESTC计算机通信网P类实验一</description></item><item><title>树莓派自编译opencv</title><link>https://blog.laning.org/posts/wp-0066/</link><pubDate>Fri, 03 Dec 2021 22:10:51 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0066/</guid><description>&lt;h2 id="项目介绍"&gt;项目介绍&lt;/h2&gt;
&lt;p&gt;OpenCV是一个基于BSD许可发行的跨平台计算机视觉和机器学习软件库，可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效，同时提供了Python、Ruby、MATLAB等语言的接口，实现了图像处理和计算机视觉方面的很多通用算法。而树莓派作为一款非常流行的开发学习平台，很多开发者的人工智能项目都基于opencv，然而，树莓派的软件源一般提供的都是opencv3.4.0这种老版本，这个项目将分享如何在树莓派上源码编译并安装指定版本的opencv。&lt;/p&gt;
&lt;h3 id="说在前面"&gt;说在前面&lt;/h3&gt;
&lt;p&gt;即便是最新的树莓派4B代（4G）版本，在一切顺利的情况下，编译安装完成本项目也大概需要5个小时以上，所以如果没有特殊要求可以考虑用清华源（其他软件源不太清楚是否有对应的软件包）直接安装opencv，关于如何换清华源不多赘述，请自行百度。换源之后，命令行依次执行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt install python3-opencv
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="1环境配置"&gt;1.环境配置&lt;/h3&gt;
&lt;p&gt;（建议SSH远程连接树莓派操作，省去自己输入命令的烦恼）&lt;/p&gt;
&lt;p&gt;现在你假设已经正确更换软件源，包括apt和pip，不换源在环境配置这一步可能会花费很多没必要花费的时间&lt;/p&gt;
&lt;p&gt;对于一些博主进行扩容的操作思路，本人并没有进行所谓的扩容，且没有出现卡死的现象，所以本教程没有扩容这一步&lt;/p&gt;
&lt;p&gt;安装opencv环境依赖，依次执行下面命令&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y cmake g++ wget unzip
&lt;/code&gt;&lt;/pre&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install build-essential git cmake pkg-config -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libjpeg8-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libtiff5-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libjasper-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libpng12-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libgtk2.0-dev -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo apt-get install libatlas-base-dev gfortran -y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2下载源码并解压"&gt;2.下载源码并解压&lt;/h3&gt;
&lt;p&gt;（建议SSH远程连接树莓派操作，省去自己输入命令的烦恼）&lt;/p&gt;</description></item><item><title>树莓派远程访问——向日葵解决方案</title><link>https://blog.laning.org/posts/wp-0062/</link><pubDate>Fri, 03 Dec 2021 20:03:54 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0062/</guid><description>&lt;h2 id="项目介绍"&gt;项目介绍&lt;/h2&gt;
&lt;p&gt;树莓派是一款口袋型电脑，拥有丰富的外设接口，同时不错的计算能力，完善的生态（可安装多种Linux操作系统），吸引了一大批技术爱好者加入树莓派社区。要想实现远程访问树莓派GUI界面，除了常用的VNC解决方案，在这里我推荐一个工具——向日葵，它很好地解决了在无公网IP的情况下，树莓派GUI访问的问题。&lt;/p&gt;
&lt;h3 id="1环境要求"&gt;1.环境要求&lt;/h3&gt;
&lt;p&gt;Raspbain_bullseye_arm64镜像，下载链接：&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_arm64/images/raspios_arm64-2021-11-08/2021-10-30-raspios-bullseye-arm64.zip"&gt;https://mirrors.tuna.tsinghua.edu.cn/raspberry-pi-os-images/raspios_arm64/images/raspios_arm64-2021-11-08/2021-10-30-raspios-bullseye-arm64.zip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;更换Debian的软件源（注意此处必须是对应系统版本Debian的软件源，而非Raspbian的软件源），更换方法如下：（&lt;a href="https://mirrors.tuna.tsinghua.edu.cn/help/debian/"&gt;参考清华大学开源软件镜像站使用帮助&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;命令行执行&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo nano /etc/apt/sources.list
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注释掉原有的软件源，即在未注释行前面加#号，并复制粘贴以下内容``&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
# deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;依次 ctrl+o 回车 ctrl+x&lt;/p&gt;
&lt;p&gt;如果细心观察你会发现我们这里使用了Debian11(bullseye)的系统但是使用的是Debian10(buster)的软件源，因为树莓派向日葵客户端的.deb包依赖只有buster能解决（截止2022年5月9日），如果后续需要使用可以在安装完向日葵客户端后再次换源Debian11(bullseye)&lt;/p&gt;
&lt;p&gt;换源方法在文尾，此处可继续执行后续步骤。&lt;/p&gt;
&lt;p&gt;接下来命令行执行下面的命令使上述变更生效&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt update
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="2下载并安装向日葵客户端"&gt;2.下载并安装向日葵客户端&lt;/h3&gt;
&lt;p&gt;通过git命令克隆.deb文件地址，命令行依次执行&lt;/p&gt;</description></item><item><title>hello world!</title><link>https://blog.laning.org/posts/wp-0052/</link><pubDate>Tue, 30 Nov 2021 23:27:56 +0800</pubDate><guid>https://blog.laning.org/posts/wp-0052/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
void main()
{
printf(&amp;#34;hello world\n&amp;#34;);
return;
}
&lt;/code&gt;&lt;/pre&gt;</description></item></channel></rss>