1 v0.1.0 的开发过程

我有一个 Raspberry Pi 4b 和 Raspberry Pico,后者也是树莓派基金会发布的一个微控制器开发板。其中芯片是树莓派基金会自研的 RP 2040,可以拿来做控制。

Pico 官方给了 microPython 和 C/C++ 的 SDK,一般来说前者对底层硬件的封装更为完备,而后者就暴露了更多的硬件属性,更适合用来做一些高性能开发,我目前偏向于后者。

pico

供电上,Pico 可以 USB 接口供电,亦可通过 5v 针脚供电。另外,它也引出了为数不少的支持各类通信协议的针脚。Pin 39 VSYS 即可 5v 电压供电,另外 Pin 1/2 可通过串口进行程序的烧录,底部三个 debug 针脚可以直接开展相应的调试工作。

Pico 支持两种烧录模式,一种是长按 BOOTSET 按钮后将它插入电脑 USB 接口中再把编译好的 uf2 文件拖入到系统挂载的大容量存储设备中,一种是串口用 OpenOCD 直接命令烧录。前者更适合小白,但是在 debug 或者其他一些需要频繁烧录的时候就让人很不方便,你要不断的插拔 USB 线,过程中还要按着 BOOTSET 按钮;后者相对来说就更方便了,敲敲键盘就好,不必要频繁动手去做一些物理操作。

显然后者更为优雅,我也想要后者那种优雅的开发模式,但这东西连接串口的时候就又会有一堆看起来乱糟糟的杜邦线。

pi2pico

pi2pico-1

上图展示了最终比较理想的连接效果,即 Rpi 4b 为 Pico 5v 供电,同时二者之间用串口进行程序烧录,SWD 进行程序的寄存器级别调试,全流程不需要按什么按钮或者插拔什么线缆,双手可以不离开键盘完成这一切。敏捷调用一些小模块的时候,用杜邦线去简单测试一下这当然没问题,但是串口烧录、供电和 debug 这种伴随全开发流程的东西居然还要一直连着那种乱七八糟的线,我不希望这样。

PCB 什么作用?其中一个不就是搞掉这些乱糟糟的走线的么…… 那就画个板好了,虽然以前从未正式探索过这棵科技树。

1.1 硬件部分

某宝找了一圈,没有我想要的那种东东,只好自己动手做,又喜闻嘉立创可以免费打板,这更坚定了我去薅羊毛的决心没钱。女朋友说立创 EDA 傻瓜式画 PCB,那应该就很适合我这个新手,下好立创 EDA,嘉立创下单助手,开始干活。一开始我并不怎么明白 PCB 的设计流程,就只好对着官方的操作手册边做边看,同时不断问自己「为什么要有这么一个流程?这流程是做什么的」这种问题,还好,最后几个小时就基本明白了。

schematic

