當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]公司使用的sam9260平臺(tái),LCD自帶控制器,單色。MinGUI的文檔說支持單色LCD,所以打算根據(jù)現(xiàn)有LCD操作方法結(jié)合framebuff驅(qū)動(dòng)格式編寫一個(gè)支持framebuff的新驅(qū)動(dòng)。原有的LCD操作方法實(shí)現(xiàn)了畫矩形、ASCII字符、漢字。最終

公司使用的sam9260平臺(tái),LCD自帶控制器,單色。MinGUI的文檔說支持單色LCD,所以打算根據(jù)現(xiàn)有LCD操作方法結(jié)合framebuff驅(qū)動(dòng)格式編寫一個(gè)支持framebuff的新驅(qū)動(dòng)。

原有的LCD操作方法實(shí)現(xiàn)了畫矩形、ASCII字符、漢字。最終是根據(jù)字符或漢字的點(diǎn)陣信息在屏幕上打點(diǎn)!如此而已。原LCD驅(qū)動(dòng)做了個(gè)雙緩沖顯示區(qū),根據(jù)緩沖區(qū)的變化改寫LCD設(shè)備的顯示區(qū),新的framebuff驅(qū)動(dòng)核心思想是:直接操作顯示區(qū)域,需要自己寫的framebuff驅(qū)動(dòng)里沒有畫點(diǎn)、畫圓、顯示字符、顯示漢字等的具體操作。這些操作在framebuff驅(qū)動(dòng)框架里已經(jīng)實(shí)現(xiàn),無需自己編寫。下面記錄下framebuff驅(qū)動(dòng)的編寫過程,LCD硬件部分僅保留修改LCD顯示區(qū)的IO映射和數(shù)據(jù)寫入即可。

手上這款LCD自帶控制器,只能通過讀寫其提供寄存器和他交互數(shù)據(jù),不能直接映射他的顯示區(qū)域。所以我在驅(qū)動(dòng)里申請(qǐng)了2個(gè)和LCD顯示緩沖區(qū)一樣大小的內(nèi)存,一個(gè)用于模擬framebuff驅(qū)動(dòng)需要的共享內(nèi)存區(qū)域,另一個(gè)用來保存這個(gè)模擬共享區(qū)域的快照,用于比對(duì)共享區(qū)域的變化。當(dāng)檢測(cè)到共享內(nèi)存區(qū)域的變化后,將這個(gè)變化通過LCD的寄存器寫給LCD,這樣就能實(shí)現(xiàn)共享區(qū)域的變化能被同步反映到LCD設(shè)備上。

在內(nèi)核的drivers/video/目錄下有很多fb設(shè)備的驅(qū)動(dòng),我找了個(gè)簡(jiǎn)單的dnfb.c作為參考,以他為藍(lán)本實(shí)現(xiàn)我的驅(qū)動(dòng)。首先修改drivers/video下Kconfig,添加:

config FB_DISPLAY

tristate"WHZYDZ LCD support"

depends on FB && ARM

select FB_CFB_FILLRECT

select FB_CFB_COPYAREA

select FB_CFB_IMAGEBLIT

接著修改Makefile,添加:

obj-$(CONFIG_FB_DISPLAY) += zydz_fb.o

我們?cè)趜ydz_fb.c中來寫驅(qū)動(dòng)代碼,首先要完成顯示區(qū)域的變化如何寫入到設(shè)備,這個(gè)雖不是framebuff驅(qū)動(dòng)本身特有的,但其作為最基本的一環(huán),必須先實(shí)現(xiàn)。原系統(tǒng)平臺(tái)的相關(guān)驅(qū)動(dòng)可以借鑒。原來的驅(qū)動(dòng)代碼是先定位到LCD顯示緩沖的行首,然后一個(gè)字節(jié)一個(gè)字節(jié)的寫,直到寫完一行的數(shù)據(jù),其中位置光標(biāo)自動(dòng)右移。但在我這,一行點(diǎn)位根本顯示不全,我們用的是RA9935A,我懷疑它在控制自動(dòng)移位方面可能存在問題。后來我改變寫數(shù)據(jù)的方式:自己控制位置光標(biāo),然后寫一個(gè)字節(jié)!這樣能正常顯示了。

接先來就是和MiniGUI聯(lián)調(diào),邊調(diào)邊修改我的驅(qū)動(dòng)。MinGUI得使用shadow引擎才能支持8bpp以下的。重新編譯minigui,configure 時(shí)加上--enable-newgal

--enable-videoshadow

--with-targetname=fbcon

MiniGUI.cfg配置文件修改如下:

[system]

# GAL engine and default options

gal_engine=shadow

defaultmode=320x240-1bpp

[shadow]

real_engine=fbcon

經(jīng)過n次的測(cè)試,主要方法是在MinGUI中增加打印信息,根據(jù)輸出信息判斷出錯(cuò)的位置,然后修改驅(qū)動(dòng)。最后跟到了src/newgal/video.c的int GAL_VideoModeOK (int width, int height, int bpp, Uint32 flags)函數(shù),

里面有段注釋和代碼看了,讓人心涼了一大節(jié)!

