XiNGRZ's BLOG

一些唠叨

终于有空把我收到的 HW-75 组起来了

前段时间收到了稚晖君和 Xikii 搞的那套瀚文 HW-75,一直没空整。这几天居家办公,终于组装起来了。

过程…略。说来惭愧,这是我第一次接触客制化,所以我的经历没什么参考价值。

整体效果

  • 键帽:PBTfans 深海来客
  • 轴体:TTC 月白
  • 卫星轴:Owlab v3 黑武士

没啥讲究,咱也不懂…在 zhudi 的店里按销量随便挑的。

好,那我折腾了个啥呢…

其实接触客制化键盘之前我就偶然发现过一个键盘固件项目 —— ZMK。它是一个基于 Zephyr 的客制化键盘固件。正因为是基于 Zephyr,所以它天生能兼容各种不同的平台,除了键圈耳熟能详的 STM32F103 之外,还支持 ESP32 系列、nRF 系列等。主要是 Zephyr 我熟啊 (doge)

好,那就动手。

烧 Bootloader

SWD

瀚文的 PCB 上预留了一个 4P PH1.0 插座的调试口,接上 DAPLink 就能烧固件。但是每次烧固件都要拆开,或者调试的时候都得一直保持拆开状态,是不优雅的。这时候我们就需要一个可以直接从 USB 更新固件的 bootloader。

之前稚晖君预告过一个 DFU bootloader,后来鸽了。所以我自己移植了一个。详情可以看我之前的分享

如上图所示,从左到右分别是 GND、SWDIO、SWCLK、5V,某宝随便买个 DAPLink 调试器(甚至合宙的白菜价 Air32 开发板)对应插上即可。注意如果你键盘插着 USB 了,那么 5V 就不用接了。

DAPLink

烧完。按住 Fn 键(空格往右第二个)插上 USB 即可进入 DFU 模式。

烧 ZMK

我已经移植好了:https://github.com/xingrz/zmk-config_xikii_hw-75

按住 Fn 进 DFU 模式,然后还是按照上面那个分享烧就行。

键位映射

我做的是 Mac 的键位映射。

ZMK 默认带了几种灯效。可以通过 Fn 组合键切换:

  • Fn + Tab:开关
  • Fn + Q/A:切换效果
  • Fn + W/S:调整亮度
  • Fn + E/D:调整色相
  • Fn + R/F:调整饱和度
  • Fn + T/G:调整动画速度

结尾

以上就是我的一点分享。各位有什么想法可以留言。后续我会在 ZMK 上继续完善一些功能。

玩了一把 wasm

最近发现了 wasm-micro-runtime 这么个小玩意,一个超小的 wasm 运行时。随手记录下。

0. 先看全貌

在 wasm-micro-runtime (简称 wamr) 里要把一个程序从源文件一直到跑起来,会经历以下步骤:

1
test.c --[wasi-sdk]-> test.wasm --[wamrc]-> test.aot --[iwasm]-> 跑起来

如你所见,现在我需要 wasi-sdk wasmrc iwasm 这仨玩意儿。

1.环境准备

1.1. 取得 wasi-sdk

现成的。在 https://github.com/WebAssembly/wasi-sdk/releases 找到对应你系统的版本下载解压即可。这里假设你把它解压到了 /opt/wasi-sdk。实际上放哪无所谓。

1.2. 编译 iwasm:wamr 运行时

wamr 官方已经提供了几个不同平台的运行时。我用 macOS,直接有现成的:

1
2
cd product-mini/platforms/darwin
cmake -G Ninja -B build && cmake --build build

你可能发现我的编译命令和官方的不一样…没错,cmake 本身就有 -B--build,大可不必手动 mkdir build && cd make,多麻烦。而且 Ninja 香啊~

跑完,build/iwasm 就是当前平台的运行时。

1.3. 编译 wamrc:AOT 编译器

先编译一遍 LLVM 的一些库,需要的时间比较久。不得不说,原版脚本用的是 GNU Makefiles 是真的慢…所以我又夹带了点私货

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
diff --git a/build-scripts/build_llvm.py b/build-scripts/build_llvm.py
index bc0daf1f..9cd23d51 100755
--- a/build-scripts/build_llvm.py
+++ b/build-scripts/build_llvm.py
@@ -114,11 +114,7 @@ def build_llvm(llvm_dir, platform, backends, projects):
)

CONFIG_CMD = f"cmake {compile_options} ../llvm"
- if "windows" == platform:
- if "mingw" in sysconfig.get_platform().lower():
- CONFIG_CMD += " -G'Unix Makefiles'"
- else:
- CONFIG_CMD += " -A x64"
+ CONFIG_CMD += " -G Ninja"
print(f"{CONFIG_CMD}")
subprocess.check_call(shlex.split(CONFIG_CMD), cwd=build_dir)

跑它:

1
python build-scripts/build_llvm.py --platform darwin --arch ARM X86

然后编译 wamrc。这里我同样用 Ninja,比官方的命令快多了。

1
2
cd wamr-compiler
cmake -G Ninja -B build && cmake --build build

跑完,同样得到了 build/wamrc

2. 编译应用

先来个简单的程序,我假设它叫 test.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
char *buf;

printf("Hello world!\n");

buf = malloc(1024);
if (!buf) {
printf("malloc buf failed\n");
return -1;
}

printf("buf ptr: %p\n", buf);

sprintf(buf, "%s", "1234\n");
printf("buf: %s", buf);

free(buf);
return 0;
}

编译它

1
$ /opt/wasi-sdk/bin/clang -O3 -o test.wasm test.c

