1、 LCD驱动学习
在 Linux
中应用程序最终也是通过操作
RGB LCD
的显存来实现在
LCD
上显示字符、图片等信息。在裸机中我们可以随意的分配显存,但是在 Linux
系统中内存的管理很严格,
显存是需要申请的,不是你想用就能用的
。而且因为虚拟内存的存在,驱动程序设置的显存和应用程序访问的显存要是同一片物理内存。为了解决上述问题,Framebuffer
诞生了,
Framebuffer
翻译过来就是帧缓冲
fb 是一种机制,将系统中所有跟显示有关的硬件以及软件集合起来,虚拟出一个
fb 设备
,当我们编写好
LCD
驱动以后会生成一个名为
/dev/fbX(X=0~n)
的设备,应用程序通过访问/dev/fbX
这个设备就可以访问
LCD。
LCD又分LCD控制器和具体屏幕参数,前者由厂家写好了,所以实际应用时我们只需要改后者
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display0>;
status = "okay";
/* 7寸1024*600 */
display0: display {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51200000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hback-porch = <140>;
hsync-len = <20>;
vback-porch = <20>;
vfront-porch = <12>;
vsync-len = <3>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
/* 4.3寸480*272 */
/* display0: display {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <9000000>;
hactive = <480>;
vactive = <272>;
hfront-porch = <5>;
hback-porch = <40>;
hsync-len = <1>;
vback-porch = <8>;
vfront-porch = <8>;
vsync-len = <1>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};*/
/* 4.3寸800*480 */
/* display0: display {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <31000000>;
hactive = <800>;
vactive = <480>;
hfront-porch = <40>;
hback-porch = <88>;
hsync-len = <48>;
vback-porch = <32>;
vfront-porch = <13>;
vsync-len = <3>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};*/
};
backlight {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
=========================================================================
将屏幕设置为终端 (要注意,方便后期改回来)
此时有两个终端,各干各的 并不同步
只删console=tty1,剩下的不用
2、RTC驱动学习(字符设备驱动)
RTC 也就是实时时钟,用于记录当前系统时间,对于 Linux 系统而言时间是非常重要的, 就和我们使用 Windows 电脑或手机查看时间一样,我们在使用 Linux 设备的时候也需要查看时间。
Linux 内核将
RTC
设备抽象为
rtc_device 结构体
,因此
RTC
设备驱动就是申请并初始化rtc_device,最后将
rtc_device
注册到
Linux
内核里面,这样
Linux
内核就有一个
RTC
设备的。 至于 RTC
设备的操作肯定是用一个操作集合
(
结构体
)
来表示的,我们先来看一下
rtc_device
结构体,此结构体定义在
include/linux/rtc.h
文件中
我们需要重点关注的是
ops 成员变量
,这是一个
rtc_class_ops
类型的指针变量,
rtc_class_ops 为 RTC
设备的最底层操作函数集合,包括从
RTC
设备中读取时间、向
RTC
设备写入新的时间 值等。因此,rtc_class_ops
是需要用户根据所使用的
RTC
设备编写的,此结构体定义在
include/linux/rtc.h
文件中,内容如下:
(读时间,设置时间,读定时,设置定时)
看名字就知道 rtc_class_ops
操作集合中的这些函数是做什么的了,但是我们要注意,
rtc_class_ops
中的这些函数只是最底层的
RTC
设备操作函数,并不是提供给应用层的 file_operations 函数操作集。
RTC
是个字符设备,那么肯定有字符设备的
file_operations
函数操 作集,Linux
内核提供了一个
RTC
通用字符设备驱动文件,文件名为
drivers/rtc/rtc-dev.c
,
rtc
dev.c
文件提供了所有
RTC
设备共用的
file_operations
函数操作集,
当 rtc_class_ops
准备好以后需要将其
注册
到
Linux
内核中,这里我们可以使用
rtc_device_registe
r函数完成注册工作。此函数会申请一个
rtc_device
并且初始化这个
rtc_device
,最后向调用者返回这个 rtc_device
当
卸载
RTC
驱动的时候需要调用
rtc_device_unregister
函数来注销注册的
rtc_device
,函数原型如下:
arm-linux-gnueabihf-gcc zhang.c -o zhang
sudo cp zhang /home/whz/linux/nfs/rootfs/lib/modules/4.1.15/ -f
date //查看时间
date -s "2022-09-05 19:54:00" //设置时间