这个项目差点就烂尾了...

低并发编程

共 3352字,需浏览 7分钟

 · 2021-05-14

大家好,我是小麦,这次想和大家分享一下我做一个小项目的一些心得和感悟。

这个项目不是什么很牛逼的大项目,是一个基于全志的一款SOC的项目。中间遇到过不少问题,差点就烂尾了,索性最后坚持下来了。

起源

这次为什么要做这个小项目呢?

因为去年刚学了一下一个开源的EDA软件 —— KiCad。然后为了练一下手,所以就一时兴起打算做一个Linux小板;开始画PCB,买物料,自己焊接,不亦乐乎,不过中间也有很多辛酸。

因为大家知道,一般的SOC,因为产品尺寸有要求,集成度很高,所以通常是BGA封装,另外片外还需要加ddremmc,就是ram和rom了,同样的,这两者往往也是BGA封装,所以焊接难度也很大;

于是我就在想,有没有对我这样的手残党友好一点的方案呢?

然后我找了一段时间,后来想起之前网上老外的一个项目 linux business card的一个项目,看了一下是全志的F1C100S,内置32M的ddr,有lqfpqfn的封装,可以外接spi的nor flash或者从sd进行启动。

QFN封装
LQFP封装

这?简直是手残党的福音啊。

第一版的时候,我用Kicad画好原理图和PCB,还用keyshot很装逼地渲染了一下PCB,虽然效果差强人意,但是自我感觉逼格比之前高了很多;

下面是第一版PCB的效果的视频;

首战失利

不知道为什么脑子抽了一下,直接采购的是qfn封装的芯片,强行给游戏增加了难度;然后买了一个廉价的热风枪(可以吹出300℃—450℃热风的设备);

春节在家是极其简陋的焊接环境,就开干了;

顺便说一下焊锡丝里是含有铅的,这几天手工焊电路板,闻多了,感觉都要提前变成老年痴呆了;

艰苦的环境

实际焊了一些QFN的芯片,感觉也不是很难,先用电烙铁在焊盘上涂上锡,然后用风枪吹一下就好了,后面再补锡,防止有的地方虚焊;

焊好了第一块电路板,只焊好了电源管理部分,还有主芯片,然后问题就来了;

废了

芯片需要三路电源,3.3V,2.5V,1.1V;

3.3V是系统电源,2.5V是给内部DDR供电的,1.1V是IO电源;

然后我测试的时候发现,在焊上主芯片之后,2.5V电源的输出就是0V;

奇怪的是,我把主芯片拆下来,这三路电压输出又恢复正常了,因为我是先把电源部分的电路焊好的,并且测试输出正常之后,才焊的芯片;

我怀疑可能这部分没有焊好,存在引脚的虚焊或者连焊;

之后,我又做了两块板子,发现原来的问题还是存在。

到底是什么问题呢?这期间也有请教了一些硬件方面的大佬,也尝试了很多的测试方法,好几次心灰意冷。

后面又调试了一段时间,没有实质性的进展,决定放弃当前版本。

准备改版;

三块尸体

屡败屡战

中间搁置了一段时间后,重新设计了第二版的PCB,我把原来的PMIC方案换了,参考开源的荔枝派,直接单芯片输出三路3.3V,2.5V和1.1V

顺便板子颜色换成了蓝色,总体感觉比绿色和黑色的阻焊漆更好;


新旧对比

工欲善其事必先利其器,顺便还改善了一下工作环境,接下来就继续战斗吧。第二次次焊起来比第一次顺手多了;

调试PMIC

不过在调试PMIC的时候,使用万用表测量输出电压,不小心把一个地方弄短路了,导致一个电感短到3.3V上,直接烧毁冒烟了。

内心很慌,后来排查了并不是硬件设计上的问题,终于三路输出的电压都正常了,长舒一口气,也算是一个小插曲。

下一步就是烧录固件了,板子接到电脑上,板子是作为usb device,电脑作为host。

板子这边是usb otg的接口(既可以作为device,也可以作为host),usb的引脚一般包括VCC,GND,D+和D-,还有一个usb_id;

