1. Development Environment
Compiler: arm-linux-gcc-4.3.22. Background knowledge
VSYNC/VFRAME/STV: vertical synchronization signal (TFT)/frame synchronization signal (STN)/SEC TFT signal;
HSYNC/VLINE/CPV: horizontal synchronization signal (TFT)/line synchronization pulse signal (STN)/SEC TFT signal;
VCLK/LCD_HCLK: pixel clock signal (TFT/STN)/SEC TFT signal;
VD[23:0]: LCD pixel data output port (TFT/STN/SEC TFT);
VDEN/VM/TP: data enable signal (TFT)/LCD drive AC bias signal (STN)/SEC TFT signal;
LEND/STH: line end signal (TFT)/SEC TFT signal;
LCD_LPCOE: SEC TFT OE signal;
LCD_LPCREV: SEC TFT REV signal;
LCD_LPCREVB: SEC TFT REVB signal.
A: The display pointer starts from the first point of the first row in the upper left corner of the rectangle, and is displayed on the LCD one by one. The timeline in the above timing diagram is VCLK, which we call the pixel clock signal;
B: When the display pointer is displayed to the right side of the rectangle, the line ends, and the action of this line is called 1 Line in the above timing diagram;
C: Then the display pointer returns to the left side of the rectangle and starts to display from the second line. Note that it takes a certain amount of time for the display pointer to return from the right side of the first line to the left side of the second line. We call it line switching;
D: And so on, the display pointer is displayed line by line to the lower right corner of the rectangle to complete the display of a picture. Therefore, the display of these lines on the timeline is HSYNC on the timing diagram;
E: However, the display of LCD is not a quick display of an image. In order to display it continuously and stably on the LCD, it is necessary to switch to another picture (the other picture can be the same or different from the previous picture, the purpose is just to display the image continuously on the LCD). Then these images are called frames, which are represented as 1 Frame on the timing diagram. Therefore, it can be seen from the timing diagram that 1 Line is just a line in 1 Frame;
F: Similarly, it takes a certain amount of time to switch between frames, which we call frame switching. Then the entire LCD display process can be represented as VSYNC on the timing diagram when viewed on the timeline.
VBPD (vertical back porch): indicates the number of invalid rows after the vertical synchronization signal at the beginning of a frame of image, corresponding to the upper_margin in the driver;
VFBD (vertical front porch): indicates the number of invalid rows before the vertical synchronization signal after the end of a frame of image, corresponding to the lower_margin in the driver;
VSPW (vertical sync pulse width): indicates the width of the vertical synchronization pulse, calculated by the number of rows, corresponding to the vsync_len in the driver;
HBPD (horizontal back porch): indicates the number of VCLKs from the start of the horizontal synchronization signal to the start of valid data of a row, corresponding to the left_margin in the driver;
HFPD (horizontal front porth): indicates the number of VCLKs from the end of valid data of a row to the start of the next horizontal synchronization signal, corresponding to the right_margin in the driver;
HSPW (horizontal sync pulse width): indicates the width of the horizontal synchronization signal, calculated by VCLK, corresponding to the hsync_len in the driver;
LCDCON1: 17 - 8-bit CLKVAL
6 - 5-bit scan mode (for STN screen: 4-bit single/dual scan, 8-bit single scan)
4 - 1-bit color mode (1BPP, 8BPP, 16BPP, etc.)
LCDCON2: 31 - 24-bit VBPD
23 - 14-bit LINEVAL
13 - 6-bit VFPD
5 - 0-bit VSPW
LCDCON3: 25 - 19-bit HBPD
18 - 8-bit HOZVAL
7 - 0-bit HFPD
LCDCON4: 7 - 0-bit HSPW
LCDCON5:
1. The structure of the frame buffer device driver in the Linux subsystem is as follows:
From the above picture, we can see that the frame buffer device can also be regarded as a complete subsystem in Linux, which is roughly composed of fbmem.c and xxxfb.c. It provides a complete device file operation interface to the application upward (that is, read, write, ioctl and other operations on the FrameBuffer device), which is implemented in the fbmem.c file provided by Linux; it provides a hardware operation interface downward, but Linux does not provide implementation for these interfaces, because this needs to be set according to the specific LCD controller hardware, so this is what we have to do (that is, the implementation of the xxxfb.c part).
2. Important data structures related to frame buffer:
From the perspective of the frame buffer device driver structure, the driver is mainly related to the fb_info structure, which records all the information of the frame buffer device, including the device's setting parameters, status, and function pointers to the underlying hardware operations. In Linux, each frame buffer device must correspond to an fb_info. The definition of fb_info in /linux/fb.h is as follows: (Only some important ones are listed)
struct fb_info {
int node;
int flags;
struct fb_var_screeninfo var;/*LCD variable parameter structure*/
struct fb_fix_screeninfo fix;/*LCD fixed parameter structure*/
struct fb_monspecs monspecs;/*LCD display standard*/
struct work_struct queue;/*Frame buffer event queue*/
struct fb_pixmap pixmap; /*Image hardware mapper*/
struct fb_pixmap sprite; /*Cursor hardware mapper*/
struct fb_cmap cmap; /*Current color table*/
struct fb_videomode *mode;/*Current display mode*/
#ifdef CONFIG_FB_BACKLIGHT
struct backlight_device *bl_dev
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS]
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct fb_ops *fbops
struct device *device;
struct device *dev;/*fb device*/
int class_flag;
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops; /*Blitting*/
#endif
char __iomem *screen_base;/*virtual base address*/
unsigned long screen_size;/*LCD IO mapped virtual memory size*/
void *pseudo_palette;/*pseudo 16-color color table*/
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state;/*LCD suspend or resume state*/
void *fbcon_par;
void *par;
};
Among them, the more important members are struct fb_var_screeninfo var, struct fb_fix_screeninfo fix and struct fb_ops *fbops, which are also structures. Let's look at them one by one.
The fb_var_screeninfo structure mainly records the controller parameters that can be modified by the user, such as the screen resolution and the number of bits per pixel. The structure is defined as follows:
struct fb_var_screeninfo {
__u32 xres;/*How many pixels are there in one row of the visible screen*/
__u32 yres;/*How many pixels are there in one column of the visible screen*/
__u32 xres_virtual;/*How many pixels are there in one
row of the virtual screen*/ __u32 yres_virtual;/*How many pixels are there in one column
of the virtual screen*/ __u32 xoffset;/
*Row offset between virtual and visible screen*/ __u32 yoffset;/*Column offset between virtual and visible screen*/
__u32 bits_per_pixel;/*Number of bits per pixel, i.e. BPP*/
__u32 grayscale;/*When not 0, it refers to grayscale*/
struct fb_bitfield red;/*R bit field of fb cache*/
struct fb_bitfield green;/*G bit field of fb cache*/
struct fb_bitfield blue;/*B bit field of fb cache*/
struct fb_bitfield transp;/*Transparency*/
__u32 nonstd;/* != 0 non-standard pixel format*/
__u32 activate;
__u32 height;/*Height*/
__u32 width;/*Width*/
__u32 accel_flags;
/*Timing: Except for pixclock itself, all other units are in pixel clock*/
__u32 pixclock;/*Pixel clock (picoseconds)*/
__u32 left_margin;/*Line switching, delay from synchronization to drawing*/
__u32 right_margin;/*Line switching, delay from drawing to synchronization*/
__u32 upper_margin;/*Frame switching, delay from synchronization to drawing*/
__u32 lower_margin;/*Frame switching, delay from drawing to synchronization*/
__u32 hsync_len;/*Horizontal synchronization length*/
__u32 vsync_len;/*Vertical synchronization length*/
__u32 sync;
__u32 vmode;
__u32 rotate;
__u32 reserved[5];/*reserved*/
};
The fb_fix_screeninfo structure mainly records the controller parameters that cannot be modified by the user, such as the physical address and length of the screen buffer. The definition of the structure is as follows:
struct fb_fix_screeninfo {
char id[16];/*identifier in string form*/
unsigned long smem_start;/*start position of fb cache*/
__u32 smem_len;/*length of fb cache*/
__u32 type;/*see FB_TYPE_* */
__u32 type_aux;/*demarcation*/
__u32 visual;/*see FB_VISUAL_* */
__u16 xpanstep;/*if there is no hardware panning, assign it to 0 */
__u16 ypanstep;/*if there is no hardware panning, assign it to 0 */
__u16 ywrapstep;/*if there is no hardware ywrap, assign it to 0 */
__u32 line_length;/*number of bytes in a line*/
unsigned long mmio_start;/*start position of memory mapped IO*/
__u32 mmio_len;/*length of memory mapped IO*/
__u32 accel;
__u16 reserved[3];/*reserved*/
};
Among them, the more important members are struct fb_var_screeninfo var, struct fb_fix_screeninfo fix and struct fb_ops *fbops, which are also structures. Let's look at them one by one.
The fb_var_screeninfo structure mainly records the controller parameters that can be modified by the user, such as the screen resolution and the number of bits per pixel. The structure is defined as follows:
struct fb_var_screeninfo {
__u32 xres;/*How many pixels are there in one row of the visible screen*/
__u32 yres;/*How many pixels are there in one column of the visible screen*/
__u32 xres_virtual;/*How many pixels are there in one
row of the virtual screen*/ __u32 yres_virtual;/*How many pixels are there in one column
of the virtual screen*/ __u32 xoffset;/
*Row offset between virtual and visible screen*/ __u32 yoffset;/*Column offset between virtual and visible screen*/
__u32 bits_per_pixel;/*Number of bits per pixel, i.e. BPP*/
__u32 grayscale;/*When not 0, it refers to grayscale*/
struct fb_bitfield red;/*R bit field of fb cache*/
struct fb_bitfield green;/*G bit field of fb cache*/
struct fb_bitfield blue;/*B bit field of fb cache*/
struct fb_bitfield transp;/*Transparency*/
__u32 nonstd;/* != 0 non-standard pixel format*/
__u32 activate;
__u32 height;/*Height*/
__u32 width;/*Width*/
__u32 accel_flags;
/*Timing: Except for pixclock itself, all other units are in pixel clock*/
__u32 pixclock;/*Pixel clock (picoseconds)*/
__u32 left_margin;/*Line switching, delay from synchronization to drawing*/
__u32 right_margin;/*Line switching, delay from drawing to synchronization*/
__u32 upper_margin;/*Frame switching, delay from synchronization to drawing*/
__u32 lower_margin;/*Frame switching, delay from drawing to synchronization*/
__u32 hsync_len;/*Horizontal synchronization length*/
__u32 vsync_len;/*Vertical synchronization length*/
__u32 sync;
__u32 vmode;
__u32 rotate;
__u32 reserved[5];/*reserved*/
};
The fb_fix_screeninfo structure mainly records the controller parameters that cannot be modified by the user, such as the physical address and length of the screen buffer. The definition of the structure is as follows:
struct fb_fix_screeninfo {
char id[16];/*identifier in string form*/
unsigned long smem_start;/*start position of fb cache*/
__u32 smem_len;/*length of fb cache*/
__u32 type;/*see FB_TYPE_* */
__u32 type_aux;/*demarcation*/
__u32 visual;/*see FB_VISUAL_* */
__u16 xpanstep;/*if there is no hardware panning, assign it to 0 */
__u16 ypanstep;/*if there is no hardware panning, assign it to 0 */
__u16 ywrapstep;/*if there is no hardware ywrap, assign it to 0 */
__u32 line_length;/*number of bytes in a line*/
unsigned long mmio_start;/*start position of memory mapped IO*/
__u32 mmio_len;/*length of memory mapped IO*/
__u32 accel;
__u16 reserved[3];/*reserved*/
};
The fb_ops structure is a function pointer to the underlying hardware operations. The operations on the hardware are defined in this structure: (only the commonly used operations are listed here)
struct fb_ops {
struct module *owner;
//Check variable parameters and set them
int (*fb_check_var)(struct fb_var_screeninfo *var, struct fb_info *info);
//Update according to the set value to make it effective
int (*fb_set_par)(struct fb_info *info);
//Set color register
int (*fb_setcolreg)(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp, struct fb_info *info);
//Display blank
int (*fb_blank)(int blank, struct fb_info *info);
//Rectangular filling
void (*fb_fillrect) (struct fb_info *info, const struct fb_fillrect *rect);
//Copy data
void (*fb_copyarea) (struct fb_info *info, const struct fb_copyarea *region);
//Graphic filling
void (*fb_imageblit) (struct fb_info *info, const struct fb_image *image);
};
3. Frame buffer device as platform device:
In S3C2440, the LCD controller is integrated into the chip as a relatively independent unit, so Linux regards it as a platform device. Therefore, LCD-related platform devices and resources are defined in the kernel code /arch/arm/plat-s3c24xx/devs.c. The code is as follows:
/* LCD Controller */
//LCD controller resource information
static struct resource s3c_lcd_resource[] = {
[0] = {
.start = S3C24XX_PA_LCD
}
};
static u64 s3c_device_lcd_dmamask = 0xffffffffUL;
struct platform_device s3c_device_lcd = {
.name = "s3c2410-lcd"
.id = -1,
.num_resources = ARRAY_SIZE(s3c_lcd_resource)
.dev = {
.dma_mask = &s3c_device_lcd_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};
EXPORT_SYMBOL(s3c_device_lcd)
In addition, Linux also defines a s3c2410fb_mach_info structure for the LCD platform device in /arch/arm/mach-s3c2410/include/mach/fb.h. This structure mainly records the hardware parameter information of the LCD (for example, the s3c2410fb_display member structure of the structure is used to record the LCD screen size, screen information, variable screen parameters, LCD configuration registers, etc.), so this structure can be used directly when writing the driver. Next, let's see how the kernel uses this structure. It is defined in /arch/arm/mach-s3c2440/mach-smdk2440.c:
/* LCD driver info */
//LCD hardware configuration information. Note that the LCD I use here is a NEC 3.5-inch TFT screen. These parameters should be set according to the specific LCD screen.
static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
//The setting here is to configure LCD register 5. These macros are defined in regs-lcd.h. The binary value after calculation is: 111111111111. Then compare the bits of LCDCON5 in the data sheet. Note that it starts from the right
. lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN |
S3C2410_LCDCON5_HWSWP,
.type = S3C2410_LCDCON1_TFT
//The following parameters have been mentioned in the above timing diagram analysis. Please set the values of each parameter according to the specific LCD screen data sheet combined with the above timing analysis
};
static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
.displays = &smdk2440_lcd_cfg
.num_displays = 1,
.default_display = 0,
.gpccon = 0xaaaa555a
.gpccon_mask = 0xffffffff,
.gpcup = 0x0000ffff
.gpcup_mask = 0xffffffff,
.gpdcon = 0xaaaaaaa
.gpdcon_mask = 0xffffffff,
.gpdup = 0x0000ffff
.gpdup_mask = 0xffffffff,
.lpcsel = 0x0
};
Note: Many friends may not know what the parameters in the red part above are for, and how to set their values? In fact, it is closely related to your development board LCD controller. I believe you will know what they are used for after looking at the following two pictures:
The first picture above is the LCD controller part of the development board schematic, and the second picture is the IO port C and IO port D controller part in the S3c2440 data sheet. In the schematic, GPC8-15 and GPD0-15 are used as the data ports of the LCD controller VD0-VD23, and GPC0 and GPC1 ports are used as the LEND and VCLK signals of the LCD controller, respectively. For GPC2-7, they are used as the related signals of STN screen or Samsung professional TFT screen. However, the various IO ports of S3C2440 are not single functions, but multiplexed ports. To use them, they must be configured first. Therefore, the parameters in the red part above are to configure some ports of GPC and GPD into LCD control function mode.
From the above, it can be seen that in order to make the LCD controller support other LCD screens, it is important to modify the values of the above parameters according to the LCD data sheet. Next, let's take a look at how to reference the s3c2410fb_mach_info structure in the driver (note that the above is how to use it in the kernel). In mach-smdk2440.c, there is:
//S3C2440 initialization function
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
s3c24xx_fb_set_platdata is defined in plat-s3c24xx/devs.c:
void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
struct s3c2410fb_mach_info *npd;
npd = kmalloc(sizeof(*npd), GFP_KERNEL);
if (npd) {
memcpy(npd, pd, sizeof(*npd));
//Here is to save the s3c2410fb_mach_info structure data defined in the kernel to the LCD platform data, so when writing the driver, you can directly get the data of the s3c2410fb_mach_info structure (that is, various LCD parameter information) in the platform data for operation
s3c_device_lcd.dev.platform_data = npd;
} else {
printk(KERN_ERR "no memory for LCD platform data\n");
}
}
Here is another little knowledge: I wonder if you have noticed that in the platform device driver, platform_data can save the data of each platform device instance, but the types of these data are different. Why can they all be saved? To understand this, we need to look at the definition of platform_data, which is defined in /linux/device.h. void *platform_data is a void type pointer. In Linux, void can save any data type.
Previous article:Pseudo-operations in ARM assembly language (I)
Next article:LCD driver (FrameBuffer) example development explanation on S3C2440 (Part 2)
Recommended ReadingLatest update time:2024-11-16 20:24
- 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)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- [Sipeed LicheeRV 86 Panel Review] The board is not responding
- Use stm32l452 to drive hts221 and stts751 routine
- [National Technology N32WB452 Review] + Basic Function Usage
- Will demand for SiC FETs increase in the future?
- Problems with pressure maintenance of testing machine
- Testing a battery-powered product with a 26K resistor between the battery pads (no battery is soldered at this time!),...
- When TMS320F28377D runs CLA, it shows that Cla1Task2 does not contain frame information
- Application and precautions of Hall elements
- Which one is better to use, the Type-C interface or the MicroUSB interface for mobile phone data cables?
- Showing goods + development board and multimeter