请教各位dts和uboot,linuxuboot kernell 版本对应问题

1928人阅读
技术(40)
以下凡是涉及代码分析的地方,可能不同平台的处理方式有所区别,具体情况是以自己手头上的平台代码为准。
曾经在空间里面转载过一篇《》的文章,当时看了几遍,仍然不知所云。后来在工作中才慢慢地对dts有所领悟。所以,在这里想用简单的词语,描述一下自己对dts的理解。
首先,dts是什么?很简单,一句话:为了瘦简内核、去掉部分冗余的代码,而用一种简单的方式(语言)把硬件设备相关信息描述出来,这就是dts。
既然命名为“device tree”(本文用dts来简称),顾名思义,它是以一种树的形态存在:树干,分支,叶子。而且这种“树”的结构形式是dts特有的。下面会对大家进行分析。
在dts里面,结点(node)和属性(property)的概念十分重要,这也是组成dts模型最重要的东西。结点,不用多说大家都明白。而属性,说的就是设备相关的name,value等信息。
在讲dts之前,先来讲讲uboot是怎样去加载dtb的。
dtb是dts编译出来的二进制文件,以“.dtb”结尾,dtb在启动阶段,会由加载到某一内存地址。当启动内核,驱动里面调用dts相关的api的时候,会到这个地址里面去寻找匹配的字符串,如果符合,则读取相关的配置信息。
这样说起来,好像跟全志代码里面配置文件的处理方式有点相似。这里没有打广告的意思,只是接触过全志代码,做个比较罢了。
好,接下来我们看到uboot代码里面:
首先是boards.cfg 里面定义 DEFAULT_FDT_FILE 的名称,这个名词必须和内核编译出来的dtb的名称一样。这样才能保证dtb被load到内存里面。
DEFAULT_FDT_FILE=&xxx.dtb&,DDR_MB=1024,SYS_USE_SPINOR
接下来,根据DEFAULT_FDT_FILE 来定义 fdt_file 的变量。
include/configs/xxxcommon.h
&fdt_file=& CONFIG_DEFAULT_FDT_FILE &\0& \
和相关环节变量的定义:
&loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0& \
&mmcboot=echo Booting from mmc ...; & \
&if test ${boot_fdt} = yes || test ${boot_fdt} = then & \
& then & \
在board.c 里面设置环境变量,在这过程中,会调用上一步骤的run loadfdt 动作,把dtb 装载到内存中。
arch/arm/lib/board.c
sprintf(buf, &fatload sata 0:1 ${fdt_addr} ${fdt_file}&);
sprintf(buf, & bootm ${loadaddr} - ${fdt_addr}&);
setenv(&bootcmd&, buf);
在这里,uboot里面的代码不详细分析,有兴趣的童鞋可以去看看。
接下来是dts结点(node)和属性(property)的分析,以一个i2c的例子为参考。
dts源码在scripts/dtc目录下
参考文档在Documentation/devicetree目录下
如在i2c上挂的一个设备:
#address-cells = &1&;
#size-cells = &0&;
#address-cells = &1&;
#size-cells = &0&;
compatible = “fsl , ec”;
reg=&0x30&;
由上到下:
&&&&&&&& reg = &address1 length1 [address2 length2][address3 length3]
&&&&&& address为1个或多个32位的整型(即cell),而length则为cell的列表或者为空(若#size-cells = 0)
reg=&1& :
&&&&&&&& 这个reg是被上面的#address-cells 和#size-cells决定的
#address-cells =&1& :
&&&&&& 决定了,以下包含的节点@后面只能接一个参数,即地址
#size-cells =&0& :
&&&&&& 决定了,以下包含的节点里面reg= & , length& , length为空(不填)
&&&&&& 以下包含的节点里面reg=&,, length&, length 前面的参数即为@后面的参数
&&&&&& 如果@后面只有一个参数,则为地址
&&&&&& 如果@后面有两个参数,则为“片选+相对该片选的基地址”
& & & &如果为address-cells 为1 ,则@直接跟地址,length一般为空,即size-cells为0
& & & &当address-cells为 ,则length一般不为空,即size-cells不为0
&&&&&&&& 名字@器件地址
Compatible :
&&&&&&&& 厂家名字,模块名字
&&&&&&&& 跟i2c_device_id里面描述的名字要一致
reg=&0x30& :
&&&&&&&& 器件地址,对应 ”@30”
以上是对一个i2c节点的说明,也就是i2c节点在dts里面的结构,上面的内容说到了,dts是有自己独特的结构的,具体不同的设备节点有所差异。我们在dts里面添加这些节点的时候,需要安照dts里面的规则来添加。
如果分析过程有什么错漏,大家可以提出。互相交流。这里不再多说,下面来看一个具体的应用实例。
此例子是linux里面一个控制背光的实例。首先,我们先看到dts里面描述的设备信息:
backlight {
pinctrl-names = &default&;
pinctrl-0 = &&pinctrl_lvds_bkl_1 &pinctrl_lvds_vcc_1&;
compatible = &pwm-backlight&;
lvds-bkl-enable = &&gpio4 6 0&;
lvds-vcc-enable = &&gpio4 7 0&;
pwms = &&pwm1 0 5000000&;
brightness-levels = &0 4 8 16 32 64 128 255&;
default-brightness-level = &7&;
pinctrl-0 :从上面lvds里面获取io脚
compatible :驱动里面会找这个名字进行匹配
lvds-bkl-enable :第四组GPIO的第六个管教,默认值为0
lvds-vcc-enable :对于gpio的描述,在include的dts里面有描述
pwms :是取寄存器的值
brightness-levels :backlight 的level
default-brightness-level :level分为7个等级
接下来,我们看看代码里面是怎样对dts节点信息进行匹配的:
driver里面会对要match的dts的分支的名字写在device_idtable里面。当遍历dtb这棵树的时候,能找到与下面“compatible”名字相同的节点的名字,就匹配成功。
static struct of_device_id pwm_backlight_of_match[] = {
{ .compatible = &pwm-backlight& },
在backlight的驱动里面,当执行到probe函数的时候,会对dts里面几个管脚进行匹对,取值。其中,要注意以下几个函数的用法:
of_get_named_gpio
of_find_property
of_property_read_u32_array
of_property_read_u32
其实这几个函数的作用,做的事情都是这样一个过程:在匹配成功的节点里面寻找到函数参数里面匹配的字符串,然后读取后面的数值。至于这几个函数的源码,可以到“scripts/dtc”里面查看。
lvds_vcc_enable = of_get_named_gpio(node, &lvds-vcc-enable&, 0);
if (lvds_vcc_enable & 0)
ret = gpio_request(lvds_vcc_enable,&lvds_vcc_enable&);
if (ret & 0) {
printk(&request lvds_vcc_enable failed: %d\n&, ret);
gpio_direction_output(lvds_vcc_enable, 1);
lvds_bkl_enable = of_get_named_gpio(node, &lvds-bkl-enable&, 0);
if (lvds_bkl_enable & 0)
ret = gpio_request(lvds_bkl_enable,&lvds_bkl_enable&);
if (ret & 0) {
printk(&request lvds_bkl_enable failed: %d\n&, ret);
gpio_direction_output(lvds_bkl_enable, 1);
/* determine the number of brightness levels */
prop = of_find_property(node, &brightness-levels&, &length);
if (!prop)
return -EINVAL;
data-&max_brightness = length / sizeof(u32);
/* read brightness levels from DT property */
if (data-&max_brightness & 0) {
size_t size = sizeof(*data-&levels) * data-&max_
data-&levels = devm_kzalloc(dev, size, GFP_KERNEL);
if (!data-&levels)
return -ENOMEM;
ret = of_property_read_u32_array(node, &brightness-levels&,
data-&levels,
data-&max_brightness);
if (ret & 0)
ret = of_property_read_u32(node, &default-brightness-level&,
上面一段代码就是读取dts数据,初始化管教,或数组的过程。
当然,dts还有include,定义变量,引用等一些用法。具体可以参考“arch/arm/boot/dts/”下的文件进行配置。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:26848次
排名:千里之外
原创:26篇
转载:15篇
(4)(4)(2)(3)(10)(12)(1)(1)(1)(6)请教一个uboot下显示logo的问题,会的大牛们给指点迷津一下,感谢!!
[问题点数:40分,结帖人zhuyi108]
请教一个uboot下显示logo的问题,会的大牛们给指点迷津一下,感谢!!
[问题点数:40分,结帖人zhuyi108]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2012年8月 硬件/嵌入开发大版内专家分月排行榜第三2012年6月 硬件/嵌入开发大版内专家分月排行榜第三2012年5月 硬件/嵌入开发大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。需要确认注册邮箱后才能开通博客,
>>>[博客大赛]U-Boot for AM335x (13) steps of building Linux Kernel
2年会员勋章目前已领取。领取条件:&凡是注册时间两年以上的活跃用户即可领取该勋章。
3年会员勋章目前未领取。领取条件:&凡是注册时间三年以上的活跃用户即可领取该勋章。
不是猫咪不是机器人的博客&&Linux/Hardware Blog
博主:&&&&
Robot Engineer
文章(207)&&&&
访问(204262)&&&&
评论(253)&&&&
投票(183)&&&&
订阅本博&&
博文列表查看方式:
需要确认注册邮箱后才能下载,
U-Boot for AM335x (13) steps of building Linux Kernel
这一节我记录了porting Linux Kernel的具体步骤,和以往相差比较大的是driver的DT策略,内核不再将描述driver的代码放置在uImage中了,而是放在*.dtb文件里面,由u-boot.img传递给内核。
具体的步骤见下(绝对路径、名字神马的,替换成自己的就行):
====& STEP 1: 安装交叉工具链,它和编译U-Boot的是同一个,Forlinx光盘里面有提供:
arm-arago-linux-gnueabi
也可以在TI的官方网站下载,还可以使用GCC的mainline编译(使用GCC源码编译自己的工具链,也是非常interesting的事情,ps:开源软件说的interesting,就是非常有挑战性的意思,就是可能会让你想咔咔咔砸掉电脑的意思。。。)
http://software-/sitara_linux/esd/AM335xSDK/latest/index_FDS.html
这是TI的官方开发软件的地址,下载这个东东,它里面神马都有:
ti-sdk-am335x-evm-07.00.00.00-Linux-x86-Install.bin
(另外,这里也提供了单独下载的链接,比如制作SD卡的工具啦,am335x的源玛啦,交叉编译器啦。。。)
因为TI官网的版本比Forllinx提供的要高一点,所以我使用了TI提供的,顺便把U-Boot也重新编译了一次。重新运行MLO和u-boot.img,没有遇到问题,意外的非常顺利!另外,使用旧版本的编译最新版本的内核,我出现了下面的错误:
/tmp/cc3G2Hh3.s: Assembler messages:
/tmp/cc3G2Hh3.s:2006: Error: garbage following instruction -- `dmb ishst'
/tmp/cc3G2Hh3.s:2023: Error: garbage following instruction -- `dmb ishst'
/tmp/cc3G2Hh3.s:2055: Error: garbage following instruction -- `dmb ish'
/tmp/cc3G2Hh3.s:2067: Error: garbage following instruction -- `dsb ishst'
总之,以后的步骤还是会使用TI官网提供的4.7.3版本。
====& STEP 2: 从Linux Kernel的官方网站下载最新版本的stable内核,下载完成之后解压,并进入目录,清理它:
tar xvf linux-3.16.1.tar.xz
cd linux-3.16.1
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc-ti/i686-arago-linux/usr/bin/arm-linux-gnueabihf- -j8 mrproper
要是交叉工具链的bin目录加入了PATH环境变量,那么CROSS_COMPILE就可以不用写完整的绝对路径。
-j8的意思是,指定同时执行的任务有8个,一般来说,电脑的CPU有几核,就指定它的两倍既可,使用lscpu命令可以查看。
====& STEP 3: 构造自己的config文件:
这是很关键的一步。
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc-ti/i686-arago-linux/usr/bin/arm-linux-gnueabihf- -j8 omap2plus_defconfig
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc-ti/i686-arago-linux/usr/bin/arm-linux-gnueabihf- menuconfig
先调入默认的config文件omap2plus_defconfig,这样很多配置就可以使用它的,而不用一个个研究了。然后使用menuconfig的方法生成.config,要修改的主要有这么几个地方:
*************************
选项1:General setup& ---&
Default hostname
填入自己希望的hostname,我填写的是Maria,这个随意,也可以不填。
*************************
选项2:General setup& ---&
Stack Protector buffer overflow detection (None)& ---&
选择none,而不是默认的strong,否则编译无法通过,错误信息如下:
cc1: error: unrecognized command line option &-fstack-protector-strong&
(这条是因为不调入omap2plus_defconfig时,默认x86体系,而arm交叉编译器maybe不支持这个选项,调入了omap2plus_defconfig时默认是none。)
*************************
选项3:Boot options& ---&
Default kernel command string
将root=/dev/mmcblk0p2 rootwait console=ttyO2,115200
修改为:root=/dev/mmcblk0p2 rootwait console=ttyO0,115200
====& STEP 4: 编译*.dtb文件
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc-ti/i686-arago-linux/usr/bin/arm-linux-gnueabihf- -j8 am335x-evm.dtb
这一步将在arch/arm/boot/dts/目录下生成am335x-evm.dtb文件。
====& STEP 5: 编译uImage
make ARCH=arm CROSS_COMPILE=/opt/arm-arago-linux-gcc-ti/i686-arago-linux/usr/bin/arm-linux-gnueabihf- -j8 LOADADDR=0x uImage
这一步将在这一步将在arch/arm/boot/下生成uImage文件,花的时间可能会比较长,大概十几分钟。
====& STEP 6: 运行
将MLO、u-boot.img、uImage、am335x-evm.dtb拷贝到SD的boot分区(假设SD卡已经使用TI公司提供的分区工具create-sdcard.sh分成了boot区和rootfs区),使用kermit连上开发板的com0,设置串口参数,等待串口出现U-Boot提示符:
U-Boot# fatls mmc 0
U-Boot# fatload mmc 0 0x uImage
U-Boot# fatload mmc 0 0x am335-evm.dtb
U-Boot# bootm 0x - 0x
此时,就可以看到欢快的内核打印信息了~~~
哦耶~~~
## Booting kernel from Legacy Image at
&& Image Name:&& Linux-3.16.1
&& Image Type:&& ARM Linux Kernel Image (uncompressed)
&& Data Size:&&& 4172416 Bytes = 4 MiB
&& Load Address:
&& Entry Point:&
&& Verifying Checksum ... OK
## Flattened Device Tree blob at
&& Booting using the fdt blob at 0x
&& Loading Kernel Image ... OK
&& Using Device Tree in place at , end
Starting kernel ...
[&&& 0.000000] Booting Linux on physical CPU 0x0
[&&& 0.000000] Linux version 3.16.1 (maria@localhost.localdomain) (gcc version 4.7.3
(prerelease) (crosstool-NG linaro-1.13.1-4.7-30313 - Linaro GCC 2013.03) ) #15 SMP Tue Sep 2 14:33:33 CST 2014
出现了内核打印信息,说明Linux Kernel就开始跑起来了,当然剩下的工作仍然很多,比如制作文件系统、解决各种各样打印问题、解决各种各样的驱动问题&&但有了打印信息,就不会是无头无脑找问题的阶段了(当然,JTAG也是个好工具),接下来的任务,就是修改mainline中关于am335x-evm.dtb的内容,直到Forlinx开发板的硬件运行正确,再制作成自己的forlinx.dtb。
万里长征,go on walking......
(补充:Forlinx的OK335D开发板,使用arch/arm/boot/dtc/am335x-bone.dts,而不是am335x-evm.dts,能够顺利出现串口的命令提示符,就是说Kernel和file system都加载正确了!到目前为止,mainline的porting工作告一段落,之后的内容属于针对项目的研发,因此这个U-Boot for AM335x系列也结束了,wish me luck!^_^)
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
1.扫描左侧二维码
2.点击右上角的分享按钮
3.选择分享给朋友
&&&&&&有[ 2 ]名读者喜欢此文
阅读(2520)&&
评论是对思考最好的总结…
你还可以输入1000字
确实是,我换了一个新的编译器这个错误就没有了
好呀好呀,期待ing~
--- 现有 7 个主题,共 1 页 ---
转发到我的博客
评论&&的“[博客大赛]U-Boot for AM335x (13) steps of building Linux Kernel”
U-BootforAM335x(13)stepsofbuildingLinuxKernel这一节我记录了portingLinuxKernel的具体步骤,和以往相差比较大的是driver的DT策略,内核不再将描述driver的代码放置在uImage中了,而是放在*.dtb文件里面,由u-boot.im...
你还可以输入30000字
同时评论给&不是猫咪不是机器人
Robot Engineer
不是猫咪不是机器人&&13:32 06-06
liumingd&&09:48 06-06
jwdxu2009&&18:32 06-05
zcz2004&&16:00 06-03
jthykj&&09:46 06-03
成员3221名创建者:
-- Use of this website is subject to its terms of use.
京ICP备号-4 |
京公网安备37 |
新版社区已上线,旧版论坛、博客将停用
1、为防数据丢失,旧版论坛、博客不再接受发帖;
2、老用户只需重设密码,即可直接登录新平台;
3、新版博客将于8月底完美归来,敬请期待;
4、全新论坛、问答,体验升级、手机阅读更方便。写在前面:关于AT043TN24的背光
背光电路一般是独立的,无论从哪个地方给背光LED供电都可以,不需要AM335x的LCD控制器参与。
AT043TN24需要使用+28V作为液晶背光,因此需要boost芯片,我使用的是LM2733,它体积较小电路简单:
控制背光的GPIO为113,因此需要定义pin_mux:
(Note: 这是LM2733的使能引脚,背光的亮度调节需要PWM,放在第30小节中。)
static struct module_pin_mux blk_pin_mux[] = {
&&&&&&& {OFFSET(mcasp0_ahclkr), MODE(7)},
&&&&&&& {-1},
然后执行:
int board_init(void)
&&&&&&& /* other actions */
&&&&&&& configure_module_pin_mux(blk_pin_mux);
&&&&&&& gpio_request(113, &lcd_light&);
&&&&&&& gpio_direction_output(113, 0);
&&&&&&& for (i = 0;; i++) {
&&&&&&&&&&&&&&& gpio_set_value(113, 1);
&&&&&&&&&&&&&&& mdelay(500);
&&&&&&&&&&&&&&& gpio_set_value(113, 0);
&&&&&&&&&&&&&&& mdelay(500);
编译之后重新运行u-boot,就可以看到液晶的背光在闪啦~
当然,在实际的使用中,还得注意上电顺序:
&* 首先是LCD的POWER;
&* 然后是signal interface;
&* 其次是display on/off;
&* 最后才是背光。
======================================================
======================================================
使用AT043TN24的准备工作:
驱动AT043TN24需要做两个准备工作,一是阅读AM335x关于LCD控制器的部分,二是阅读AT042TN24用户手册中指令的部分。
准备工作一:&AM335x ARM & CortexTM-A8 Microprocessors (MPUs) Technical Reference Manual&
-- LCD Controller
13.1 Introduction
13.1.1 Purpose of the Peripheral
The LCD controller consists of two independent controllsers, the Raster and the LCD Interface Display Driver (LIDD) controller. Each controller operates independently from the other and only one of them is active at any given time.
&* The Raster Controller handles the synchronous LCD interface.
&* The LIDD Controller supports the asynchronous LCD interface.
(Raster controller和LCD Interface Display Driver,前者是同步的,后者是异步的。像我这次用的AT043TN24使用的是前者Raster Controller,它的特点是数据在CLK的边沿锁存进去。)
13.1.2 Features
Supports up to 24- 8 bit-per-pixel (RGB).
Supports up to WXGA () resolution.
13.2 Integration
13.2.1 LCD Controller Connectivily Attributes
13.2.2 LCD Controller Clock and Reset Management
13.3.3 LCD Controller Pin List
&* lcd_cp (O): Pixel Clock in Raster model Read Strobe or Read/Write Strobe in LIDD mode.
&* lcd_pixel_i[15:0] (I): LCD Data Bus input (for LIDD mode only)
&* lcd_pixel_o[23:0] (O): LCD Data Bus output
&* lcd_lp (O): Line Clock or HSYNC in R Write Strobe or Direction bit in LIDD mode.
&* lcd_fp (O): Frame Clock or VSYNC in R Address Latch Enable in LIDD mode.
&* lcd_ac (O): AC bias or Latch Enable in R Primary chip Select/Primary Enable in LIDD MPU Hitachi mode.
&* lcd_mclk (O): N/A in R Memory Clock/Secondary chip select/Secondary Enable in LIDD Synchronous/Async MPU/Hitachi mode.
(AT043TN24除了使用那24个RGB口之外,不包括背光控制IO还需要三条线,CLK,DISP,DE,分别是时钟、使能显示和数据使能,具体应该怎么和AM335x相连,还得继续往下看。)
13.3 Functional Description
13.3.1 Clocking
13.3.1.1 Pixel Clock (LCD_PCLK)
13.3.1.2 Horizontal Clock (LCD_HSYNC)
13.3.1.3 Vertical Clock (LCD_VSYNC)
13.3.1.4 !LCD_AC_BIAS_EN
&* Passive (STN) mode. To prevent a dc charge within the screen pixels, the power and ground supplies of the display are periodically switched. The Raster Controller signal the LCD to switch the polarity by toggling this pin (!LCD_AC_BIAS_EN).
&* Active (TFT). This signal acts as an output enable (OE) signal. It is used to signal the external LCD that the data is valid on the data bus (LCD_DATA).
(!LCD_AC_BIAS_EN用来指示数据有效:当它为高电平的时候,意为LCD_DATA上面的数据是可用的;而AT043TN24的DE用来指示数据使能:当它为高电平的时候,LCD_DATA上面的数据被认为是valid,否则就是invalid。可见,AM335x的!LCD_AC_BIAS_EN是要和AT043TN24的DE相连的。)
13.3.2 LCD External I/O Signals
&* LCD_VSYNC:& OUT
& Raster controller: Frame clock the LCD uses to signal the start of a new frame of pixels. Also used by TFT displays as the vertical synchronous signal.
&* LCD_HSYNC:& OUT
& Raster controller: Line clock the LCD uses to signal the end of a line of pixels that transfers line data from the shift register to the screen and to increment the line pointer(s). Also used by TFT displays as the horizontal synchronization signal.
&* LCD_PCLK:& OUT
& Raster controller: Pixel clock the LCD uses to clock the pixel data into the line shift register. In passive mode, the pixel clock transitions only when valid data is available on the data lines. In active mode, the pixel clock transitions continuously, and the ac-bias pin is used as an output enable to signal when data is available on the LCD pin.
(AT043TN24的时钟线只有一根CLK,它用来锁存每个pixel值,所以它应该连接这里的LCD_PCLK。LCD_PCLK在passive模式下,当数据有效时它才有时钟输出;而在active模式下,是一直会输出时钟信号,由!LCD_AC_BIAS_EN告诉液晶哪些时刻的数据是有效的。)
&* !LCD_AC_BIAS_EN:& OUT
& Raster controller: ac-bias used to signal the LCD to switch the polarity of the power supplies to the row and column axis of the screen to counteract DC offset. Used in TFT mode as the output enable to signal when data is latched from the data pins using the pixel clock.
&* LCD_MCLK: OUT
& Raster controller: not used.
&* LCD_D[23:0]:& Raster OUT
& LCD data bus, providing a 4-, 8-, 16- or 24- data path.
& Raster controller: For monochrome displays, each signa for passive color displays, grouping of three signals represent one pixel (red, green, and blue.)
& LCD_DATA[3:0] is used for monochrome displays of 2, 4, and 8 BPP; LCD_DATA[7:0] is used for color STN displays and LCD_DATA[15:0] or LCD_DATA[23:0] is used for active (TFT) mode.
(AT043TN24可以使用LCD_DATA[15:0]做R5/G6/B5驱动,这样可以节省8根数据线;这里采用了R8/G8/B8驱动,LCD_DATA[23:0]都分配给液晶了。)
(AT043TN24还有一个DISP引脚,使能显示,给它分配一个普通的IO口即可。)
13.3.3 DMA Engine
It operates on one or two frame buffers, which are set up during initialization. Using two frame buffers (ping-pong buffers) enables the simultaneous operation of outputting the current video frame to the external display and updating the next video frame. The ping-pong buffering approach is preferred in most applications.
(推荐使用双缓冲。)
13.3.3.1 Interrupts
13.3.3.1.1 LIDD Mode
13.3.3.1.2 Raster Mode
&* Output FIFO under-run
&* Frame synchronization lost
&* Palette loaded
&* AC bias transition
&* Frame transfer completed
13.3.3.1.3 Interrupt Handling
13.3.4 LIDD Controller
13.3.5 Raster Controller
13.3.5.1 Logical Data Path
&-& Data source (frame buffers)
&-& Input FIFO
&-& TFT (active)
&-& 24 BPP
&-& Output pins
13.3.5.2 Frame Buffer
13.3.5.3 Palette
13.3.5.4 Gray-Scaler/Serializer
13.3.5.4.1 Passive (STN) Mode
13.3.5.4.2 Active (TFT) Mode
&* The gray-scaler/serializer is bypassed.
13.3.5.4.3 Summary of Color Depth
13.3.5.5 Output Format
13.3.5.1 Passive (STN) Mode
13.3.5.2 Active (TFT) Mode
13.3.5.6 Subpicture Feature
13.3.6 Interrupt Conditions
13.3.6.1 Highlander 0.8 Interrupts
13.3.6.1.1 Highlander Interrupt Basics
13.3.6.1.2 Raw Status Register
13.3.6.1.3 Masked Status Register
13.3.6.1.4 Interrupt Enable Set Register
13.3.6.1.5 Interrupt Enable Clear Register
13.3.6.1.6 End of Interrupt Register
13.3.6.2 Interrupt Sources
13.3.6.2.1 Overview of Interrupt Sources
13.3.6.2.1.1 DMA End of Frame 0 and End of Frame 1 Interrupt
13.3.6.2.1.2 Palette Loaded Interrupt
13.3.6.2.1.3 FIFO Underflow Interrupt
13.3.6.2.1.4 AC Bias Count Interrupt
13.3.6.2.1.5 Sync Lost Interrupt
13.3.6.2.1.6 Recurrent Frame Done Interrupt
13.3.6.2.1.7 LIDD or Raster Frame Done Interrupt
13.3.7 DMA
13.3.8 Power Management
13.4 Programming Model
13.4.1 LCD Character Displays
13.4.1.1 Configuration Registers, Setup, and Settings
13.4.1.1.1 Configuration Registers
13.4.1.1.2 Defining Panel
13.4.1.2 CPU Initiated Data Bus Transactions
13.4.1.2.1 Initiating Data Bus Transactions
13.4.1.3 DMA Initiated Data Bus Transactions for LIDD
13.4.1.3.1 DMA Overview for MPU Bus Output
13.4.1.3.2 MCU/LIDD DMA Setup: Example Pseudo Code
13.4.1.4 Passive Matrix
13.4.1.4.1 Monochrome Bitrate Awareness
13.4.2 Active Matrix Displays
13.4.2.1 Interfacing to Dual LVDS Transmitters
13.4.3 System Interaction
13.4.3.1 DMA End of Frame Interrupts
13.4.4 Patelle Lookup
13.4.5 Test Logic
13.4.6 Disable and Software Reset Sequence
In Raster Modes, the module must be disabled before applying a software reset. When cfg_lcden is set to '0' to disable the module, the output continues to the end of the current frame.
13.4.7 Precedence Order for Determining Frame Buffer Type
13.5 LCD Registers
======================================================
准备工作二:AT043TN24的用户手册
它的分辨率是480x272;
工作在+3.3V下,背光电压+28V;
信号需要24根RGB线,以及CLK、DISP、DE三根指令线;
======================================================
======================================================
准备工作完成之后,就可以着手开始修改U-Boot了:
(PS:直接用U-Boot的IO口控制方法来驱动AT043TN24不可取,因为AT043TN24要求的CLK在9MHz左右;而使用__raw_writel直接操作GPIO_SETDATAOUT和GPIO_CLEARDATAOUT寄存器,最快也只能达到1us。所以,还是得使用AM335x的LCD外设功能!)
(PS:board/siemens/pxm2,这块西门子的电路板也是使用AM335x为CPU,使用了LCD外设,因此可以以它为参考,编写自己的board.c文件。)
================
Step 1: 然后来了解几个重要的结构体的概念(随着学习的过程来添加):
&* 在include/video_fb.h里面,定义了struce GraphicDevice:
typedef struct {
&&& unsigned int isaB
&&& unsigned int pciB
&&& unsigned int dprB
&&& unsigned int vprB
&&& unsigned int cprB
&&& unsigned int frameA
&&& unsigned int memS
&&& unsigned int gdfI
&&& unsigned int gdfBytesPP;
&&& unsigned int plnSizeX;
&&& unsigned int plnSizeY;
&&& unsigned int winSizeX;
&&& unsigned int winSizeY;
&&& char modeIdent[80];
} GraphicD
plnSizeX是显示屏的横向分辨率,plnSizeY是显示屏的竖向分辨率。
GraphicDevice描述了一个显示设备。
&* 在include/linux/fb.h里面定义了struct fb_info:
struct fb_info {
&&&&&&& struct fb_var_&& /* Current var */
&&&&&&& struct fb_fix_&& /* Current fix */
&&&&&&& struct fb_&&& /* Current Monitor specs */
&&&&&&& struct fb_&&&&&&& /* Image hardware mapper */
&&&&&&& struct fb_&&&&&&& /* Cursor hardware mapper */
&&&&&&& struct fb_&&&&&&&&&&& /* Current cmap */
&&&&&&& struct list_&&&&& /* mode list */
&&&&&&& struct fb_videomode *&&&&& /* current mode */
&&&&&&& char *screen_&&&&& /* Virtual address */
&&&&&&& unsigned long screen_&&&&& /* Amount of ioremapped VRAM or 0 */
&&&&&&& void *pseudo_&&&&&&&&&& /* Fake palette of 16 colors */
#define FBINFO_STATE_RUNNING&&& 0
#define FBINFO_STATE_SUSPENDED& 1
&&&&&&& u32&&&&&&&&&&&&&&&&&&&&& /* Hardware state i.e suspend */
&&&&&&& void *fbcon_&&&&&&&&&&&&&&& /* fbcon use-only private area */
&&&&&&& /* From here on everything is device dependent */
&&&&&&& void *
fb的意思是frame buffer,它描述了桢缓冲区的概念。
&* 在include/lcd.h中定义了vidinfo_t:(不同的架构其具体定义也是不同的,AM335x并没有在它的ifdef中被列举,所以会使用这个默认的定义)
typedef struct vidinfo {
&&&&&&& ushort& vl_&&&&&&&& /* Number of columns (i.e. 160) */
&&&&&&& ushort& vl_&&&&&&&& /* Number of rows (i.e. 100) */
&&&&&&& u_char& vl_&&&&&&& /* Bits per pixel, 0 = 1 */
&&&&&&& ushort& *&&&&&&&&& /* Pointer to the colormap */
&&&&&&& void&&& *&&&&&&&&& /* Pointer to driver-specific data */
} vidinfo_t;
为LCD定义的结构体挺多的,用到什么就grep它的定义。
上面这几个也不一定很重要=_=~
================
Step 2: 为config文件增加lcd相关的宏定义。
#define CONFIG_VIDEO
#define CONFIG_VIDEO_DA8XX
#define CONFIG_CFB_CONSOLE
#define CONFIG_CMD_BMP
#define DA8XX_LCD_CNTL_BASE&&&& 0x
#define CONFIG_SYS_CONSOLE_IS_IN_ENV
#define VIDEO_TSTC_FCT&&&&&&&&& serial_tstc
#define VIDEO_GETC_FCT&&&&&&&&& serial_getc
#define VIDEO_KBD_INIT_FCT&&&&& 0
#define CONFIG_VIDEO_LOGO
&* 使用CONFIG_SYS_CONSOLE_IS_IN_ENV宏,来告诉U-Boot使用env中定义的console;如果不增加它,U-Boot就会搜索LCD作为console输出,而此时我的LCD还未被初始化;使用printenv打印环境变量:&console=ttyO0,&。
&* 使用CONFIG_CMD_BMP宏,来添加在屏幕上显示bmp图片的功能,从SD卡、USB存储、TFTP服务器等等都可以加载图片放置在内存的相应位置,再使用bmp命令来显示。
&* 使用CONFIG_CFB_CONSOLE宏,意为添加将显示器console的驱动;drv_keyboard_init函数就会被stdio_init函数调用;drv_keyboard_init函数用来设置AM335x的LCD外设,以及执行其他和LCD相关的初始化工作。显示器作为console时,还需要定义输入设备,因此添加VIDEO_TSTC_FCT、VIDEO_GETC_FCT以及VIDEO_KBD_INIT_FCT。
================
Step 3: 理解U-Boot关于驱动文件da8xx-fb.c和da8xx-fb.h。
http://processors./index.php/DA8xx_LCDC_Linux_FB_FAQs?keyMatch=DA8xx&tisearch=Search-EN
DA8xx LCDC Linux FB FAQs
1. About this page
This page describes the flicker/tearing issue faced on AM335x when graphics(SGX)/Android comes up. Also describes root cause and its solution.
2. Introduction
AM335x LCD controller is based LCDC IP of DA8xx which has 2 DMA channels(channel 0 and channel 1), controller ping pongs between them in dual frame buffer mode on every other frame done interrupt. Linux frame buffer driver uses 2 DDR frame buffers as ping pong buffers. And it is expected to feed the filled buffer on every frame done callback.
3. DMA channel 0/1 ping ponging
4. Recommended Ping Pong usage
5. Host CPU Keep Out Regions
6. Issue with Linux FB use case
7. Solution or work around for issue
8. Limitation with above solution
9. Other solution
10. Backup section
11. Flicker due to underflow error
好吧,上面的帖子主要是讲ping pong是怎么工作的,那再来看看下面这个:
http://processors./index.php/AM335x_LCD_Controller_Driver%27s_Guide
AM335x LCD Controller Driver's Guide
1. Introduction
LCD controller(LCDC) on AM335x is an updated version of LCDC that is found on OMAP-L138 SoC. It has following updates in comparision with OMAP-L138
&* Interrupt configuration and status registers are different.
&* Increased resolution of .
&* 24 bits per pixel active TFT raster configuration.
So da8xx-fb LCD driver can be used by having enhancements under LCD_VERSION2 code. This update in LCDC version can be detected by reading PID register.
(由于要通过lcd_ctrl_init为外设LCD进行初始化之后,video_hw_init函数才能进行LCD_VERSION的读取,所以这里先认为它就是LCD_VERSION2。)
2. LCDC on AM335x Soc
&* LCDC has 2 interface clocks, L3 peripheral and L4LS peripherial.
&* LCDC functional clock can be mux selected among DISPLAY PLL CLKOUTM2, CORE PLLCLOCKM5 OR PER PLLCLKOUTM2. Supports MAX pixel clock of ~126MHz, configure DISPLAY PLL for 600MHz.
&* LCD_DATA[0-15] pins are in mode0 and LCD_DATA[16-23] are in mode1.
&* LCD is enabled on General Purpose EVM operating in profile 0/1/2 and on IP-Phone.
&* Backlight is through eCAP0_in_PWM0_out pin, controls brightness via eCAP0 module. LCD EVM also has alternative backlight control via TLC59108 power control chip. This is via do not implement(DNI) R23 register on non-alpha boards, only populated in-case of non-availability of eCAP0_in_PWM0_out pin.
(由da8xx-fb.c中调用的clk_get(2)可知,它的LCDC时钟由sysclk2获得,但是clk_get函数并没有在AM335x中被定义,所以需要自己编写,可以直接返回CLKPM2的值192MHz,也可以参考下面的帖子:)
(http://patchwork.ozlabs.org/patch/264389/)
(为了控制LM2733,需要两个IO,一个做shutdown的使能,一个做负载的PWM波切换。)
3. Driver Configuration
3.1 Building as Loadable Kernel Module
4. Usage and Verification
(上面这几个小节的内容是基于Linux系统的,而不是U-Boot。)
通过这两个帖子,可以知道,要成功驱动LCD,就需要知道如何配置da8xx-fb.c和da8xx-fb.h的结构体参数,以及调用其中的函数。
旗下网站:
与非门科技(北京)有限公司 All Rights Reserved.
京ICP证:070212号
北京市公安局备案编号: 京ICP备:号

我要回帖

更多关于 uboot不能启动kernel 的文章

 

随机推荐