一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

U

 arm_embed 2012-12-07

原文地址U-boot中通過ENV設(shè)置顯示設(shè)備(如LCD)參數(shù)的方法與格式 作者tekkamanninja


       對于一個(gè)移植比較完善的U-boot來說,顯示設(shè)備一般也是可以使用的。在嵌入式中的LCD液晶屏一般由芯片的內(nèi)置的LCD控制器或者VPSS(視頻處理子系統(tǒng))來控制。在U-boot中已經(jīng)實(shí)現(xiàn)了類似framebuffer的機(jī)制,只要在移植的時(shí)候完成對LCD控制等顯示設(shè)備的初始化,并將framebuffer的對應(yīng)的內(nèi)存地址空間通過結(jié)構(gòu)體傳遞給u-boot的中控制臺(tái)實(shí)現(xiàn)部分,就可以在u-boot的啟動(dòng)時(shí)從LCD上看到u-boot的控制臺(tái)終端信息,并且可以在LCD的左上角看到uboot的logo。對于顯示部分的初始化代碼根據(jù)CPU芯片的不同而異,但是大體結(jié)構(gòu)都是一樣的。
      在大部分液晶控制器的初始化中都需要以下參數(shù):

  1. /******************************************************************
  2.  * 解析結(jié)構(gòu)體
  3.  ******************************************************************/
  4. struct ctfb_res_modes {
  5.     int xres; /* 可見分辨率 */
  6.     int yres;
  7.     /* 時(shí)序: 所有值都以像素時(shí)鐘為單位(當(dāng)然除了像素時(shí)鐘本身) */
  8.     int pixclock; /* 像素時(shí)鐘(單位:微秒) */
  9.     int left_margin; /* 從行同步到圖像左邊沿的像素時(shí)鐘數(shù) */
  10.     int right_margin; /* 從行同步到圖像右邊沿的像素時(shí)鐘數(shù) */
  11.     int upper_margin; /* 從場同步到圖像上邊沿的行數(shù) */
  12.     int lower_margin; /* 從場同步到圖像下邊沿的行數(shù) */
  13.     int hsync_len; /* 行同步時(shí)間長度(像素時(shí)鐘數(shù)) */
  14.     int vsync_len; /* 場同步時(shí)間長度(行數(shù)) */
  15.     int sync; /* see FB_SYNC_* */
  16.     int vmode; /* see FB_VMODE_* */
  17. };

      而這些參數(shù)將隨著所使用的LCD液晶屏不同而不同。如果將這些參數(shù)寫死在代碼中,這樣換一個(gè)不同參數(shù)的液晶屏就要重新給參數(shù),重新編譯一次uboot,這么做當(dāng)然比較不合適。動(dòng)態(tài)配置這些參數(shù)對于U-boot來說,當(dāng)然是從自身ENV(環(huán)境變量)中獲取。兩年前我在移植MINI6410的時(shí)候,就對液晶屏的顯示做了支持,并參考uboot中別的液晶驅(qū)動(dòng)做了動(dòng)態(tài)參數(shù)配置的支持,但是當(dāng)時(shí)寫完代碼之后沒有仔細(xì)去測試和研究其配置的方法和格式。這些研究顯示設(shè)備參數(shù)的傳遞的時(shí)候才重新回來驗(yàn)證一下原來的代碼,發(fā)現(xiàn)原來我在MINI6410上的代碼是完全OK的,并支持3種不同的配置方法。關(guān)鍵的參數(shù)獲取代碼如下:

  1. got_mode = 0;
  2.     videomode = CONFIG_SYS_DEFAULT_VIDEO_MODE;
  3.          /* get video mode via environment */
  4.          if (((penv = getenv ("videomode")) != NULL) &&
  5.                  (penv[0] <= '9'))    {
  6.                      videomode = (int) simple_strtoul (penv, NULL, 16);
  7.          /* parameter are vesa modes */
  8.          /* search params */
  9.          for (i = 0; i < VESA_MODES_COUNT; i++) {
  10.          if (vesa_modes[i].vesanr == videomode)
  11.          break;
  12.          }
  13.          if (i == VESA_MODES_COUNT) {
  14.          printf ("no VESA Mode found, switching to mode 0x%x ",
  15.                      CONFIG_SYS_DEFAULT_VIDEO_MODE);
  16.          i = VESA_MODES_COUNT - 2;
  17.          }
  18.          res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i].resindex];
  19.          bits_per_pixel = vesa_modes[i].bits_per_pixel;
  20.          } else {
  21.                  /*init to default params*/
  22.                  res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[VESA_MODES_COUNT - 2].resindex];
  23.                 bits_per_pixel = vesa_modes[VESA_MODES_COUNT - 2].bits_per_pixel;

  24.                  if ((penv = getenv ("video-mode")) != NULL) {
  25.                     ret = video_get_video_mode(&var_mode.xres, &var_mode.yres,
  26.                                                 &bits_per_pixel, &dumpfreq, &p);

  27.                     while ((i = video_get_param_len (p, ',')) != 0) {
  28.                         GET_OPTION ("le:", var_mode.left_margin)
  29.                         GET_OPTION ("ri:", var_mode.right_margin)
  30.                         GET_OPTION ("up:", var_mode.upper_margin)
  31.                         GET_OPTION ("lo:", var_mode.lower_margin)
  32.                         GET_OPTION ("hs:", var_mode.hsync_len)
  33.                         GET_OPTION ("vs:", var_mode.vsync_len)
  34.                         GET_OPTION ("pclk:", var_mode.pixclock)
  35.                         p += i;
  36.                         if (*p != 0)
  37.                             p++;    /* skip ',' */
  38.                     }
  39.          res_mode = (struct ctfb_res_modes *) &var_mode;
  40.                 }    else    {
  41.                     printf ("no Video params found, try bootargs~~ ");
  42.                     res_mode = (struct ctfb_res_modes *) &var_mode;
  43.                     bits_per_pixel = video_get_params (res_mode, "bootargs");
  44.                     if((bits_per_pixel != 8) &&
  45.                         (bits_per_pixel != 15) &&
  46.                         (bits_per_pixel != 16) &&
  47.                         (bits_per_pixel != 24))    {
  48.                         printf ("Get params error, set to default!");
  49.                         res_mode = (struct ctfb_res_modes *) &res_mode_init[vesa_modes[VESA_MODES_COUNT - 2].resindex];
  50.                         bits_per_pixel = vesa_modes[VESA_MODES_COUNT - 2].bits_per_pixel;
  51.                         }
  52.                 }
  53.         }
      上面的代碼根據(jù)先后順序會(huì)從3個(gè)不同的環(huán)境變量中獲取所連接的液晶屏參數(shù):

  • 一、選擇預(yù)先編譯進(jìn)uboot的某個(gè)顯示器參數(shù)(videomode=)
      這種形式的參數(shù)配置適合預(yù)先知道你要用的幾個(gè)液晶屏的參數(shù),并將其寫在driver/video/videomodes.c中。比如我在MINI6410的移植中添加了3.5寸、 4.3寸和7寸屏的參數(shù):


  1. const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
  2. ......
  3.      {0x211, RES_MODE_240x320, 16},
  4.      {0x212, RES_MODE_480x272, 16},
  5.      {0x213, RES_MODE_800x480, 16},
  6. };
  7. const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = {
  8.      /* x y pixclk le ri up lo hs vs s vmode */
  9. ......
  10.      {240, 320, 90000, 1, 4, 1, 1, 30, 4, 0, FB_VMODE_NONINTERLACED},
  11.      {480, 272, 75000, 2, 3, 1, 1, 40, 1, 0, FB_VMODE_NONINTERLACED},
  12.      {800, 480, 50000, 2, 2, 2, 2, 41, 4, 0, FB_VMODE_NONINTERLACED},
  13. };