usb_id根据引脚的上下拉,来区别当前的工作状态(是host还是device);通常作为usb device时候,这个引脚要进行上拉,作为主机的时候,要进行上拉;

不巧的是,我默认给板子的usb_id下拉了,所以,通过sunxi-tool去枚举usb设备的时候,就出现了错误提示;

错误提示

没有办法,最后经过飞线,可以成功识别到USB设备了;

发现设备

最终焊完的板子,背面贴了一块屏幕;

最终形态

后面,编译了一份uboot,但是烧写的时候又出问题了,提示usb传输错误,这下可把我难道了,心中的猜测:

  1. 硬件的问题,然后把flash的引脚都补锡补了一遍,主芯片的spi接口引脚用烙铁刮了一遍,然后重新补了一下锡,确保没有虚焊和连焊,然后,问题依然没有解决;
  2. 软件的问题,排查了libusb的问题,我先后在Linux上重新安装了这个库,依然没有解决这个问题;顺便在Windows系统重新搭建了测试环境,依然存在问题。

我陷入了困境,并且不知道如何解决这个问题,差点烂尾。

当时想过要放弃:“这个版本如果再不行,这个项目就不搞了”。

然后我安慰自己,再尝试一下别的办法,说不定就解决了。

于是我测试了PMIC的输出,3.3V,这是实际只有3.1V—3.2V左右,然后怀疑:会不会电压太低造成的呢?

抱着疑问,调了一下DCDC的电阻,改变了一下电源的输出,稳定在3.4V左右;歪打正着,经过测试,发现问题就这样解决了,后面工作都比较稳定。

于是可以正常烧录固件了;

烧录成功

系统移植

硬件的坑才是大问题,移植方面因为有不少开源的案例,所以也相对比较轻松;

总结一下是四个步骤;

  • 环境搭建;
  • uboot的移植;
  • linux kernel的移植;
  • 文件系统;

烧录uboot,就是要把程序烧写到flash中,绝大多数都是从 0 地址开始执行;

对于大部分的 SoC 而言,芯片执行其内部的固化 i-bootloader 之后就会从外部的 flash 来执行 bootloader,然后就芯片就会执行我们所烧录的 uboot 了。

这个是uboot正常烧录之后的串口终端输出的log,还没有烧kernel

uboot的log

uboot是芯片最开始会执行的程序,比如x86的电脑的BIOS,差不多的道理;不过芯片内部都会固化一段启动代码,F1C100S也不例外;

uboot启动之后,就要开始启动内核了;

这里简单介绍一下bootargsbootcmd

bootcmd一般都会包含 bootm 或者 bootz 指令 ;

  • bootz:因为kernel和rootfs都保存在flash中,所以要先将他们搬运到ram中;
  • bootm:搬运完之后开始启动内核;

然后根据bootargs这个环境变量,向内核传递参数;

参考如下;

bootargs=console=ttyS0,115200 panic=5 rootwait root=/dev/mtdblock3 rw rootfstype=jffs2

其中

console=ttyS0,115200:表示控制台终端定向到串口0,波特率115200;

panic=5:表示传递参数错误的时候,程序会进入死循环,并在5秒后重启内核;

rootwait:表示是让内核进入无限等待,因为启动时间无法预估,就让内核无限等待直到启动完成;

root=/dev/mtdblock3:表示文件系统挂载到mtd设备的分区3上;

rw:表示当前文件系统是可读可写的;

rootfstype=jffs2:文件系统类型,在配置内核时选择支持该类型;

kernel启动成功了,但是文件系统也挂载成功了,但是没有成功,提示/bin/sh exists but couldn't execute it

错误提示

用buildroot编译的根文件系统,上面的问题在我努力排查下也顺利解决了,主要是rootfs中的文件没有可执行权限;

成功进入系统的log
点击放大
点击放大

总结

整体过程还是很好玩的,虽然遇到意料之外的问题很虐心,但是问题一个个解决之后,感觉还是很棒,因为做这个东西不需要取悦任何人,自己快乐就行了;所以,劳资屏幕就先不调了。

最后,无论是生活中,还是工作中,难免都会遇到困难和挫折,不要轻易放弃,坚持到最后,一定能成功,共勉!!!


—— The End ——
浏览 20
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报