Exploration des Pilotes d'Écran LCD sous Linux pour Débutants

Table des matières

L'écran LCD est un périphérique couramment utilisé, et les fabricants de semi-conducteurs fournissent généralement des programmes pilotes d'interface LCD pré-écrits pour leurs puces. Les développeurs n'ont pas besoin de modifier la section du pilote LCD ; ils doivent uniquement ajuster l'arborescence des périphériques en fonction du dispositif LCD spécifique qu'ils utilisent. Bien qu'aucune modification ne soit nécessaire dans le pilote, il est toujours essentiel de comprendre le processus du pilote LCD.

 

 

 

 

 

 

 

 

 

1. Périphérique Framebuffer

Dans le système d'exploitation Linux, les applications interagissent finalement avec la mémoire vidéo de l'écran LCD RGB pour afficher des caractères, des images et d'autres informations sur l'écran LCD. La gestion de la mémoire sous Linux est rigoureuse, et la mémoire vidéo doit être allouée. De plus, en raison de la présence de mémoire virtuelle, la mémoire vidéo définie par le pilote et la mémoire vidéo accessible par l'application doivent correspondre à la même mémoire physique. Pour résoudre ce problème, le Framebuffer (appelé “fb”) a été introduit. Le Framebuffer représente une zone de mémoire qui stocke une image complète. Écrire des données dans cette mémoire équivaut à écrire des données sur l'écran. En substance, le Framebuffer mappe chaque point de l'écran à un espace mémoire linéaire, permettant aux programmes de modifier la valeur de ce segment de mémoire pour changer la couleur d'un point spécifique sur l'écran.

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

Le mécanisme Framebuffer fournit une interface unifiée pour les opérations en espace utilisateur sur les dispositifs d'affichage, en masquant les différences entre les composants matériels sous-jacents. Lorsque le pilote LCD est chargé avec succès, il génère un fichier de périphérique nommé /dev/fbX. Les applications peuvent accéder à l'écran LCD via ce fichier de périphérique. /dev/fbX est un périphérique caractère, et il possède son propre ensemble d'opérations file_operations , qui est défini dans le fichier 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;
};

Le noyau Linux abstrait tous les Framebuffers sous la forme de structures fb_info . La structure fb_info contient les attributs complets et les ensembles d'opérations du périphérique Framebuffer. Par conséquent, chaque périphérique Framebuffer est associé à une fb_info. La structure est définie dans le fichier include/linux/fb.h .

2. Analyse du Pilote LCD

Pour une puce donnée, le code du pilote pour le contrôleur eLCDIF des écrans LCD avec différentes résolutions reste le même. À titre d'exemple, considérons le pilote LCD pour la puce NXP IMX6ULL sous Linux et décrivons brièvement le processus du pilote LCD.

  • Ouverture de l'Arborescence des Périphériques : Ouvrez le fichier imx6ull.dtsi et localisez le contenu du lcdif nœud, qui contient les détails de configuration pour le contrôleur d'interface LCD.

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

  • Correspondance du pilote de périphérique : La compatible valeur de propriété est utilisée pour faire correspondre le pilote de périphérique dans le code source Linux. Le fichier mxsfb.c contient le pilote de plateforme pour le Framebuffer 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], },
{ /* sentinelle */ }
};
……
……
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);

  • Fonction Probe : Lorsque le pilote correspond au périphérique, la fonction mxsfb_probe est exécutée. Cette fonction initialise le périphérique Framebuffer, alloue les ressources, mappe la mémoire et configure le gestionnaire d'interruption.

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, “Impossible d'obtenir la ressource mémoire IO\n”);
return -ENODEV;
}

host = devm_kzalloc(&pdev->dev, sizeof(struct mxsfb_info), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, “Échec de l'allocation de la ressource IO\n”);
return -ENOMEM;
}

fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev);
if (!fb_info) {
dev_err(&pdev->dev, “Échec de l'allocation de 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) a échoué avec l'erreur %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, “Échec de 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, “Échec de l'enregistrement du framebuffer\n”);
goto fb_destroy;
}
……
return ret;
}

  • Initialisation du Framebuffer : Le périphérique Framebuffer est initialisé et le pilote l'enregistre auprès du noyau Linux.

Les principales tâches de la fonction mxsfb_probe fonction incluent l'allocation de mémoire pour fb_info, l'allocation de mémoire pour la pseudo_palette, l'initialisation du contrôleur eLCDIF, et l'enregistrement du fb_info auprès du noyau Linux.

En effet, l'utilisation du système Linux a toujours été un aspect technique difficile pour de nombreux fournisseurs de modules LCD. Choisir le bon fournisseur de modules LCD n'est pas facile pour ceux qui développent des produits avec le système Linux. RJOYTEK est une entreprise technologique spécialisée dans les modules LCD et le développement de cartes. Si vous avez besoin d'une assistance technique supplémentaire, n'hésitez pas à nous contacter!

À propos de RJY Display

Nous sommes un fabricant leader de panneaux LCD et fournisseur de solutions d'affichage basé en Chine, dédié au développement et à la production de panneaux LCD hautes performances, rentables et très fiables. De plus, nous proposons des solutions d'affichage sur mesure conçues pour répondre aux divers besoins de différentes applications d'IHM (Interface Homme-Machine). Notre mission est d'aider les clients à réduire les risques de maintenance des équipements tout en renforçant leur compétitivité sur le marché. Que vous exploriez de nouvelles solutions d'affichage ou recherchiez des partenaires d'approvisionnement à long terme, notre équipe est prête à vous offrir une consultation professionnelle gratuite, les derniers catalogues de produits et des devis compétitifs.

Pourquoi choisir RJY Display ?

  • Solutions tout-en-un : En plus des modules LCD entièrement personnalisés, nous fournissons également des cartes de contrôle compatibles, des câbles numériques et des solutions tactiles — achetés ensemble pour une intégration transparente.

  • Flexibilité de personnalisation : La taille du produit, le type d'écran tactile, l'interface numérique et les options de carte de contrôle peuvent tous être adaptés aux besoins spécifiques de votre projet.

  • Qualité certifiée : Nos produits et usines détiennent les certifications incluant ISO9001, ISO45001, REACH, CE, garantissant conformité et fiabilité.

  • Forte capacité de production : Avec deux usines avancées, nous garantissons des délais de livraison rapides et une production de masse efficace pour soutenir vos projets à toutes les échelles.

Collaborez avec RJY Display pour des solutions d'affichage fiables, une livraison plus rapide des projets et une valeur commerciale à long terme.

Partager cette publication
Facebook
Twitter
LinkedIn
WhatsApp

Envoyez-nous un message

Défiler vers le Haut