现在,你得到了一个 test.wasm 文件了。理论上,你可以直接用 iwasm 去执行它。但我想玩玩 AOT。所以继续。

1
2
3
4
5
6
7
8
9
$ ./wamrc -o test.aot test.wasm
Create AoT compiler with:
target: x86_64
target cpu: westmere
cpu features:
opt level: 3
size level: 1
output format: AoT file
Compile success, file test.aot was generated.

现在你得到了一个 test.aot,执行它:

1
2
3
4
$ ./iwasm test.aot
Hello world!
buf ptr: 0x114e0
buf: 1234

完成!

3. 顺带一提

编译 wamrc AOT 编译器之前,使用 build_llvm.py 编译 LLVM 运行库时所传入的参数,--platform 表示当前 (也就是运行 wamrc 的构建机) 平台,--arch 表示需要 wamrc 支持生成的目标架构。具体可选值可执行 build-scripts/build_llvm.py --help 查看。

如果你需要生成 Xtensa 目标,直接传入 --arch Xtensa 会遇到两个问题,需要额外处理一下。

一是由于 LLVM 的 Xtensa 支持目前还是试验阶段,需要一个宏打开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
diff --git a/build-scripts/build_llvm.py b/build-scripts/build_llvm.py
index bc0daf1f..db8dd1f7 100755
--- a/build-scripts/build_llvm.py
+++ b/build-scripts/build_llvm.py
@@ -66,7 +66,9 @@ def build_llvm(llvm_dir, platform, backends, projects):
"windows": [
"-DCMAKE_INSTALL_PREFIX=LLVM-install",
],
- "default": [],
+ "default": [
+ '-DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD:STRING="Xtensa"',
+ ],
}

LLVM_TARGETS_TO_BUILD = [

二是由于官方 llvm/llvm-project 不支持 Xtensa 目标,需要换成乐鑫的 espressif/llvm-project

1
2
3
4
5
cd core/deps/llvm
git remote set-url origin https://github.com/espressif/llvm-project.git
git fetch origin xtensa_release_13.0.0:xtensa_release_13.0.0 --depth 1
git checkout xtensa_release_13.0.0
cd ../../..

删掉 build 重新编译一下。

1
2
rm -rf core/deps/llvm/build
python build-scripts/build_llvm.py --platform darwin --arch Xtensa

4. 参考资料

做了个基于 Web 的 Gerber 渲染器

关注我比较久的人可能知道,我之前会利用 tracespace 和一些脚本配合将我做的 PCB 渲染成效果图。但是每次操作的步骤有点繁琐。于是在鸽了不知道多久后…我终于自己做了一个工具来完成这件事情了。

image

特性:

  1. 可以将 Gerber 渲染成 SVG 或 PNG (高达 100 dots per mm 的分辨率)
  2. 内置了几种常见配色方案 (咖喱创用户都懂)
  3. 支持渲染浮雕材质,便于你扔进 3D 软件渲染出逼真的铜层凹凸效果 (用法见 BV1pK4y1g7fY)

地址:gerber.xingrz.me

image
image
image
image

关于新博客

上一篇文章说了,我不喜欢用 Jekyll 写博客。具体来说,我不喜欢在代码仓里码字。我觉得这么做很奇怪,感觉我需要正襟危坐打开 VSCode,准备各种图片素材,git commitgit push

那这次重开的博客,怎么解决这个问题呢?简而言之,Issues 和 Actions。

GitHub Issues 本身就可以充当一个内容管理系统。你想想:它支持 Markdown,它的 open 和 closed 状态正好可以对应草稿和发布,它的 labels 就是 tags…它甚至可以粘贴带图!

image

How?

这一整个流程,可以简化如下:

  1. 我有一个私有仓,xingrz/blog,我在里面码字

  2. 我有一个公开仓,xingrz/xingrz.github.io,用来发布 GitHub Pages

  3. 在私有仓里,我做了一个 sync workflow。只要 Issues 有任何变化,就触发公开仓的另一个 deploy workflow

    image
  4. 公开仓的 deploy workflow 作用很简单,就是拉取私有仓的 Issues,生成 posts,然后生成最终 HTML,部署

    image

公开仓的 deploy workflow,大家自己也可以看到:deploy.yml。它的另一个关键是 sync.mjs 这个用来拉取 Issues 并生成 posts 的脚本。

私有仓的 sync workflow 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
name: Sync posts

on:
issues:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: sync
cancel-in-progress: true

jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Sync
run: gh workflow run deploy.yml
env:
GH_REPO: xingrz/xingrz.github.io
GH_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

如果你想把这套流程用到你自己的博客,你需要开一个 Personal Access Token 分别加到两个仓库的 Secrets 里(名称为 DEPLOY_TOKEN)。并且对应更改这两个 workflow 里的 GH_REPO 变量。

挖坑

基于 Actions,可以有更多玩法,比如:

  • 自动发一条 Telegram channel 广播
  • 调用 Puppeteer 生成长截图

以后再说吧。

结语

好了,这篇分享就到这里。主要就是想试试真正用这个流程发一篇文章而已。

博客又重开了

为什么呢

刚毕业工作的时候试着写了一段时间博客。后来因为 Jekyll 每次新建文章都过于严肃,慢慢地就鸽了(刚刚去翻了翻仓库,甚至有一篇草稿躺了 8 年没写完)。

这几年有时候会忍不住码一条非常长的微博来分享一些技术。但是逐渐发现这种分享还是应该好好地用 Markdown 写下来。想来想去,决定还是重新搭一个博客好一点。

就看这次会在什么时候鸽了。

Proudly powered by Hexo and Theme by Hacker
© 2022 XiNGRZ