而對于這三種屏,只需要在環(huán)境變量中配置:

  1. 3.5寸 :videomode=0x211
  2. 4.3寸 :videomode=0x212
  3. 7 寸  :videomode=0x213
即,

  1. 3.5寸 : setenv videomode 0x211 ;saveenv
  2. 4.3寸 : setenv videomode 0x212 ;saveenv
  3. 7 寸 : setenv videomode 0x213 ;saveenv

  • 二、通過環(huán)境變量(video-mode=)獲取參數(shù)
    如果在環(huán)境變量中沒有videomode,則uboot會(huì)繼續(xù)查找是否有video-mode變量。如果有,代碼會(huì)從這個(gè)環(huán)境變量中直接解析出所需要的參數(shù),這個(gè)環(huán)境變量的格式應(yīng)為:

  1. video-mode=ctfb:800x480-16@60,le:2,ri:2,up:2,lo:2,hs:41,vs:4,pclk:50000
其中ctfb 有沒有都無所謂,但是后面的 :一定要有
藍(lán)色的符合只要不是數(shù)字就好,寫成這個(gè)形式比較標(biāo)準(zhǔn)罷了。這個(gè)看了代碼就明白了。

這種情況比較適用于僅uboot需要這些顯示參數(shù),并需要靈活配置的情況。這些參數(shù)沒有主動(dòng)傳遞給內(nèi)核。
  • 三、從將要傳遞給內(nèi)核的cmdline(bootargs=)獲取參數(shù)
    如果通過上面兩步,在環(huán)境變量中沒有正確地解析出參數(shù),代碼會(huì)到bootargs(也就是傳遞給內(nèi)核的cmdline)中找相關(guān)參數(shù),在bootargs中的格式必須是:

  1. 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
