转载 uboot LCD 进度条 为OMAP L138增加uboot启动画面

先说说环境 OMAPL138 软件以TI为主, 开发板是我们自己做的, 仿真器是闻亭的

由于默认的UBOOT不支持OMAPL138开机画面, 所以需要手动移植, 我的移植分为3个阶段, 前2个阶段都以失败告终, 如果不想耽误时间可以直接跳转到第3阶段处.

 

第一阶段: 在TI官方提供的开发包里, 找到用CCS测试LCD 的程序, 将此程序稍作修改生成2个文件, my_lcd.h和my_lcd.c

MY_LCD.C ( 示意代码 )

#include "my_lcd.h"

void mlz_usleep ( int n ) { 略 }

void OMAPL138_lpscTransition(psc_regs_t *psc, unsigned int in_domain, unsigned char in_module, unsigned char in_next_state)

{

while (CHKBIT(psc->PTSTAT, in_domain)) {}

... 略

}

unsigned int enable_lcdc( void )

{

/* Enable the LCD Hardware */

OMAPL138_lpscTransition(PSC1, DOMAIN0, LPSC_LCDC, PSC_ENABLE);

... 略

return (ERR_NO_ERROR);

}

unsigned int raster_config( void )

{

unsigned int x;

unsigned short *pdata;

LCDC->RASTER_CTRL &= 0xfffffffe; // Turn raster controller off

return (ERR_NO_ERROR);

... 略

}

unsigned int disable_lcdc( void ) {略}

void RASTER_plot(unsigned short x, unsigned short y, unsigned short pixel_data)

{

*((unsigned short *)(FRAMEBUF_BASE + 32 + y * (LCD_WIDTH <<1) + (x << 1))) = pixel_data;

}

unsigned int RASTER_init(void)

{

int x,y;

unsigned int rtn = ERR_NO_ERROR;

// enable power and setup lcdc.

enable_lcdc();

raster_config();

mlz_usleep(300000);

disable_lcdc();

mlz_usleep(100000);

// power-up the display kit following the correct sequence.

// enable_lcd_power();

enable_lcdc();

mlz_usleep(300000);

// enable_lcd_backlight();

for (x = 0; x < LCD_WIDTH; x++)

for (y = 0; y < LCD_HEIGHT; y++)

RASTER_plot(x, y, 0x55aa );

return (rtn);

}

 

MY_LCD.H ( 示意代码 )

typedef struct

{

volatile unsigned int REVID; // 0x0000

} psc_regs_t;

#define SETBIT(dest,mask) (dest |= mask)

#define CLRBIT(dest,mask) (dest &= ~mask)

// define the power and sleep config modules.

#define PSC0 ((psc_regs_t *)PSC0_REG_BASE)

#define PSC1 ((psc_regs_t *)PSC1_REG_BASE)

//-----------------------------------------------------------------------------

// power and sleep config registers

typedef struct

{

volatile unsigned int REVID; // 0x0000

volatile unsigned int LCD_CTRL; // 0x0004

...

} lcdc_regs_t;

#define LCDC ((lcdc_regs_t *)LCDC_REG_BASE)

#define LCDC_REG_BASE (0x01E13000)

#define FRAMEBUF_BASE 0xc0000000

修改后把这2个文件放入common文件夹中, 并强制修改common文件夹的Makefile, 以生产my_lcd.o

然后在board/davinci/da8xxevm/da850evm.c中增加RASTER_init调用

int board_init(void)

{

Extern void RASTER_init ( void );

RASTER_init();

}

开机, 应该出现整屏的蓝色, 但颜色变成了渐变色而且分成了好几块, 且一段时间后会花屏, 跟彩色电视机的雪花一样, 然后在linux的开机画面出现前1s, 出现了一个错位/缩小的linux开机画面.

第二阶段, 利用CONFIG_LCD

自己写驱动失败, 于是想利用UBOOT里的CONFIG_LCD和CONFIG_LCD_LOGO.于是寻找带这2个标记的代码段, 在添加这2个选项后 , 编译会报很多错, 主要因为需要指定一款LCD, 而UBOOT里没有对138的支持, 在 drvier/video里找到atmel 的驱动, 这个对LCD支持比较强, 准备在此基础上改, 把驱动的核心代码换成上面第一阶段的代码. 而思想就是对LCDC进行控制.此过程持续了2,3天, 最终因为关联东西太多而放弃.

第三阶段, 参考HAWK

在QQ群里有人提到了,http://code.google.com/p/hawkboard/downloads/list

作为TI的138的合作伙伴, hawkboard也出了开发板, 下载他的UBOOT代码,编译,可以看见启动画面了, 只是在uboot和linux直接会有1s的时间图像错位, 这点至今我也不会改.

