Erkundung von LCD-Bildschirmtreibern unter Linux für Einsteiger

Inhaltsverzeichnis

LCD is a commonly used peripheral, and semiconductor manufacturers typically provide pre-written LCD interface driver programs for their chips. Developers don’t need to modify the LCD driver section; they only need to adjust the device tree according to the specific LCD device they are using. While no modifications are necessary in the driver, it’s still essential to comprehend the LCD driver process.

 

 

 

 

 

 

 

 

 

1. Framebuffer Device

In the Linux operating system, applications ultimately interact with the video memory of RGB LCD to display characters, images, and other information on the LCD screen. Memory management in Linux is rigorous, and video memory needs to be allocated. Moreover, because of the presence of virtual memory, the video memory set by the driver and the video memory accessed by the application must correspond to the same physical memory. To address this issue, the Framebuffer (referred to as “fb”) was introduced. The Framebuffer represents a memory area that stores a frame of an image. Writing data to this memory is equivalent to writing data to the screen. In essence, the Framebuffer maps each point on the screen to a linear memory space, enabling programs to change the value of this memory segment to alter the color of a specific point on the screen.

static const struct file_operations fb_fops = {
.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,
};

The Framebuffer mechanism provides a unified interface for user space operations on display devices, abstracting away the differences between underlying hardware components. When the LCD driver is successfully loaded, it generates a device file named /dev/fbX. Applications can access the LCD through this device file. /dev/fbX is a character device, and it has its corresponding file_operations operation set, which is defined in the drivers/video/fbdev/core/fbmem.c file.

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;
};

The Linux kernel abstracts all Framebuffers as fb_info structures. The fb_info structure contains the complete attributes and operation sets of the Framebuffer device. As a result, each Framebuffer device is associated with an fb_info. The structure is defined in the include/linux/fb.h file.

2. Analysis of the LCD Driver

For a given chip, the driver code for the eLCDIF controller for LCD screens with different resolutions remains the same. As an example, let’s consider the LCD driver for the NXP IMX6ULL chip in Linux and briefly outline the LCD driver’s process.

  • Opening the Device Tree: Open the imx6ull.dtsi file and locate the content of the lcdif node, which contains configuration details for the LCD interface controller.

lcdif: lcdif@021c8000 {
compatible = “fsl,imx6ul-lcdif”, “fsl,imx28-lcdif”;
reg = <0x021c8000 0x4000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
<&clks IMX6UL_CLK_LCDIF_APB>,
<&clks IMX6UL_CLK_DUMMY>;
clock-names = “pix”, “axi”, “disp_axi”;
status = “disabled”;
};

  • Device Driver Matching: The compatible property value is used to match the device driver in the Linux source code. The mxsfb.c file contains the platform driver for the MXS Framebuffer.

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);

  • Probe Function: When the driver matches the device, the mxsfb_probe function is executed. This function initializes the Framebuffer device, allocates resources, maps memory, and sets up the interrupt handler.

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, “Cannot get memory IO resource\n”);
return -ENODEV;
}

host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, “Failed to allocate IO resource\n”);
return -ENOMEM;
}

fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
if (!fb_info) {
dev_err(&pdev->dev, “Failed to allocate 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) failed with error %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 failed\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, "Fehler bei der Registrierung des Framebuffers\n");
goto fb_destroy;
}
……
return ret;
}

  • Framebuffer-Initialisierung: Der Framebuffer wird initialisiert und der Treiber registriert ihn beim Linux-Kernel.

Die Hauptaufgaben der mxsfb_probe Funktion umfassen die Speicherzuweisung für fb_info, die Speicherzuweisung für pseudo_palette, die Initialisierung des eLCDIF-Controllers und die Registrierung des fb_info beim Linux-Kernel.

Tatsächlich stellt die Verwendung des Linux-Systems für viele LCD-Modulhersteller stets eine technische Herausforderung dar. Die Auswahl des richtigen LCD-Modulherstellers ist nicht einfach für diejenigen, die Produkte mit dem Linux-System entwickeln. RJOYTEK ist ein Technologieunternehmen, das sich auf LCD-Module und Board-Entwicklung spezialisiert hat. Wenn Sie weitere technische Unterstützung benötigen, zögern Sie bitte nicht uns zu kontaktieren!

Über RJY Display

Wir sind ein führender LCD-Panel-Hersteller und Anbieter von Display-Lösungen aus China, der sich der Entwicklung und Produktion von leistungsstarken, kostengünstigen und hochzuverlässigen LCD-Panels widmet. Darüber hinaus liefern wir maßgeschneiderte Display-Lösungen, die den vielfältigen Anforderungen verschiedener HMI-Anwendungen (Human-Machine Interface) gerecht werden. Unsere Mission ist es, Kunden dabei zu helfen, Wartungsrisiken von Geräten zu reduzieren und gleichzeitig die Wettbewerbsfähigkeit auf dem Markt zu stärken. Ob Sie neue Display-Lösungen erkunden oder nach langfristigen Lieferpartnern suchen, unser Team steht bereit, um kostenlose Fachberatung, die neuesten Produktkataloge und wettbewerbsfähige Angebote.

Warum RJY Display wählen?

  • Alles-aus-einer-Hand-Lösungen: Neben vollständig kundenspezifischen LCD-Modulen liefern wir auch passende Steuerplatinen, digitale Kabel und Touch-Lösungen – zusammen gekauft für nahtlose Integration.

  • Anpassungsflexibilität: Produktgröße, Touchscreen-Typ, digitale Schnittstelle und Steuerplatine können alle an Ihre spezifischen Projektanforderungen angepasst werden.

  • Zertifizierte Qualität: Unsere Produkte und Fabriken halten Zertifizierungen einschließlich ISO9001, ISO45001, REACH, CE, was Konformität und Zuverlässigkeit gewährleistet.

  • Starke Produktionskapazität: Mit zwei modernen Fabrikengarantieren wir kurze Lieferzeiten und effiziente Massenproduktion, um Ihre Projekte in jedem Maßstab zu unterstützen.

Arbeiten Sie mit RJY Display zusammen für vertrauenswürdige Displaylösungen, schnellere Projektabwicklung und langfristigen Geschäftswert.

Diesen Beitrag teilen
Facebook
Twitter
LinkedIn
WhatsApp

Senden Sie uns eine Nachricht

Bitte aktiviere JavaScript in deinem Browser, um dieses Formular fertigzustellen.
Zum Anfang scrollen