1. An interrupt function is implemented in the driver. Under what circumstances is the interrupt generated? There are two main interrupts: INT_FRSYN and INT_FICNT, namely frame synchronized interrupt and FIFO interrupt. When is the frame synchronized interrupt generated? Is a segment generated after each frame is displayed?
In the interrupt function:
static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
{
struct s3c2410fb_info *fbi = dev_id;
void __iomem *irq_base = fbi->irq_base;
unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND);
if (lcdirq & S3C2410_LCDINT_FRSYNC) {
if (fbi->palette_ready)
s3c2410fb_write_palette(fbi);
writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND);
writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND);
}
return IRQ_HANDLED;
}
What is the purpose of writing these two pending registers? I did not see any corresponding introduction in the data sheet.
2. The framebuffer is implemented in FIFO mode and DMA mode. I still don't understand the content of DMA. I originally wanted to learn about DMA by learning fb.
3. The role of LCD palette: There are many colors, more than 256. But we selected 256 and put them in the palette, so that our screen displays only one of the limited 256 colors. The palette is equivalent to a small collection of colors.
4. The driver only implements a few functions, and I still don’t understand the specific implementation process of frambuffer.
5. What is the function of the function in static struct fb_ops my2440fb_ops?
6. After writing the framebuffer driver, how should it be tested? How should the application layer test function be written?
A simple test can be done with dd: dd if=/dev/zero of=/dev/fb0 bs=480 count=3200 clear screen
echo '1000' > /dev/tty0 is output directly to the screen. The driver of tty0 has already called fb0
Continued from: Detailed explanation of LCD driver (FrameBuffer) example development on S3C2440 (I)
4. FrameBuffer device driver example code:
①. Create the driver file: my2440_lcd.c, which is the most basic structure of the driver: the initialization and unloading part of the FrameBuffer driver and others, as follows:
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /*FrameBuffer device name*/ static char driver_name[] = "my2440_lcd"; /*Define a structure to maintain the variables used in each function in the driver program Don't look at the structure to define these members, you will understand when you see where each function uses them*/ struct my2440fb_var { int lcd_irq_no; /*Save LCD interrupt number*/ struct clk *lcd_clock; /*Save the LCD clock obtained from the platform clock queue*/ struct resource *lcd_mem; /*LCD IO space*/ void __iomem *lcd_base; /*LCD IO space is mapped to the virtual address*/ struct device *dev; struct s3c2410fb_hw regs; /* represents 5 LCD configuration registers, s3c2410fb_hw is defined in mach-s3c2410/include/mach/fb.h*/ /*Define an array to act as a palette. According to the data sheet, when the TFT screen color bit mode is 8BPP, the length of the palette (color table) is 256, and the starting address of the palette is 0x4D000400*/ u32 palette_buffer[256]; u32 pseudo_pal[16]; unsigned int palette_ready; /*Identifies whether the palette is ready*/ }; /*Used as a clear palette (color table)*/ #define PALETTE_BUFF_CLEAR (0x80000000) /*LCD platform driver structure, the platform driver structure is defined in platform_device.h, the structure member interface function is implemented in step ②*/ static struct platform_driver lcd_fb_driver = { .probe = lcd_fb_probe, /*FrameBuffer device detection*/ .remove = __devexit_p(lcd_fb_remove), /*FrameBuffer device removal*/ .suspend = lcd_fb_suspend, /*FrameBuffer device suspend*/ .resume = lcd_fb_resume, /*FrameBuffer device resume*/ .driver = { /*Note that the name here must be consistent with the place where the platform device is defined in the system, so that the platform device can be associated with the driver of the platform device*/ .name = "s3c2410-lcd", .owner = THIS_MODULE, }, }; static int __init lcd_init(void) { /*In Linux, the frame buffer device is considered a platform device, so register the platform device here*/ return platform_driver_register(&lcd_fb_driver); } static void __exit lcd_exit(void) { /*Unregister platform device*/ platform_driver_unregister(&lcd_fb_driver); } module_init(lcd_init); module_exit(lcd_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Huang Gang"); MODULE_DESCRIPTION("My2440 LCD FrameBuffer Driver"); ②、Implementation of various interface functions of LCD platform equipment: /*Implementation of LCD FrameBuffer device detection. Note that a __devinit macro is used here. The implementation of the lcd_fb_remove interface function is explained here*/ static int __devinit lcd_fb_probe(struct platform_device *pdev) { int i; int ret; struct resource *res; /*Used to save LCD resources obtained from LCD platform device*/ struct fb_info *fbinfo; /*fb_info structure corresponding to the FrameBuffer driver*/ struct s3c2410fb_mach_info *mach_info; /*Save the platform device data obtained from the kernel*/ struct my2440fb_var *fbvar; /*Driver global variable structure defined above*/ struct s3c2410fb_display *display; /*LCD screen configuration information structure, the structure is defined in mach-s3c2410/include/mach/fb.h*/ /*Get LCD hardware related information data. As mentioned earlier, the kernel uses the s3c24xx_fb_set_platdata function to save LCD hardware related information to The LCD platform data, so here we take it out from the platform data and use it in the driver*/ mach_info = pdev->dev.platform_data; if (mach_info == NULL) { /*Judge whether the data acquisition is successful*/ dev_err(&pdev->dev, "no platform data for lcdn"); return -EINVAL; } /*Get the LCD configuration information structure data of the FrameBuffer platform device defined in the kernel*/ display = mach_info->displays + mach_info->default_display; /* Allocate space for fb_info, the size is the memory of my2440fb_var structure, framebuffer_alloc is defined in fb.h and implemented in fbsysfs.c*/ fbinfo = framebuffer_alloc(sizeof(struct my2440fb_var), &pdev->dev); if(!fbinfo) { dev_err(&pdev->dev, "framebuffer alloc of registers failedn"); ret = -ENOMEM; goto err_noirq; } platform_set_drvdata(pdev, fbinfo);/*Reset the LCD platform device data to fbinfo so that it can be used in some subsequent functions*/ /*The purpose here is actually to point the member par of fb_info (note that it is a void type pointer) to the private variable structure fbvar here, The purpose is to retrieve the member par of fb_info in other interface functions so that the private variables here can continue to be used*/ fbvar = fbinfo->par; fbvar->dev = &pdev->dev; /*Get the LCD interrupt number from the system-defined LCD platform device resources, platform_get_irq is defined in platform_device.h*/ fbvar->lcd_irq_no = platform_get_irq(pdev, 0); if(fbvar->lcd_irq_no < 0) { /*Judge whether the interrupt number is obtained successfully*/ dev_err(&pdev->dev, "no lcd irq for platformn"); return -ENOENT; } /*Get the IO port resources used by the LCD platform device. Note that the IORESOURCE_MEM flag is consistent with the LCD platform device definition*/ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if(res == NULL) { /*Judge whether the resource acquisition is successful*/ dev_err(&pdev->dev, "failed to get memory region resourcen"); return -ENOENT; } /*Request the IO space occupied by the LCD IO port (note the difference between IO space and memory space), request_mem_region is defined in ioport.h*/ fbvar->lcd_mem = request_mem_region(res->start, res->end - res->start + 1, pdev->name); if(fbvar->lcd_mem == NULL) { /*Judge whether the application for IO space is successful*/ dev_err(&pdev->dev, "failed to reserve memory regionn"); return -ENOENT; } /*Map the IO space occupied by the LCD IO port to the virtual address of the memory. ioremap is defined in io.h Note: IO space can only be used after mapping, and the subsequent operations on virtual addresses are operations on IO space*/ fbvar->lcd_base = ioremap(res->start, res->end - res->start + 1); if(fbvar->lcd_base == NULL) { /*Judge whether the mapping virtual address is successful*/ dev_err(&pdev->dev, "ioremap() of registers failedn"); ret = -EINVAL; goto err_nomem; } /*Get the LCD clock from the platform clock queue. Why do we need to get this clock here? From the timing diagram of the LCD screen, the delay of various control signals All are related to the LCD clock. Some system clock definitions are in arch/arm/plat-s3c24xx/s3c2410-clock.c*/ fbvar->lcd_clock = clk_get(NULL, "lcd"); if(!fbvar->lcd_clock) { /*Judge whether the clock acquisition is successful*/ dev_err(&pdev->dev, "failed to find lcd clock sourcen"); ret = -ENOENT; goto err_nomap; } /*After the clock is acquired, it must be enabled before it can be used. clk_enable is defined in arch/arm/plat-s3c/clock.c*/ clk_enable(fbvar->lcd_clock);
Previous article:Analysis of MMC/SD card driver on s3c2440 (I)
Next article:LCD driver (FrameBuffer) development on S3C2440 (Part 1)
Recommended ReadingLatest update time:2024-11-23 21:08
- Popular Resources
- Popular amplifiers
- MCU C language programming and Proteus simulation technology (Xu Aijun)
- 100 Examples of Microcontroller C Language Applications (with CD-ROM, 3rd Edition) (Wang Huiliang, Wang Dongfeng, Dong Guanqiang)
- Power Integrated Circuit Technology Theory and Design (Wen Jincai, Chen Keming, Hong Hui, Han Yan)
- Installation and Testing of Analog Electronic Products (Edited by Chen Jingzhong and Tang Mingjun)
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Optimization of embedded system design based on MCU
- General Problems of Power Amplifier Circuits
- Build a laser tripwire alarm using the MSP430 LaunchPad
- Reprint
- About the calculation of msp430g2553
- Switching power supply testing "Five rules"
- [Sipeed LicheeRV 86 Panel Review] - 2 Burning Waft System Image
- CC2538EM Reference Design CC2538EM-RD
- Source Insight Open Issues
- Why do many domestic chip information require signing an NDA before obtaining it?