Hawk的源代码在TI的基础上做了不大不小的改动, 在LCD方面, 他没有修改现有的驱动(如atmel), 也没有建立单独的c文件, 也就是说它没有用到 CONFIG_LCD选项. 他的思想和我的第一阶段比较相似, 直接写寄存器, 只不过他做的更简单,下面给出了我修改的文件:

文件名: board/davinci/da8xxevm/da850evm.c

修改说明: 写了一个LCDC初始化函数, 并在系统启动时调用,

写了一个画进度条函数, 以便在别的初始化时显示

LCDC初始化函数里, 对LCDC寄存器的初始化没有采用hawd的方式, 而是采用之前my_lcdc.c里面的参数,

增加 #include "uboot_logo.h" , 此文件存储开机画面图片, 后面介绍

增加 static int X1 = 117; //进度条外框

static int Y1 = 342;

static int X2 = 497;

static int Y2 = 362;

增加 #define LCDDMA_FB0_BASE 0xC3601000 - 32

//定义FB基地址, 范围 0xc0000000~0xc8000000

在这个地址中, -32 是为了将来画图直接从1000开始, 因为前32个字节是调色板, 而1000也是为了变成整数, 最重要的在0xc360xxxx, 以前在my_lcd里写成了0xc0000000, 因为在启动参数里将uImage调入0xc0700000, 而内核的入口地址是c0008000, 这就导致画面被冲, 结果也是如此, 在第一阶段load内核后,只有屏幕最上方的画面还在, 下面花屏了, 最上方正好对应 8000个字节

在HAWD的地址写成了c7200000, 我把它改成了36, 反正DDR的寻址是128M, 即c80000000, 而我的36M也没用, 所以没问题.

之前失败的时候还曾经试过0XA000000, 因为以前写DOS程序的时候FB就是a000000, 现在发现,在UBOOT里, 这个基地址任意给, 只要在DDR的寻址范围内即可.

 

增加进度条显示函数

void DispLogoProgress ( int data )

{

int i, j;

int n = ( X2 - X1 - 6 ) / 100.0 * data*2 + X1 * 2;

for ( i = ( Y1 + 3 ) * 640 * 2 ; i < ( Y2 - 3 ) * 640 * 2; i += 2*640 )

for ( j = ( X1 + 3 ) * 2 ; j < n; j+= 2 )

*((volatile unsigned short *)(LCDDMA_FB0_BASE+32+i+j ) ) = 0xfc00;

}

增加初始化LCDC函数

static void logo_init(void)

{

unsigned int i,k;

unsigned char pixel[3];

int offset = 0;

int ptr = 0;

*((volatile uint *) 0x01E13028) = 0x010000C0; //TURN_OFF RASTER_CTRL

*((volatile uint *) LCDDMA_FB0_BASE) = 0x00004000;

*((volatile uint *) 0x01E13004) = 0x00000801; //LCD_CTRL

*((volatile uint *) 0x01E1302C) = (0x19 << 24)

| (0x89 << 16)

| (0x31 << 10)

| (0x27 << 4);; //RASTER_TIMING_0

*((volatile uint *) 0x01E13030) = (0x1F << 24)

| (0x20 <<16)

| (0x02 <<10)

| (0x1DF);; //RASTER_TIMING_1

*((volatile uint *) 0x01E13034) = 0x02700000 ; //RASTER_TIMING_2

*((volatile uint *) 0x01E13038) = 0x00000000; //RASTER_SUBPANEL

*((volatile uint *) 0x01E13040) = 0x00000640; //LCDDMA_CTRL

*((volatile uint *) 0x01E13044) = LCDDMA_FB0_BASE; //LCDDMA_FB0_BASE

*((volatile uint *) 0x01E13048) = LCDDMA_FB0_BASE + 640*480*2 + 30; //LCDDMA_FB0_CEILING

//画黑色背景

for (i = 0; i < (640*480*2); i+= 2)

*((volatile unsigned short *)(LCDDMA_FB0_BASE+32 + i)) = 0x0;

//显示白色字体, log_buf里存的不是颜色, 而是白色的偏移量

for ( i = 0 ; i < 4608 ; i++ )

*((volatile unsigned short *)(LCDDMA_FB0_BASE+32 + logo_buf[i] ) ) = 0xffff;

//

//显示进度条框

for ( i = Y1*640*2+X1*2 ; i < Y1*640*2+X2*2; i+= 2 ) //横线

*((volatile unsigned short *)(LCDDMA_FB0_BASE+32 + i)) = 0xfc00;

for ( i = Y2*640*2+X1*2 ; i < Y2*640*2+X2*2; i+= 2 )

*((volatile unsigned short *)(LCDDMA_FB0_BASE+32 + i)) = 0xfc00;

这里有2点值得注意, 一是一开始TURN_OFF RASTER_CTRL然后对LCDC寄存器初始化, 在my_lcd.c里, 初始化结束后要再打开这个CTRL, 然后就可以写屏了, 但HAWD把它放到了后面(下文提到), 我把它放到这里屏幕不正常.

二是LCDDMA_CTRL的默认值, MY_lcd.C里是0x20, 而通过调试发现, uboot实际启动时, 此参数是640, 而hawd是540, 而不论哪个值, 都会在uboot和linux切换的1s左右会有闪屏, 但640 闪的小些, 这个问题暂时无法解决.

 

增加logo_init调用logo_init

int board_init(void)

{

logo_init();

Return 0;

}

增加代码, 关闭LCDC

int misc_init_r(void)

{

dspwake();

*((volatile uint *) 0x01E13028) = 0x010000C1; //关闭控制器

return (0);

}

 

文件名

/lib_arm/board.c

修改摘要

增加阶段显示进度条

修改内容

增加函数声明:extern void DispLogoProgress ( int ) ;

增加进度显示

void start_armboot (void)

{

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)

{ if ((*init_fnc_ptr)() != 0) {hang ();}}

DispLogoProgress(10);

}