首先是原理图,原理图给出的是各个电子器件之间的逻辑联结关系,它描述了各个器件之间是怎么连接的,或者说,是表达「哪个接口和哪个接口连一起」这个问题的工具。画图的时候,我对最初的想法有了略微的改动:把 Pico 和 Rpi 4b 的引脚都引了出来,再按照上述要求把相应的针脚连接到一起,我又额外在 Rpi 4b 的 5v 引脚上引出了一对给风扇供电的引脚。这里还有个问题,就是说怎么确定每个模块的封装,我一开始也根本找不到排母和排针在哪儿,怎么办?多试试,反正选错了女朋友也不会分手,大不了删档重开,谁让你是新手,低效率解决问题是应该的(

pcb

其次是 PCB,这个过程中有一个「原理图转 PCB」的步骤,图中也明显体现了各个模块之间的逻辑联结关系,这个联结关系即由刚刚的原理图给出。值得说明的是,PCB 又分为各种层,名字上叫得天花乱坠让人直呼真看不懂,可简单一想就能理解为什么要这么做了:Photoshop 里建立了电子图片中「图层」的概念,即将不同的元素视作不同的图层,每层之间相互独立又互相耦合 —— 独立编辑,耦合呈像。PCB 中「层」的概念,我的理解和「图层」类似,即把打印字符、实际布线等等分开考虑,类似于一种「元素组」。至于说多层板,我目前涉及不多,对其理解还简单停留在「有多层布线,之间用过孔连接」的程度。其实简单一想,电源也好信号也罢,之间必然会因为电磁效应而互相影响,高速通信(频率高)时这种影响会更强,导致电路系统不能正常工作也完全是有可能的。这还没涉及到更微观的芯片层面上的考虑,想必到那一步必然会有更多的门道在里面,问题总会有些解决方法的。专业工程师的专业体现在哪儿?不就体现在这儿吗……Pico 官方文档上不用针脚供电而用 USB 供电,我觉得可能也有信号干扰等等这些方面的考虑,只是我现在的知识水平或许还达不到那个层次,而且我也不用 Pico 去做一些特别高大上的东西,针脚就先用着吧,出了问题以后就再更新个 Raspico 的版本号。

layout

把相应的元素在 PCB 上摆放完毕之后,就可以进行布线了 —— 用具体的走线把原有的逻辑关系给落地成实际的导线电路。

布线可以手动布也可以自动布,我当然要先试试自动布线,立创 EDA 自动布线有云端和离线两种方式,实际下下来发现这玩意儿也就是用 Java 跑了个本地服务,可能立创 EDA 再去调相应的接口。当时我身边有个计科的朋友在,我随口问他一句这玩意儿实质上是不是就是个图形学上的路径规划问题,他说是。嗯,或许以后有时间可以研究一下。

sdk

这里还有个小插曲,我运行的时候本地服务器这货给我报错端口已占用,这更确定了它是个本地服务了,简单看了下它的目录结构,我想扒出来它配置文件然后看看它究竟用了哪个端口,如上图所示,这肯定要打开 config 文件夹了,打开发现里面又有个 local,这和刚刚确定的本地服务器又对应起来了,再进去,main.json 人比花娇地就在那儿趴着呢。

config

打开,标准的配置文件格式,用了 3579 端口。cports 走一波,发现没有被占用。这就有点懵,同时联想到我 Clash 偶尔会开机端口被强制置 0,重启之后恢复正常,感觉这事没这么简单,直接就用了云端布线。这事一直也就搁下了,最近几天我 Jetbrains 全系 IDE 也全部 GG,又促使我去搞定了这个问题,未来更新记录一下这个搞事的过程。

自动布线完毕!

copper-clad

覆铜这个一开始我确实是没怎么搞明白,后来简单查了一下,有些明白了。覆铜我的理解,它就是把一些引脚给连接上大面积的铜箔,然后这个铜箔基本覆盖在整个电路板上 —— 为什么是基本?因为你不能跨过其他走线。这样一来,自然覆铜范围内的电位就和该引脚时刻保持一致了。作用?大概就是可以屏蔽掉一些无关的电磁干扰之类的吧,这个我不太明白,而且我觉得我这么简单的东西覆不覆说实话对性能来说应该是无所谓的,但是这是追求。我决定是给 GND 覆铜,选中 GND 管脚,覆上,感觉还有点好看。

最后加上一些相应管脚的标注,放些相关的注释信息,就搞定了。以下是渲染图:

shot-1

shot-2

shot-3

1.2 软件部分

硬件有了,软件也要相应配合。回归初心,我做这个东西的目的就是要优雅地使用 OpenOCD 和 GDB 进行烧录和 debug,具体配置过程确实挺简单的,不放 Shell 命令记录了,简单说下流程。具体的细节在官方文档中也都有。

首先下好 SDK,配环境变量告诉系统你这玩意儿在哪儿,之后就可以去下 OpenOCD 了,记得装那一堆必须要用的工具链。OpenOCD 下好,初始化编译一下,就可以拿来用了。直接怼命令就好了,一堆参数记得加上,一般就是一些板子的配置文件和 elf 文件的路径啥的比较重要,最后也别忘了 verify reset exit,不然可能引导会出问题。

OpenOCD 命令可以直接地、反复地烧录,你全程不必要去碰开发板,只需要在 Shell 里敲些命令就好了。

树莓派基金会官方也提供了 Pico 在 VSCode 上的 launch.json 和 setting.json。再强调一遍,这里的软件部分所有内容在官方文档中都有具体细节,只不过文档是全英文的。

搞定这些之后,就可以用 Rpi 4b 中的 VSCode 去十分优雅的开发了(写完代码鼠标点一下按钮就可编译,且编译可选 debug、release 等等不同模式,编译完毕之后在内置 shell 中几个命令就可以烧录过去),一般也没啥人去直接插键鼠显示器给 Rpi 4b 用,大家都远程居多,但是远程就不可避免的带来一个性能问题,而性能问题又是一个工程师不能妥协的问题,所以必须要用笔记本上的 IDE 或者 VSCode 开发才行,怎么办?用一些 VSCode remote 插件就好了,相当于用 SSH 去连接,性能上没任何问题,但是配置上有问题。可能是 CMake 配置上出了些什么错,我目前在本地 win11 上调用不了远程的 VSCode CMake 插件,所以只能写写代码,编译的话要用 Shell 命令,烧录自然也是,而且 debug 体验基本没有,这些虽然都能够在 Rpi 远程上补足,但是我不想这么做。

以后解决掉这个问题再在这里更新一次好了,那个时候可能我的水平又更上一层楼了。

下面是全家福。

photo

我本来还有个 Rpi 第三方外壳,配合有风扇,我把风扇从里面掏出来,放到侧面来散热。注意过程中一些比如 Rpi GPIO 接口之类数据的测量和布局,所谓机电不分家嘛,何况电又有硬件和软件呢。

GitHub repo 地址:https://github.com/wolfyzhang-github/Raspico

禅定时刻

今天初冬大雪,昨晚英雄联盟全球总决赛,男生疯狂完了女生欢呼,写作过程中楼下莺歌燕舞连绵不绝,现在我写完了,只有大妈铲雪的声音。雪人堆完终归要铲掉,谁来铲?谁想铲?

这篇文章写了四个小时,小米手环提醒我好几次久坐,我可是一个追求生活质量的人呐。下楼,运动,喝水,用膳!

2 v1.0.0 的开发过程

有了上面第一次设计 PCB 的经验后,第二次就轻车熟路了,这是订单记录:

嘉立创订单记录

第二次的 v1.0.0 相比第一次的 v0.1.0,不管是在 PCB 布局上还是在实际功能上都有了挺大的变动,列举如下:

v0.1.0 v1.0.0
Pico 开发支持 Raspberry Pi 4b 状态屏幕
GPIO 引出标注 GPIO 引出标注
独立风扇电源 独立风扇位置及电源

新版本的设计并不复杂,不过也有个小遗憾在。Raspberry Pi 4b 本身通过软件提供了一个根据 CPU 温度有电压信号变化的 GPIO,但是其电流太小,不足以维持风扇运转,所以需要借助另外的 5v 恒压源来供电,同时外接一个三极管来实现风扇的开关,可我手头没有合适的三极管,只好作罢,取消这个温控功能。

另外新的状态屏幕功能其实也就是通过 GPIO 外接了一块 0.96 寸 OLED,然后系统中运行着一个 Python 进程来获取系统状态并输出到屏幕上,代码也很简单。

如下为 PCB 预览:

PCB-1

实际上这里有个设计阶段比较难看出来的问题,实物到手之后才发现,我也在想怎么能够设计一个流程去规避类似的问题:

photo-1

实物图中可以看到,上图中风扇的供电线实际上是和 OLED 有空间冲突的,这个问题我在设计阶段就没注意到… 不过幸好可以直接接到引出的 GPIO 上,可以将就着挽救一下。

photo-2

PCB 的 layout 过程中我从 Raspberry Pi 4b 的 CAD 图纸上获取到其物理尺寸信息,所以最后我用铜柱把板子固定住了,并加了散热片和硅脂,结合上方直吹的风扇,散热属性算是拉满了。实际上我平时也是把它超频到 2.0Ghz 用(官方标准是 1.5Ghz)。

同样,设计文件也开源至 Github:https://github.com/wolfyzhang-github/Raspico