紅色的字體是必須的,這個(gè)看了video_get_params 函數(shù)你就明白了。
    這種情況可以靈活配置,并且這些參數(shù)會(huì)通過tagged-list--->cmdline主動(dòng)傳遞給內(nèi)核,適用于uboot和內(nèi)核共享ENV區(qū)參數(shù)的情況。


        而對于在上面我在mini6410中實(shí)現(xiàn)的代碼,其實(shí)可以移植到別的芯片啟動(dòng)中去,只要將參數(shù)解析到struct ctfb_res_modes 中去,其中的數(shù)據(jù)就可以用于初始化LCD控制器等初始化代碼中了

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产精品免费不卡视频| 国产精品刮毛视频不卡| 欧美人妻免费一区二区三区| 欧美日韩精品久久亚洲区熟妇人| 国产精品激情在线观看| 视频一区二区黄色线观看| 欧美性高清一区二区三区视频| 久草热视频这里只有精品| 最新午夜福利视频偷拍| 久久永久免费一区二区| 亚洲国产一级片在线观看| 亚洲丁香婷婷久久一区| 国产亚洲欧美自拍中文自拍| 国产精品国产亚洲区久久| 欧美国产极品一区二区| 中国少妇精品偷拍视频| 91麻豆视频国产一区二区 | 亚洲另类女同一二三区| 国产精品免费无遮挡不卡视频| 日韩精品一级一区二区| 日韩精品一级片免费看| 好吊视频有精品永久免费| 东京热男人的天堂社区| 麻豆剧果冻传媒一二三区| 在线观看国产午夜福利| 欧美三级不卡在线观线看| 日本午夜乱色视频在线观看| 国产成人精品一区在线观看| 国产三级欧美三级日韩三级| 亚洲第一区二区三区女厕偷拍| 少妇熟女亚洲色图av天堂| 日本精品最新字幕视频播放| 小黄片大全欧美一区二区| 国产高清精品福利私拍| 国产一区二区三区香蕉av| 91欧美日韩一区人妻少妇| 亚洲少妇一区二区三区懂色| 国产又大又黄又粗又免费| 视频一区日韩经典中文字幕| 国产日产欧美精品视频| 老司机精品视频免费入口|