增加进度显示

DispLogoProgress(20);

for (;;) {

main_loop ();

}

 

文件名

/lib_arm/common/cmd_nand.c

修改摘要

增加阶段显示进度条

修改内容

Void nand_load_image ( void )

{

/* Loading ok, update default load address */

load_addr = addr;

// 从NAND将linux内核load到内存后, 显示进度条

extern void DispLogoProgress(int);

DispLogoProgress(40);

}

 

文件名

/lib_arm/common/cmd_bootm.c

修改摘要

增加阶段显示进度条

修改内容

Int bootm_start( void )

{

// bootm 执行成功后更新进度条

extern void DispLogoProgress(int);

DispLogoProgress ( 50 );

return 0;

}

 

增加文件:board/davinci/da8xxevm/uboot_logo.h

说明: 存放初始背景图片, 由于初始背景图片简单, 且单色, 所以实际存储的只是白色的文字所在的位置,一共4K多个点,

最后附上UBOOT 启动流程(从LCD角度)




start_armboot ()
{
board_init ()
{
logo_init()
{

初始化LCDC
设置进度条 0%

}
}

.... 其他初始化

设置进度条10%

misc_init_r
{
关闭LCDC控制器
}

设置进度条20%

main_loop
{

加载内核从NAND到内存后, 40%
BOOTM执行后50%
}
}

 

HTTP 监控程序使用说明(本程序只能用于Win2000/XP,不能用于NT4) 将 HttpMon.exe 复制到硬盘上,并将其添加到Windows的任务计划中,设置为"计算机启动时运行",以administrator 的权限运行。 功能一 定时功能 ------------------------------------------------------------ 可指定每隔几天重启一次计算机或是重启IIS。 若是指定为0天时表示每天重启一次。 功能二 http监控 ------------------------------------------------------------ 1.运行HttpMon.exe 点击"添加"按钮添加监控条件。 a)在"检查链接"里加上用来监控的页面 在state.asp加随意加上一个简单代码,如<%response.write "OK"%> 这样可以检查IIS是否死掉 若要检查链接数据库是否正常还可以把代码写为: <% set db=CreateObject("ADODB.Connection") db.open 数据库链接 db.close %> b)在"检查频率"中可以指定多长时间检查一次,默认是20分钟 c)在返回信息中选择要检查的条件,有几种情况: 返回状态等于,返回状态值不等于,文件大小等于,小于,大于。 "返回状态值" 指IIS返回的客户端时的状态。 200 是正常 302 文件重定向 404 文件找不到 500 服务器内部错误 . . . 默认是:当返回状态不等于200时(表示IIS出错时)重起IIS 当上面情况出现时可做几个对应处理: a)重启计算机 b)重启IIS c)关闭计算机 d)请求页面 "请求页面"可用于扩展程序功能,如通过请求一个程序页面 发信给管理员。 2.因为有时重启IIS不一定成功,所以当上面错误情况出现时,程序会自动缩短检查的隔时间,默认为5分钟。也可以自定义。 当上面操作多次重试都不成功时,还可以设置对应的操作。例如:当重启了3次IIS后还是有错误,这时可以在后面设置为重启计算机 3.关于日志功能 日志功能可以记录Http监控程序的工作情况,他可以记录什么时候检查过什么页面,什么时候出现了错误,对应操作是什么。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值