LCDは一般的に使用される周辺機器であり、半導体メーカーは通常、自社チップ向けにあらかじめ記述されたLCDインターフェースドライバプログラムを提供しています。開発者はLCDドライバ部分を修正する必要はなく、使用する特定のLCDデバイスに応じてデバイスツリーを調整するだけで済みます。ドライバの修正は不要ですが、LCDドライバのプロセスを理解することは依然として重要です。.

1. フレームバッファデバイス
Linuxオペレーティングシステムでは、アプリケーションは最終的にRGB LCDのビデオメモリと相互作用し、LCD画面上に文字、画像などの情報を表示します。Linuxのメモリ管理は厳格であり、ビデオメモリを割り当てる必要があります。さらに、仮想メモリが存在するため、ドライバによって設定されたビデオメモリとアプリケーションがアクセスするビデオメモリは、同じ物理メモリに対応している必要があります。この問題に対処するために、フレームバッファ(以下「fb」と称す)が導入されました。フレームバッファは、1フレームの画像を格納するメモリ領域を表します。このメモリにデータを書き込むことは、画面上にデータを書き込むことと同等です。本質的に、フレームバッファは画面上の各点を線形メモリ空間にマッピングし、プログラムがこのメモリセグメントの値を変更することで、画面上の特定の点の色を変更できるようにします。.
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
.unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = fb_compat_ioctl,
#endif
.mmap = fb_mmap,
.open = fb_open,
.release = fb_release,
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
.get_unmapped_area = get_fb_unmapped_area,
#endif
#ifdef CONFIG_FB_DEFERRED_IO
.fsync = fb_deferred_io_fsync,
#endif
.llseek = default_llseek,
};
フレームバッファメカニズムは、ユーザ空間が表示デバイスを操作するための統一されたインターフェースを提供し、基盤となるハードウェアコンポーネント間の差異を抽象化します。LCDドライバが正常にロードされると、 /dev/fbX. という名前のデバイスファイルが生成されます。アプリケーションはこのデバイスファイルを通じてLCDにアクセスできます。. /dev/fbX はキャラクタデバイスであり、対応する file_operations 操作セットを持っています。これは drivers/video/fbdev/core/fbmem.c ファイルで定義されています。.
struct fb_info {
atomic_t count;
int node;
int flags;
struct mutex lock;
struct mutex mm_lock;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_monspecs monspecs;
struct work_struct queue;
struct fb_pixmap pixmap;
struct fb_pixmap sprite;
struct fb_cmap cmap;
struct list_head modelist;
struct fb_videomode *mode;
#ifdef CONFIG_FB_BACKLIGHT
struct backlight_device *bl_dev;
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS];
#endif
struct fb_ops *fbops;
struct device *device;
struct device *dev;
int class_flag;
char __iomem *screen_base;
unsigned long screen_size;
void *pseudo_palette;
};
Linuxカーネルはすべてのフレームバッファを fb_info 構造体として抽象化します。 fb_info 構造体には、フレームバッファデバイスの完全な属性と操作セットが含まれています。その結果、各フレームバッファデバイスは fb_info. に関連付けられています。この構造体は include/linux/fb.h ファイルで定義されています。.
2. LCDドライバの分析
特定のチップの場合、異なる解像度のLCD画面用のeLCDIFコントローラのドライバコードは同じままです。例として、LinuxにおけるNXP IMX6ULLチップのLCDドライバを取り上げ、LCDドライバのプロセスを簡単に概説します。.
- デバイスツリーを開く:
imx6ull.dtsiファイルを開き、以下の内容を探します。lcdifLCDインターフェースコントローラの設定詳細を含むノード。
lcdif: lcdif@021c8000 {
compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
reg = ;
interrupts = ;
clocks = ,
,
;
clock-names = "pix", "axi", "disp_axi";
status = "disabled";
};
- デバイスドライバのマッチング:
compatibleプロパティの値は、Linuxソースコード内のデバイスドライバと対応付けるために使用されます。mxsfb.cファイルには、MXSフレームバッファ用のプラットフォームドライバが含まれています。
static const struct of_device_id mxsfb_dt_ids[] = {
{ .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },
{ .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], },
{ /* sentinel */ }
};
……
……
static struct platform_driver mxsfb_driver = {
.probe = mxsfb_probe,
.remove = mxsfb_remove,
.shutdown = mxsfb_shutdown,
.id_table = mxsfb_devtype,
.driver = {
.name = DRIVER_NAME,
.of_match_table = mxsfb_dt_ids,
.pm = &mxsfb_pm_ops,
},
};
module_platform_driver(mxsfb_driver);
- プローブ関数: ドライバがデバイスと一致すると、
mxsfb_probe関数が実行されます。この関数は、フレームバッファデバイスの初期化、リソースの割り当て、メモリのマッピング、および割り込みハンドラの設定を行います。
static int mxsfb_probe(struct platform_device *pdev) {
const struct of_device_id *of_id = of_match_device(mxsfb_dt_ids, &pdev->dev);
struct resource *res;
struct mxsfb_info *host;
struct fb_info *fb_info;
struct pinctrl *pinctrl;
int irq = platform_get_irq(pdev, 0);
int gpio, ret;
……
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "メモリIOリソースを取得できません\n");
return -ENODEV;
}
host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, "IOリソースの割り当てに失敗しました\n");
return -ENOMEM;
}
fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
if (!fb_info) {
dev_err(&pdev->dev, "fbdevの割り当てに失敗しました\n");
devm_kfree(&pdev->dev, host);
return -ENOMEM;
}
host->fb_info = fb_info;
fb_info->par = host;
ret = devm_request_irq(&pdev->dev, irq, mxsfb_irq_handler, 0, dev_name(&pdev->dev), host);
if (ret) {
dev_err(&pdev->dev, "request_irq (%d) がエラー %d で失敗しました\n", irq, ret);
ret = -ENODEV;
goto fb_release;
}
host->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(host->base)) {
dev_err(&pdev->dev, "ioremapに失敗しました\n");
ret = PTR_ERR(host->base);
goto fb_release;
}
……
fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16, GFP_KERNEL);
if (!fb_info->pseudo_palette) {
ret = -ENOMEM;
goto fb_release;
}
INIT_LIST_HEAD(&fb_info->modelist);
pm_runtime_enable(&host->pdev->dev);
ret = mxsfb_init_fbinfo(host);
if (ret != 0)
goto fb_pm_runtime_disable;
mxsfb_dispdrv_init(pdev, fb_info);
if (!host->dispdrv) {
pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
goto fb_pm_runtime_disable;
}
}
if (!host->enabled) {
writel(0, host->base + LCDC_CTRL);
mxsfb_set_par(fb_info);
mxsfb_enable_controller(fb_info);
pm_runtime_get_sync(&host->pdev->dev);
}
ret = register_framebuffer(fb_info);
if (ret != 0) {
dev_err(&pdev->dev, "フレームバッファの登録に失敗しました\n");
goto fb_destroy;
}
……
return ret;
}
- フレームバッファ初期化: フレームバッファデバイスを初期化し、ドライバはLinuxカーネルに登録します。
主なタスクは、 mxsfb_probe メモリの割り当て、 fb_info疑似パレット用のメモリ割り当て、 pseudo_palette、eLCDIFコントローラの初期化、および fb_info をLinuxカーネルに登録することです。
実際、Linuxシステムの使用は、多くのLCDモジュールサプライヤーにとって常に挑戦的な技術的側面です。Linuxシステムを使用して製品を開発する場合、適切なLCDモジュールサプライヤーを選択することは容易ではありません。RJOYTEKは、LCDモジュールおよびボード開発に特化したテクノロジー企業です。さらに技術サポートが必要な場合は、お気軽にご連絡ください。 お問い合わせください!
- 製品リストはこちらでご確認いただけます TFT LCD表示モジュール
- LCDパネル動画はこちら LCDソリューション RJY
- エンジニアリングサポートが必要な場合は お問い合わせください