U-boot中通過ENV設定顯示裝置(如LCD)引數的方法與格式
阿新 • • 發佈:2019-02-11
對於一個移植比較完善的U-boot來說,顯示裝置一般也是可以使用的。在嵌入式中的LCD液晶屏一般由晶片的內建的LCD控制器或者VPSS(視訊處理子系統)來控制。在U-boot中已經實現了類似framebuffer的機制,只要在移植的時候完成對LCD控制等顯示裝置的初始化,並將framebuffer的對應的記憶體地址空間通過結構體傳遞給u-boot的中控制檯實現部分,就可以在u-boot的啟動時從LCD上看到u-boot的控制檯終端資訊,並且可以在LCD的左上角看到uboot的logo。對於顯示部分的初始化程式碼根據CPU晶片的不同而異,但是大體結構都是一樣的。
在大部分液晶控制器的初始化中都需要以下引數:
- /******************************************************************
- * 解析結構體
- ******************************************************************/
- struct ctfb_res_modes {
- int xres;
/* 可見解析度
*/
- int yres;
- /* 時序: 所有值都以畫素時鐘為單位(當然除了畫素時鐘本身)
*/
- int pixclock;
/* 畫素時鐘(單位:微秒)
*/
- int left_margin;
/* 從行同步到影象左邊沿的畫素時鐘數
*
- int right_margin;
/* 從行同步到影象右邊沿的畫素時鐘數
*/
- int upper_margin;
/* 從場同步到影象上邊沿的行數
*/
- int lower_margin;
/* 從場同步到影象下邊沿的行數
*/
- int hsync_len;
/* 行同步時間長度(畫素時鐘數)
*/
- int vsync_len;
/* 場同步時間長度(行數)
*/
- int sync;
/* see FB_SYNC_*
*/
- int vmode;
/* see FB_VMODE_*
*/
- };
- got_mode = 0;
- videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
- /*
get video mode via environment
*/
- if (((penv
= getenv ("videomode"))
!=
NULL) &&
- (penv[0]
<=
'9')) {
- videomode =
(int) simple_strtoul
(penv,
NULL, 16);
- /* parameter are vesa modes
*/
- /* search params
*/
- for (i
= 0; i
< VESA_MODES_COUNT; i++)
{
- if (vesa_modes[i].vesanr
== videomode)
- break;
- }
- if (i
== VESA_MODES_COUNT)
{
- printf ("no VESA Mode found, switching to mode 0x%x ",
- CONFIG_SYS_DEFAULT_VIDEO_MODE);
- i = VESA_MODES_COUNT
- 2;
- }
- res_mode =
(struct ctfb_res_modes *)
&res_mode_init[vesa_modes[i].resindex];
- bits_per_pixel = vesa_modes[i].bits_per_pixel;
- } else
{
- /*init
to default params*/
- res_mode =
(struct ctfb_res_modes *)
&res_mode_init[vesa_modes[VESA_MODES_COUNT
- 2].resindex];
- bits_per_pixel = vesa_modes[VESA_MODES_COUNT
- 2].bits_per_pixel;
- if
((penv = getenv
("video-mode"))
!=
NULL) {
- ret = video_get_video_mode(&var_mode.xres,
&var_mode.yres,
- &bits_per_pixel,
&dumpfreq,
&p);
- while
((i = video_get_param_len
(p,
','))
!= 0)
{
- GET_OPTION ("le:", var_mode.left_margin)
- GET_OPTION ("ri:", var_mode.right_margin)
- GET_OPTION ("up:", var_mode.upper_margin)
- GET_OPTION ("lo:", var_mode.lower_margin)
- GET_OPTION ("hs:", var_mode.hsync_len)
- GET_OPTION ("vs:", var_mode.vsync_len)
- GET_OPTION ("pclk:", var_mode.pixclock)
- p += i;
- if
(*p != 0)
- p++; /* skip
','
*/
- }
- res_mode =
(struct ctfb_res_modes *)
&var_mode;
- } else {
- printf ("no Video params found, try bootargs~~ ");
- res_mode =
(struct ctfb_res_modes *)
&var_mode;
- bits_per_pixel = video_get_params
(res_mode,
"bootargs");
- if((bits_per_pixel
!= 8)
&&
- (bits_per_pixel
!= 15)
&&
- (bits_per_pixel
!= 16)
&&
- (bits_per_pixel
!= 24)) {
- printf ("Get params error, set to default!");
- res_mode =
(struct ctfb_res_modes *)
&res_mode_init[vesa_modes[VESA_MODES_COUNT
- 2].resindex];
- bits_per_pixel = vesa_modes[VESA_MODES_COUNT
- 2].bits_per_pixel;
- }
- }
- }
- 一、選擇預先編譯進uboot的某個顯示器引數(videomode=)
- const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT]
= {
- ......
- {0x211, RES_MODE_240x320, 16},
- {0x212, RES_MODE_480x272, 16},
- {0x213, RES_MODE_800x480, 16},
- };
- const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT]
= {
- /* x y pixclk le ri up lo hs vs s vmode
*/
- ......
- {240, 320, 90000, 1, 4, 1,
1, 30, 4, 0, FB_VMODE_NONINTERLACED},
- {480, 272, 75000, 2, 3, 1,
1, 40, 1, 0, FB_VMODE_NONINTERLACED},
- {800, 480, 50000, 2, 2, 2,
2, 41, 4, 0, FB_VMODE_NONINTERLACED},
- };
- 3.5寸 :videomode=0x211
- 4.3寸 :videomode=0x212
- 7 寸 :videomode=0x213
- 3.5寸 : setenv videomode 0x211 ;saveenv
- 4.3寸 : setenv videomode 0x212 ;saveenv
- 7 寸 : setenv videomode 0x213 ;saveenv
- 二、通過環境變數(video-mode=)獲取引數
- video-mode=ctfb:800x480-16@60,le:2,ri:2,up:2,lo:2,hs:41,vs:4,pclk:50000
- 三、從將要傳遞給核心的cmdline(bootargs=)獲取引數
- video=ctfb:x:800,y:480,depth:16,le:2,ri:2,up:2,lo:2,hs:41,vs:4,pclk:50000,vmode:0,sync:0