/* Currently 1 and 4 bpp are not supported */

if ( bpp < 8 || bpp > 32 ) {

return(0);

}

看來MinGUI1.6.10是不支持位深小于8的屏了。我嘗試著注釋掉了這段代碼,以便讓MinGUI能完成初始化的工作。接著出現(xiàn)下面的錯(cuò)誤:

Linux_fbcon fb_fix.line_length=40

Linux_fbcon fbcon_info.yres=240

Linux_fbcon fbcon_info.fb_size=12288

Linux_fbcon fbcon_info.fb=40021000

Linux_fbcon fbcon_info.bpp=1

GAL_GetVideoMode 1

width=320

height=240

bpp=1

Unhandled fault: external abort on non-linefetch (0x008) at 0x40021000

Bus error

查看linux_fbcon.c:

fbcon_info.fb =

#ifdef _FXRM9200_IAL /* workaround for Fuxu RM9200 */

mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, MAP_SHARED,

fbcon_info.fd_fb, 0);

#elif defined (__uClinux__)

mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, 0,

fbcon_info.fd_fb, 0);

#else

mmap (NULL, fbcon_info.fb_size, PROT_READ | PROT_WRITE, MAP_SHARED,

fbcon_info.fd_fb, 0);

#endif

這個(gè)使用到了framebuff驅(qū)動(dòng)的mmap調(diào)用,再查看drivers/video/Fbmem.c默認(rèn)的fb_mmap函數(shù):

/* frame buffer memory */

start = info->fix.smem_start;

len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);

他會(huì)將info->fix.smem_start這個(gè)物理地址進(jìn)行映射。好了,framebuff驅(qū)動(dòng)里面我們可以使用virt_to_phys獲取共享內(nèi)存區(qū)域的物理地址!

自此,edit例程總算運(yùn)行起來了!顯示效果見下圖:


顯示效果不理想,MiniGUI還是用在8bpp以上屏上合適!,下面貼上主要的代碼:

* linux/drivers/video/zydzfb.c -- ZYDZ graphics adaptor frame buffer device


*


* Created 16 Sep2011 by hongchang.yu(yu_hongchang@163.com)


* Based on dnfb.c


*


* History:


*


* This file is subject to the terms and conditions of the GNU General Public


* License. See the file COPYING in the main directory of this archive


* for more details.


*/


#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include



#define LCD_WIDTH 320

#define LCD_HEIGHT 240

#define DISPRAMBUFLSZ (LCD_WIDTH/8)

#define DISPRAMBUFSIZE (DISPRAMBUFLSZ*LCD_HEIGHT)

/* display_ video definitions */


static void __iomem *io_data=NULL;

static void __iomem *io_cmd=NULL;

static void __iomem *io_ctrl=NULL;

static unsigned long ioo_data=0;


static unsigned char *rambuf_org = NULL;

static unsigned char *rambuf_cur = NULL;


/* frame buffer operations */

// zydzfb_blank控制屏幕開關(guān)

static int zydzfb_blank(int blank, struct fb_info *info);


static struct fb_ops zydzfb_ops = {

.owner = THIS_MODULE,

//.fb_blank = zydzfb_blank,

.fb_fillrect = cfb_fillrect,

.fb_copyarea = cfb_copyarea,

.fb_imageblit = cfb_imageblit,

};


struct fb_var_screeninfo zydzfb_var __devinitdata = {

.xres = 320,//實(shí)際x軸分辨率

.yres = 240,//實(shí)際y軸分辨率

.xres_virtual = 320,//虛擬x軸分辨率

.yres_virtual = 240,//虛擬y軸分辨率

.bits_per_pixel= 1, //定義每個(gè)點(diǎn)用多少位表示

.height = -1,

.width = -1,

//.vmode = FB_VMODE_NONINTERLACED,


};

static struct fb_fix_screeninfo zydzfb_fix __devinitdata = {

.id = "zydzfb",//設(shè)備名稱

.type = FB_TYPE_PACKED_PIXELS,

.visual = FB_VISUAL_MONO01 ,/* Monochr. 1=Black 0=White */

.line_length = DISPRAMBUFLSZ,

};


/*

* Initialization

*/


static int __devinit zydzfb_probe(struct platform_device *dev)

{

struct fb_info *info;

int err = 0;

info = framebuffer_alloc(0, &dev->dev);

if (!info)

return -ENOMEM;

info->fbops = &zydzfb_ops;

info->fix = zydzfb_fix;

info->fix.smem_start = virt_to_phys(rambuf_cur);

info->fix.smem_len = DISPRAMBUFSIZE;

info->var = zydzfb_var;

/* Virtual address */

info->screen_base = rambuf_cur;

info->screen_size = DISPRAMBUFSIZE;


err = fb_alloc_cmap(&info->cmap, 2, 0);


if (err < 0) {

framebuffer_release(info);

return err;

}


err = register_framebuffer(info);

if (err < 0) {

fb_dealloc_cmap(&info->cmap);

framebuffer_release(info);

return err;

}


platform_set_drvdata(dev, info);


/* now we have registered we can safely setup the hardware */

printk("display_ frame buffer alive and kicking !n");

retu

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