查看: 10447|回复: 0

干货 | 解锁多重姿势为Beaglebone Black制作cape

[复制链接]
  • TA的每日心情

    2018-8-2 13:58
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2019-8-8 18:39:54 | 显示全部楼层 |阅读模式
    分享到:
    如果你买来BBB是为了搞跟硬件相关的项目,那你八成需要制作一个cape。cape是BBB官方的叫法,其实就是指BBB的软件和硬件外设。通过学习device tree我们了解到BBB是使用capemgr和device tree来控制cape的,通过向$SLOTS传入dtbo文件来加载某个cape,像这样:

    • echo BB-ADC > $SLOTS


    但有时候我们不想每次都手动输入这样一条命令来启用某个cape,而是想让它开机自动启动。这时就需要用到本文讲的内容了。

    要做到开机自动启动,你只需要增加一个eeprom(官方推荐的型号是CAT24C256),并把它接到特定的引脚上,里面写上符合规定格式的内容就行了。系统在启动时会检查特定引脚上有没有符合规定格式的eeprom,如果有的话,就按照eeprom里面的内容自动加载相应的dtbo文件。

    还记得我们 cat $SLOTS 看到了什么吗?

    • cat /sys/devices/bone_capemgr.*/slots  
    • 0: 54F---   
    • 1: 55F---   
    • 2: 56F---   
    • 3: 57F---   
    • 4: ff-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G  
    • 5: ff-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI


    这里前4项为什么是空的呢?因为它们就是给那些有EEPROM的实体cape预留的位置。不难看出,这样的实体cape最多只能插4个。

    二、eeprom的连接

    2.jpg
    这里的知识比较零散,我将分点阐述:

    • eeprom的地址必须在0x54到0x57之间,否则系统不会加载。科普一下:不管什么牌子的eeprom芯片,它们的地址都是一样的,高4位是1010,低3位对应着芯片的A2,A1,A0这3个引脚的电平(有的芯片只有A1和A0),所以通过外接电路就能改变eeprom的地址。也就是说eeprom的地址只可能是0x50到0x57这8种,如果A2保持高电平,那么就只有0x54到0x57这4个地址可用了(这就是SRM(BBB官方参考手册)里eeprom电路中把A2接高电平的原因。
    • eeprom必须连接到BBB的I2C2_SCL和I2C2_SDA引脚上(在系统中看到的是i2c-1)。因为I2C2这两个引脚的默认功能就是i2c功能。这也告诉我们,程序中尽量不要永久改变这两个引脚的功能复用,否则就没法加载cape了。
    • BBB最多只支持同时插4个eeprom,它们的地址必须互不相同。
    • 如果一次插入多个eeprom,会依次读取之。准确来说,读取顺序就是从0x54到0x57的顺序。为什么如此强调overlay的加载顺序呢?因为一旦前面加载的overlay占用了某些片上资源,其他overlay就不能再用了。比如我要做的LCD使用的引脚跟默认加载的HDMI用的引脚是有重叠的,当系统启动时首先加载了LCD的overlay,那么HDMI就不能再加载了。
    • eeprom上WP引脚是写保护用的,一旦上拉,就不能进行写入了。所以自己做电路的时候可以把它悬空或者拉低。


    三、eeprom的读写

    下面先介绍如何进行读写,再介绍该写入什么东西。

    首先确定eeprom的地址。由A0,A1,A2三个引脚的电平确,按照上面刚刚说的,比如我把A0,A1接地,A2拉高,地址就是0x54。

    然后在命令行操作:

    • cd /sys/bus/i2c/devices/1-0054/  #到eeprom目录中  
    • cat eeprom | hexdump -C  #读取eeprom内容并以字符形式显示  
    • echo -e "\xaa\x55\x33\xeeA1Beaglebone LCD4 Cape\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0000A1BeagleboardToys\x00BB-BONE-LCD4-01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" > eeprom  #写入内容  
    • cat eeprom | hexdump -C  #确认是否写入成功  

    其中\x开头的字符代表按ASCII码值写入。上面就写入了官方LCD4 cape的eeprom内容。如果你想自制LCD cape,使用的LCD面板参数跟官方的一样的话,那么系统使用的驱动程序就是一样的,所以就可以直接用上面的eeprom内容加载BBB自带的dtbo文件了,就不必自己重写dtbo文件了。

    写入内容时,要按照SRM里的标准(如下图),最重要的是要把头6个字节\xaa\x55\x33\xeeA1以及后面的版本号00A1和要调用的dtbo文件名BB-BONE-LCD4-01写对,其他的比Number of Pins什么的都无所谓。空余的地方必须用\x00补全,用其他字符会产生错误。

    3.jpg
    经过上面的方法配置好eeprom后,系统就能在启动时自动加载对应的dtbo文件了。但是这里还是再强调一下dts文件编写的注意事项。

    四、编写dts文件的注意事项
    • 文件名必须是 boardname-version.dts 的形式,比如 BB-BONE-LCD4-01-00A0.dts。这里面BB-BONE-LCD4-01就是boardname,00A0就是version号。(其实dts的名字无所谓了,关键是编译出来的dtbo名字必须是它,为了统一,就都这么规定吧)。

    • version必须是00AX的形式,X从0开始按版本依次增加,而且,想命名00A1,必须有00A0的存在才行!不能跨越版本!
    • dts文件里面会有part-number和version这两项,其内容必须跟文件名相符!part-number就是boardname。
    • 编译完的dtbo文件必须放到 /lib/firmware/ 目录中才可以加载。


    OK,上面介绍了所有cape通用的内容。具体某个cape需要加载特定的驱动,那就是如何写dts文件和配置驱动的问题了,在此就不做讨论啦。

    五、其实不用eeprom也能做 uEnv.txt

    其实不用eeprom的话,也可以通过修改uEnv.txt文件来实现自动加载dtbo文件。USB连接好BBB以后在电脑里会出现一个盘符,里面有一个叫做uEnv.txt的文件。通过它可以设置系统启动时加载或禁止加载的dtbo。比如我想在系统启加载BB-ADC。我们就可以打开它,在下面添加一行:

    • optargs=quiet capemgr.enable_partno=BB-ADC


    然后安全弹出这个盘符,重启BBB就行啦。

    我们知道BBB启动会自动加载HDMI,而HDMI与LCD公用了部分引脚。如果我们想启动后再插上LCD,然后 echo BB-BONE-LCD4-01 > $SLOTS 来加载LCD cape的话,会提示你File exists,就是因为HDMI已经首先加载了,那些引脚就不能再动了。但我们可以配置uEnv.txt使得启动时不自动加载HDMI,方法是在uEnv.txt中添加一行:

    • optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN


    就OK啦。

    注意,如果想同时实现上面两个,即禁用HDMI并加载ADC的话,不能简简单单把上面两句话写进去,应该合并成一句话:

    • optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN capemgr.enable_partno=BB-ADC


    否则会失败。

    所以,使用eeprom的意义就在于方便啦。什么也不用配置,买回来插上就能用。如果你爱折腾的话,那么实现方法就多了去啦。

    六、其实不用eeprom也能做 systemd

    上面说的修改uEnv.txt的方法其实跟用eeprom的效果是差不多的——一个不能用的话另一个也不能用= =!

    6月的Angstrom系统(终端输入 uname -a 查看你的BBB里装的是哪个版本的系统)有bug,如果你自己编译了一个dtbo文件,即便放进 /lib/firmware 目录下也不能自动加载(/lib/firmware里原本就有的可以加载是因为它们已经被编译进内核了)。所以除非你自己编译一遍系统,否则不能用这个办法在启动时自动加载自己的cape。刚说了用uEnv.txt跟用eeprom差不多……所以也不行。

    9月的Angstrom系统稍微修改了这个bug,但还是不好用——系统启动时会在加载cape那步停留60秒才继续……本来Angstrom是以启动速度快见长的,只需10秒。这一下拖了太多后腿了。(而且9月的Angstrom系统增添了新的bug——LCD电阻触摸屏指针会漂移!想自己解决这个问题当然依旧只能重新编译系统——不是每个人都有耐心编译系统玩的!所以即便它是新系统,我还是果断使用6月的吧,至少触摸屏正常。)

    总之,无论哪个版本的Angstrom系统,eeprom和uEnv.txt法都不太好使,下面就介绍一个完全不同的招数:使用systemd。

    Step by step教学:

    Step 1.
    在/etc/systemd/system目录下新建一个文件,命名mystartup.service(名字可以自定),内容如下:

    • [Unit]
    • Description=My script
    • [Service]
    • ExecStart=/home/root/mystartup.sh
    • [Install]
    • WantedBy=multi-user.target


    Description是写给自己看的注释,可以随便写。mystartup.sh是要启动时自动执行的脚本。

    注意:不能写成ExecStart=/bin/sh /path/to/script.sh这样的,直接按上面给出的例子写就好了。

    Step 2.
    然后在 /home/root 目录新建一个mystartup.sh,内容如下:
    • #!/bin/sh
    • echo BB-YOUR-CAPE > /sys/devices/bone_capemgr.8/slots


    注意:
    1、这里必须用sh脚本,不能用bash脚本。
    2、sh脚本中不能使用bone_capemgr.*这样的通配符,必须是bone_capemgr.8或者.9(根据你的系统来写)
    3、当然,dtbo文件还是必须得放在 /lib/firmware 下才行。

    Step 3.
    最后执行命令:
    • systemctl enable myscript.service


    就可以了。重启BBB会发现成功加载了dtbo。

    如果你执行dmesg | grep capemgr,会发现加载dtbo的时间点跟用eeprom或uEnv.txt不同,所以跟启动以后手动输入 echo 命令的效果类似。

    七、结束

    我当然推荐第六种方法。预计在找到更好的办法之前,这就是我将来在Development Kit里采用的办法了。想要使用我的Kit的话建议掌握这个小技巧。

    最后这句写给能看懂的人,看不懂就不必深究了:crontab @reboot 在BBB的Angstrom里不好使,不用尝试了。似乎会被系统kill掉。

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-18 22:08 , Processed in 0.115953 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.