为BBB制作专属自己的cape(一)

最新更新请见http://blog.csdn.net/wyt2013/article/details/18228095

本文将以制作“LCD显示屏cape”为例记录一下制作Beaglebone Black的cape的过程。目前还没有做完,遇到的困难比想象多得多。。。不过还是先把前面解决的问题和注意事项记录一下吧~

为什么要制作cape?



cape是Beaglebone官方所称的硬件插接外设的统称(完全没有概念的同学可以到 http://elinux.org/Beagleboard:BeagleBone_Capes 这里来看一下)。使用cape的好处是可以把硬件外设模块化。比如今天我想实现某个功能,就插上相应的cape,明天想换个功能,就插上另一个cape。一旦cape做好,今后就无需再为驱动和硬件问题烦心了。BBB的一大优点就是接口多,而且为BBB定制的Angstrom Linux系统也有很多特性方便了我们制作和使用cape。

我的目标是给BBB添加一个LCD显示屏。虽然官方有卖现成的LCD cape,但买回来插上就完事了,感觉过于easy,少了很多乐趣。刚好我手头有一个购买ALIENTEK STM32开发板时一起买的2.4“ TFT LCD触摸屏,我决定就用它改造了。OK,我们马上开始吧!

需要准备的东西


除了LCD,还需要准备 面包板、杜邦线、若干阻值在2K到7K之间的电阻和一个eeprom芯片。(我本来想用ALIENTEK STM32开发板上带的24C02 EEPROM,可是由于一些奇怪的不能用)
eeprom是每个cape上必备的东西。假设你有很多个cape,分别插到BBB上,那么BBB怎么区分你插上的是哪个cape,该加载什么驱动呢?就是靠存在eeprom里的信息来确定的。
ALIENTEK的LCD模块只能用80并口模式,接线更少的SPI模式它竟然不支持。。好吧,只能用杜邦线连接16跟并口线了。。所以要多准备点杜邦线。
电阻是做eeprom i2c接口的上拉电阻使用的。

先说说cape的工作原理


Angstrom Linux使用device tree来 绑定硬件和驱动以及 设定芯片引脚的复用功能,系统内核里存有一个默认的device tree(后缀名是dtb),启动时首先会加载它。然后使用 device tree overlay的方式,在这个默认device tree的基础上” 覆盖“(overlay)上新的硬件和驱动或者remap引脚功能,要用到的覆盖文件的后缀名是dtbo。

BBB自带了很多的dtbo文件,放在 /lib/firmare/ 目录下,大部分dtbo文件都对应着官方支持的cape(就是前面那个网址里的那些cape,正因为系统里已经有了对应的dtbo文件,所以我们买来cape以后才能插上就能用,我们自己要做cape,就只能自己写dtbo文件了)。

接着说系统启动。加载了默认的dtb以后,系统就开始扫描是否有要加载的overlay。系统默认要加载的有两个overlay,对应着板子上的eMMC芯片和HDMI处理芯片。如果没有外接cape的话,就把这两个overlay加载,然后这一步就过去了。不过下面要说一下有外接cape的情况。

说有外接cape,其实不如说有外接eeprom。如果发现有eeprom,并且里面存的信息符合cape要求的格式,那么系统会首先加载这个eeprom里要求加载的overlay(如果同时插了几个eeprom,就依次加载对应的overlay),然后再去加载eMMC和HDMI的overlay(注意加载顺序)。加载完overlay以后,系统再按照overlay的指示进行驱动绑定和引脚复用,然后再继续其他的启动项目。

启动完成以后,硬件和驱动就完美匹配好了,芯片引脚功能也正确了。

(顺便说一句,我是怎么知道这些的?输入dmesg便知。)

几个细节


1、BBB最多只支持同时插 4个eeprom,它们的地址必须互不相同。

2、 eeprom的地址必须在0x54到0x57之间,否则系统不会加载。科普一下:不管什么牌子的eeprom芯片,它们的地址都是一样的,高4位是1010,低3位对应着芯片的A2,A1,A0这3个引脚的电平(有的芯片只有A1和A0),所以通过外接电路就能改变eeprom的地址。也就是说eeprom的地址只可能是0x50到0x57这8种,如果A2保持高电平,那么就只有0x54到0x57这4个地址可用了(这就是SRM(官方参考手册)里eeprom电路中把A2接高电平的原因)。

另外,似乎所有8个引脚的eeprom,它们的引脚布局也都是一样的。(我今天买回来一个24C256的eeprom,一看上面印的标号完全不知道是啥,网上也搜不到。我就按照其他牌子的引脚接上,发现果然能用。。)

3、前面说如果一次插入多个eeprom,会依次读取之。准确来说,读取顺序就是从0x54到0x57的顺序。

为什么如此强调overlay的加载顺序呢?因为 一旦前面加载的overlay占用了某些片上资源,其他overlay就不能再用了。比如我要做的LCD使用的引脚跟默认加载的HDMI用的引脚是有重叠的,当系统启动时首先加载了LCD的overlay,那么HDMI就不能再加载了。

4、eeprom必须连接到BBB的 I2C2_SCL和I2C2_SDA引脚上(在系统中看到的是i2c-1)。因为I2C2这两个引脚的默认功能就是i2c功能。这也告诉我们,程序中尽量不要永久改变这两个引脚的功能复用,否则就没法加载cape了。

5、由上述可以看到,cape是在系统启动时候加载的,所以必须 先插好cape,再给BBB通电但是!对于LCD来说,因为它用到的引脚中有些是与系统启动相关的,所以如果不做额外软件处理的话,LCD模块只能在系统启动完以后才允许装上,否则系统无法启动(具体表现就是电源灯亮了,4个user led一直不亮)。但是eeprom显然必须在上电前就连好。 这就是官方LCD cape电路原理图中buffer芯片(74AVC32T245)的作用,看起来这个芯片的输入和输出是完全相同的,没什么作用,可是它能防止启动前那些LCD引脚电平不稳定。

6、插一句,系统运行时用 echo *** > $SLOTS 来加载虚拟cape时如果遇到 echo: write error: File exists 的提示,不代表这个cape已经加载,而是某些硬件资源已经被占用了的意思。所以系统启动以后你是无法加载与LCD有关的cape的,因为引脚已经被HDMI占用了。

编写自己的overlay(dtbo)


dtbo文件是用dts文件编译而成的(请看我之前的日志),我简要说一下怎么写与某个设备相关的dts文件。

注意,我的假设是需要的驱动都已经装好在系统中了。否则的话,请自行想办法!其实BBB定制的Angstrom系统自带驱动有很多,我手边的芯片都能找到对应的驱动。一般驱动都会带说明文档,特别是关于如何写dts的文档,几乎都有的。你只需要按照里面的例子,结合BBB现有的dts文件(/lib/firmware目录下),自行修改就可以了。
BBB定制的Angstrom系统源码在这里下载https://github.com/beagleboard/kernel。你需要一个桌面linux系统(或者mac os)来解压和下载kernel文件,加起来大约700MB吧好像,下载挺慢的,我下了一晚上。。但这是居家必备的东西,果断下!

记录几个dts书写的注意事项:

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

2、 version必须是00AX的形式,X从0开始按版本依次增加,而且, 想命名00A1,必须有00A0的存在才行!不能跨越版本!

3、dts文件里面会有part-number和version这两项, 其内容必须跟文件名相符!part-number就是boardname。

实际上,系统启动读取eeprom时,就是要读取里面的boardname和version这两个内容,然后查找有没有对应的dtbo文件。

如何编译dts为dtbo文件请看我之前的日志。编译完的 dtbo文件必须放到 /lib/firmware/ 目录中才可以。(实际上,我用的3.8.13版系统(可输入 uname -r 查看系统版本)似乎还有bug,自己写的dtbo文件,即便放到指定目录中,系统还是没法自动加载。。后面的日志里我再解决这个问题。)

最后说一下,我用的dts文件是在 /lib/firmware/BB-BONE-LCD4-01-00A1.dts 的基础上改的。(其实基本什么都没改,就是把名字和版本号改了一下。里面lcd有关的参数我还不晓得如何改。)

硬件连接


eeprom的电路就不详述了,电路在SRM里可以找到。LCD模块的连接必须跟device tree overlay里描述的相符,所以就按照BB-BONE-LCD4-01-00A1.dts里写的引脚来连接了。需要注意的是,经过查阅TI的AM335x手册,引脚有如下对应关系:

lcd_vsync <-> RS
lcd_hsync <-> WR
lcd_pclk <-> RD
lcd_ac_bias_en <-> CS
gpio3_19 <-> RST
ehrpwm1a <-> BL_CTR


剩下的就是电源、地线和16跟并口线了。注意BL_CDD连的是5V。并口线接到BBB的LCD_DATA_[0-16]引脚上(注意从LCD_DATA_10开始,引脚顺序就变了)。图中T开头的引脚都是与触摸功能有关的,暂时不连。

BB-BONE-LCD4-01-00A1.dts里还有5个功能按键和1个指示灯,我暂时不需要这些,就不管它们了。

原代码如下:
	/* state the resources this cape uses */
	exclusive-use =
		/* the pin header uses */
		"P8.45",	/* lcd: lcd_data0 */
		"P8.46",	/* lcd: lcd_data1 */
		"P8.43",	/* lcd: lcd_data2 */
		"P8.44",	/* lcd: lcd_data3 */
		"P8.41",	/* lcd: lcd_data4 */
		"P8.42",	/* lcd: lcd_data5 */
		"P8.39",	/* lcd: lcd_data6 */
		"P8.40",	/* lcd: lcd_data7 */
		"P8.37",	/* lcd: lcd_data8 */
		"P8.38",	/* lcd: lcd_data9 */
		"P8.36",	/* lcd: lcd_data10 */
		"P8.34",	/* lcd: lcd_data11 */
		"P8.35",	/* lcd: lcd_data12 */
		"P8.33",	/* lcd: lcd_data13 */
		"P8.31",	/* lcd: lcd_data14 */
		"P8.32",	/* lcd: lcd_data15 */
		"P8.27",	/* lcd: lcd_vsync */ //rs
		"P8.29",	/* lcd: lcd_hsync */ //wr
		"P8.28",	/* lcd: lcd_pclk */ //rd
		"P8.30",	/* lcd: lcd_ac_bias_en */ //cs
		"P9.27",	/* lcd: gpio3_19 */ //rst
		"P9.12",	/* led: gpio1_28 */ //led
		"P9.14",	/* pwm: ehrpwm1a */ //bl_ctr
		"P9.15",	/* keys: gpio1_16 */
		"P9.23",	/* keys: gpio1_17 */
		"P9.16",	/* keys: gpio1_19 */
		"P9.21",	/* keys: gpio0_3 */
		//...





==================================================
本篇先写这么多,在后面日志里我会继续写如何向eeprom里写东西,写入格式是什么,如何利用sysfs和procfs查错和控制LCD屏幕等内容。


最后再附上dmesg系统启动时的信息中与cape有关的部分, 从中可以验证很多我刚刚写的东西。我用###号标注在对应行的后面。

[    0.250231] bone-capemgr bone_capemgr.8: Baseboard: 'A335BNLT,0A5C,3513BBBK2728'
[    0.250272] bone-capemgr bone_capemgr.8: compatible-baseboard=ti,beaglebone-black
[    0.281252] bone-capemgr bone_capemgr.8: slot #0: No cape found###可以看到最多可接4个cape。我的eeprom地址是0x57,是4个允许地址的最后一个,所以加载到了3号slot里。
[    0.318358] bone-capemgr bone_capemgr.8: slot #1: No cape found
[    0.355467] bone-capemgr bone_capemgr.8: slot #2: No cape found
[    0.385730] bone-capemgr bone_capemgr.8: slot #3: 'Alfred,00A1,TJU,BB-BONE-LCD4-01'###这就是从eeprom里读取的原始数据
[    0.385899] bone-capemgr bone_capemgr.8: slot #4: specific override
[    0.385940] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 4
[    0.385968] bone-capemgr bone_capemgr.8: slot #4: 'Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G'###默认加载eMMC cape
[    0.386100] bone-capemgr bone_capemgr.8: slot #5: specific override
[    0.386136] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 5
[    0.386164] bone-capemgr bone_capemgr.8: slot #5: 'Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI'###默认加载HDMI cape之一
[    0.386312] bone-capemgr bone_capemgr.8: slot #6: specific override
[    0.386347] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 6
[    0.386375] bone-capemgr bone_capemgr.8: slot #6: 'Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN'###默认加载HDMI cape之二
[    0.386927] bone-capemgr bone_capemgr.8: loader: before slot-3 BB-BONE-LCD4-01:00A1 (prio 0)###从prio优先级可以看出,cape比默认的两个优先级要高。
[    0.386956] bone-capemgr bone_capemgr.8: loader: check slot-3 BB-BONE-LCD4-01:00A1 (prio 0)
[    0.387091] bone-capemgr bone_capemgr.8: loader: before slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.387116] bone-capemgr bone_capemgr.8: loader: check slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.387242] bone-capemgr bone_capemgr.8: loader: before slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.387267] bone-capemgr bone_capemgr.8: loader: check slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.387328] bone-capemgr bone_capemgr.8: initialized OK.###前面检测好了要加载哪些cape,并确定了加载顺序,下面开始加载
[    0.389325] OneNAND driver initializing
[    0.390678] bone-capemgr bone_capemgr.8: loader: after slot-3 BB-BONE-LCD4-01:00A1 (prio 0)
[    0.390714] bone-capemgr bone_capemgr.8: slot #3: Requesting part number/version based 'BB-BONE-LCD4-01-00A1.dtbo###根据eeprom的数据生成了要加载的dtbo的名字,所以文件名才如此重要!
[    0.390745] bone-capemgr bone_capemgr.8: slot #3: Requesting firmware 'BB-BONE-LCD4-01-00A1.dtbo' for board-name 'Alfred', version '00A1'
[    0.390778] bone-capemgr bone_capemgr.8: slot #3: dtbo 'BB-BONE-LCD4-01-00A1.dtbo' loaded; converting to live tree###读取完dtbo文件,把信息写入设备树中
[    0.391665] bone-capemgr bone_capemgr.8: slot #3: #4 overlays
[    0.392824] bone-capemgr bone_capemgr.8: loader: check slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.392876] bone-capemgr bone_capemgr.8: loader: check slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.393619] ehrpwm 48302200.ehrpwm: unable to select pin group
[    0.396508] bone-capemgr bone_capemgr.8: loader: before slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.396539] bone-capemgr bone_capemgr.8: loader: check slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.396569] bone-capemgr bone_capemgr.8: loader: check slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.396905] usbcore: registered new interface driver asix###绑定 BB-BONE-LCD4-01-00A1.dtbo 里涉及到的各种驱动
[    0.397027] usbcore: registered new interface driver cdc_ether
[    0.397149] usbcore: registered new interface driver smsc95xx
[    0.397239] usbcore: registered new interface driver net1080
[    0.397329] usbcore: registered new interface driver cdc_subset
[    0.397433] usbcore: registered new interface driver zaurus
[    0.397597] usbcore: registered new interface driver cdc_ncm
[    0.398492] usbcore: registered new interface driver cdc_acm
[    0.398510] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[    0.398524] Initializing USB Mass Storage driver...
…… ###绑定了好多驱动,略掉……
[    0.404045] bone-capemgr bone_capemgr.8: slot #3: Applied #4 overlays.###3号slot处理完了,开始处理4号slot
[    0.404071] bone-capemgr bone_capemgr.8: loader: done slot-3 BB-BONE-LCD4-01:00A1 (prio 0)
[    0.404158] bone-capemgr bone_capemgr.8: loader: check slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.404203] bone-capemgr bone_capemgr.8: loader: check slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.404231] bone-capemgr bone_capemgr.8: loader: after slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.404326] bone-capemgr bone_capemgr.8: slot #5: Requesting firmware 'cape-boneblack-hdmi-00A0.dtbo' for board-name 'Bone-Black-HDMI', version '00A0'
[    0.404369] bone-capemgr bone_capemgr.8: slot #5: dtbo 'cape-boneblack-hdmi-00A0.dtbo' loaded; converting to live tree
[    0.405239] bone-capemgr bone_capemgr.8: slot #5: BB-BONELT-HDMI conflict P8.45 (#3:BB-BONE-LCD4-01)###与3号发生资源冲突,所以加载失败!
[    0.414850] bone-capemgr bone_capemgr.8: slot #5: Failed verification
[    0.421627] bone-capemgr bone_capemgr.8: loader: failed to load slot-5 BB-BONELT-HDMI:00A0 (prio 1)
[    0.431144] bone-capemgr bone_capemgr.8: loader: check slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.431174] bone-capemgr bone_capemgr.8: loader: after slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.431209] bone-capemgr bone_capemgr.8: slot #4: Requesting firmware 'cape-bone-2g-emmc1.dtbo' for board-name 'Bone-LT-eMMC-2G', version '00A0'
[    0.431235] bone-capemgr bone_capemgr.8: slot #4: dtbo 'cape-bone-2g-emmc1.dtbo' loaded; converting to live tree
[    0.432641] bone-capemgr bone_capemgr.8: slot #4: #2 overlays
[    0.433438] bone-capemgr bone_capemgr.8: slot #4: Applied #2 overlays.
[    0.433466] bone-capemgr bone_capemgr.8: loader: done slot-4 BB-BONE-EMMC-2G:00A0 (prio 1)
[    0.433670] bone-capemgr bone_capemgr.8: loader: check slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.433704] bone-capemgr bone_capemgr.8: loader: after slot-6 BB-BONELT-HDMIN:00A0 (prio 2)
[    0.433744] bone-capemgr bone_capemgr.8: slot #6: Requesting firmware 'cape-boneblack-hdmin-00A0.dtbo' for board-name 'Bone-Black-HDMIN', version '00A0'
[    0.433780] bone-capemgr bone_capemgr.8: slot #6: dtbo 'cape-boneblack-hdmin-00A0.dtbo' loaded; converting to live tree
[    0.434078] bone-capemgr bone_capemgr.8: slot #6: BB-BONELT-HDMIN conflict P8.45 (#3:BB-BONE-LCD4-01)###同样与3号冲突,加载失败
[    0.443794] bone-capemgr bone_capemgr.8: slot #6: Failed verification
[    0.450574] bone-capemgr bone_capemgr.8: loader: failed to load slot-6 BB-BONELT-HDMIN:00A0 (prio 2)






  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值