这个项目差点就烂尾了...
这个项目不是什么很牛逼的大项目,是一个基于全志的一款SOC的项目。中间遇到过不少问题,差点就烂尾了,索性最后坚持下来了。
起源
这次为什么要做这个小项目呢?
因为去年刚学了一下一个开源的EDA软件 —— KiCad。然后为了练一下手,所以就一时兴起打算做一个Linux
小板;开始画PCB,买物料,自己焊接,不亦乐乎,不过中间也有很多辛酸。
因为大家知道,一般的SOC,因为产品尺寸有要求,集成度很高,所以通常是BGA封装,另外片外还需要加ddr
和emmc
,就是ram和rom了,同样的,这两者往往也是BGA封装,所以焊接难度也很大;
于是我就在想,有没有对我这样的手残党友好一点的方案呢?
然后我找了一段时间,后来想起之前网上老外的一个项目 linux business card
的一个项目,看了一下是全志的F1C100S,内置32M的ddr
,有lqfp
和qfn
的封装,可以外接spi的nor flash或者从sd进行启动。
这?简直是手残党的福音啊。
第一版的时候,我用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的时候,使用万用表测量输出电压,不小心把一个地方弄短路了,导致一个电感短到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传输错误,这下可把我难道了,心中的猜测:
硬件的问题,然后把flash的引脚都补锡补了一遍,主芯片的spi接口引脚用烙铁刮了一遍,然后重新补了一下锡,确保没有虚焊和连焊,然后,问题依然没有解决; 软件的问题,排查了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是芯片最开始会执行的程序,比如x86的电脑的BIOS,差不多的道理;不过芯片内部都会固化一段启动代码,F1C100S也不例外;
uboot启动之后,就要开始启动内核了;
这里简单介绍一下bootargs
和 bootcmd
;
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中的文件没有可执行权限;
总结
整体过程还是很好玩的,虽然遇到意料之外的问题很虐心,但是问题一个个解决之后,感觉还是很棒,因为做这个东西不需要取悦任何人,自己快乐就行了;所以,劳资屏幕就先不调了。
最后,无论是生活中,还是工作中,难免都会遇到困难和挫折,不要轻易放弃,坚持到最后,一定能成功,共勉!!!