Erkundung von LCD-Bildschirmtreibern unter Linux für Einsteiger

Inhaltsverzeichnis

LCD ist ein häufig verwendetes Peripheriegerät, und Halbleiterhersteller stellen in der Regel vorgefertigte LCD-Schnittstellentreiberprogramme für ihre Chips bereit. Entwickler müssen den LCD-Treiberabschnitt nicht ändern; sie müssen lediglich den Gerätebaum gemäß dem spezifischen verwendeten LCD-Gerät anpassen. Obwohl keine Änderungen am Treiber erforderlich sind, ist es dennoch wichtig, den LCD-Treiberprozess zu verstehen.

 

 

 

 

 

 

 

 

 

1. Framebuffer-Gerät

Im Linux-Betriebssystem interagieren Anwendungen letztendlich mit dem Videospeicher des RGB-LCD, um Zeichen, Bilder und andere Informationen auf dem LCD-Bildschirm anzuzeigen. Die Speicherverwaltung in Linux ist streng, und Videospeicher muss zugewiesen werden. Aufgrund des Vorhandenseins von virtuellem Speicher muss der vom Treiber festgelegte Videospeicher und der von der Anwendung zugängliche Videospeicher demselben physischen Speicher entsprechen. Um dieses Problem zu lösen, wurde der Framebuffer (kurz “fb”) eingeführt. Der Framebuffer stellt einen Speicherbereich dar, der ein Bild eines Frames speichert. Das Schreiben von Daten in diesen Speicher entspricht dem Schreiben von Daten auf den Bildschirm. Im Wesentlichen bildet der Framebuffer jeden Punkt auf dem Bildschirm auf einen linearen Speicherraum ab, wodurch Programme den Wert dieses Speichersegments ändern können, um die Farbe eines bestimmten Punkts auf dem Bildschirm zu ändern.

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

Der Framebuffer-Mechanismus bietet eine einheitliche Schnittstelle für Benutzerraumoperationen auf Anzeigegeräten und abstrahiert die Unterschiede zwischen zugrunde liegenden Hardwarekomponenten. Wenn der LCD-Treiber erfolgreich geladen wird, erzeugt er eine Gerätedatei namens /dev/fbX. Anwendungen können über diese Gerätedatei auf den LCD zugreifen. /dev/fbX ist ein Zeichengerät und hat seinen entsprechenden file_operations Operationssatz, der in der Datei drivers/video/fbdev/core/fbmem.c definiert ist.

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

Der Linux-Kernel abstrahiert alle Framebuffer als fb_info Strukturen. Die fb_info Struktur enthält die vollständigen Attribute und Operationssätze des Framebuffer-Geräts. Daher ist jedes Framebuffer-Gerät mit einem fb_info. verknüpft. Die Struktur ist in der Datei include/linux/fb.h definiert ist.

2. Analyse des LCD-Treibers

Für einen gegebenen Chip bleibt der Treibercode für den eLCDIF-Controller für LCD-Bildschirme mit unterschiedlichen Auflösungen gleich. Als Beispiel betrachten wir den LCD-Treiber für den NXP IMX6ULL-Chip in Linux und skizzieren kurz den Prozess des LCD-Treibers.

  • Öffnen des Gerätebaums: Öffnen Sie die Datei imx6ull.dtsi und suchen Sie den Inhalt des lcdif Node, der Konfigurationsdetails für den LCD-Interface-Controller enthält.

lcdif: lcdif@021c8000 {
compatible = “fsl,imx6ul-lcdif”, “fsl,imx28-lcdif”;
reg = ;
interrupts = ;
clocks = ,
,
;
clock-names = “pix”, “axi”, “disp_axi”;
status = “disabled”;
};

  • Gerätetreiber-Abgleich: Der compatible Eigenschaftswert wird verwendet, um den Gerätetreiber im Linux-Quellcode abzugleichen. Die mxsfb.c Datei enthält den Platform-Treiber für den 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-Funktion: Wenn der Treiber mit dem Gerät übereinstimmt, wird die mxsfb_probe Funktion ausgeführt. Diese Funktion initialisiert das Framebuffer-Gerät, weist Ressourcen zu, mappt Speicher und richtet den Interrupt-Handler ein.

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, “Kann Speicher-IO-Ressource nicht abrufen\n”);
return -ENODEV;
}

host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, “Zuweisung der IO-Ressource fehlgeschlagen\n”);
return -ENOMEM;
}

fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
if (!fb_info) {
dev_err(&pdev->dev, “Zuweisung von fbdev fehlgeschlagen\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) fehlgeschlagen mit Fehler %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 fehlgeschlagen\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

Zum Anfang scrollen