基于imx6ull的LCD驱动移植

移植思路:

LCD除了显示之外,它的表面通常还贴有一个触摸屏。

所以我们移植的是2个设备的驱动:LCD、触摸屏。

LCD驱动在内核中已经有了,并且很完善,我们只需要修改设备树就可以:修改时序等LCD参数,修改背光引脚等板子参数。

触摸屏的驱动在内核中一般也有了,各厂家用的触摸屏IC可能不同,需要配置内核把它加进去,同时修改设备树:指定触摸IC的信息(比如I2C地址),指定中断引脚。

如果能拿到这块LCD在别的板子上的内核源码,就可以参考它的LCD参数、触摸IC信息。

再结合你用的开发板,把涉及的GPIO找出来写入设备树。

移植LCD驱动:

注意:100ASK_IMX6ULL不能直接连接其他厂家的屏,需要转接板。

MX6ULL跟LCD的连接框图如下:

               

IMX6ULL内部有LCD控制器,肯定是厂家对这个LCD控制器最熟悉了,所以他们为了卖芯片,一般都会在内核中做好LCD控制器的驱动程序。

而IMX6ULL可以接各种LCD,这些LCD参数各有不同。LCD控制器的驱动程序会去设备树中获得这些参数,并根据这些参数来设置LCD控制器。

所以,我们要做的事情从理论上讲很简单:根据LCD参数修改设备树。

但是,谁说厂家的驱动就没有BUG,就完美无缺了?

我们要做的事有3项:确定LCD参数,修改设备树,完善驱动。

一、确定LCD参数

如果还保留有LCD的芯片手册,这是最好的。野火的屏在板子背后直接写明分辨率是多少,这比较简单直接。如果是从零开发,我们还需要找到芯片手册确定LCD的详细时序。

我们没有LCD的手册,即使有也懒得看。

直接看厂家的源码不就行了?直接点,直接看它的设备树不就行了?

找到LCD厂家的IMX6ULL内核源码,执行以下命令:

$ cd  arch/arm/boot/dts/
$ ls  *imx6ull*.dts

可以找到2个设备树文件,我们只关心里面的LCD信息,打开任意一个看看:

这些时序参数描述了一个 LCD 的基本时序信息。让我们逐个解释:

  • clock-frequency = <50000000>;:像素时钟的频率,这里是 50 MHz。

  • hactive = <1024>;:水平方向的有效像素数,这里是 1024 个像素。

  • vactive = <600>;:垂直方向的有效像素数,这里是 600 行像素。

  • hfront-porch = <160>;:水平前沿的时钟周期数,即行同步信号之后到数据有效期之前的周期数,这里是 160 个时钟周期。

  • hback-porch = <140>;:水平后沿的时钟周期数,即数据有效期结束到行同步信号之前的周期数,这里是 140 个时钟周期。

  • hsync-len = <20>;:水平同步脉冲的持续时间,这里是 20 个时钟周期。

  • vback-porch = <20>;:垂直后沿的行数,即垂直同步信号之后到数据有效期之前的行数,这里是 20 行。

  • vfront-porch = <12>;:垂直前沿的行数,即数据有效期结束到垂直同步信号之前的行数,这里是 12 行。

  • vsync-len = <3>;:垂直同步脉冲的持续时间,这里是 3 行。

  • hsync-active = <0>;:水平同步信号的极性,这里是低电平有效。

  • vsync-active = <0>;:垂直同步信号的极性,这里是低电平有效。

  • de-active = <1>;:数据使能信号的极性,这里是高电平有效。

  • pixelclk-active = <0>;:像素时钟信号的极性,这里是低电平有效。

这些参数描述了 LCD 显示信号的时序和极性,以确保 LCD 控制器能够正确地驱动 LCD 屏幕。

二、修改设备树

100ASK_IMX6ULL用的内核版本是4.9.88,版本高一点,但是IMX6ULL设备树的写法完全一样。

设备树文件是arch/arm/boot/dts/100ask_imx6ull-14x14.dts,替换下图红框部分:

修改好设备树后,就可以编译了。将编译得到的设备树文件放在开发板的boot目录下,更新设备树后,重启板子观察效果。

三、完善驱动

使用新的设备树启动板子后,你会发现一个神奇的现象:LCD有时候有显示,有时候没有,不断地冷启动偶尔会有显示。

如果你经验丰富,可以判断这是没办法正确初始化或配置,是复位问题

为验证是否复位问题,我们可以执行命令手工发出复位信号,先确定LCD复位引脚是哪个GPIO:

从上图可以确定LCD的复位引脚用到GPIO3_IO04,那我们可以使用GPIO子系统来验证。

执行某些命令让GPIO输出低电平,再输出高电平,这样就可以复位LCD了。

使用GPIO子系统复位LCD

GPIO3_IO04在GPIO子系统中编号为:(3-1)*32+4=68,它是第68号GPIO。板子进入Linux后,执行以下命令:

$ fb-test                                          // LCD上应该显示红绿蓝色块
$ echo  68 > /sys/class/gpio/export                  // 导出68号GPIO
$ echo out > /sys/class/gpio/gpio68/direction          // 设置为输出引脚
$ echo 0 > /sys/class/gpio/gpio68/value              // 让它输出0
$ echo 1 > /sys/class/gpio/gpio68/value              // 让它输出1
$ echo  68 > /sys/class/gpio/unexport               // unexport

你会发现一旦执行上述命令,LCD立刻就有显示了。

所以,LCD驱动不完善,应该加上复位信号。

修改设备树:指定复位引脚

设备树文件为:arch/arm/boot/dts/100ask_imx6ull-14x14.dts

如下图修改:

修改驱动:复位LCD

LCD驱动程序是哪个?

在Linux内核源码目录下执行命令:

fbdev 是 Linux 内核中用于管理 Framebuffer 设备的子系统。它提供了一组接口和数据结构,用于操作和管理 Framebuffer 设备,包括图形显示的配置、内存管理、绘图操作等。

$ ls drivers/video/fbdev/*.o
drivers/video/fbdev/built-in.o  drivers/video/fbdev/mx3fb.o  drivers/video/fbdev/mxsfb.o

发现有2个.o文件:mx3fb.o、mxsfb.o。我们是imx6ull,应该是后者。mx3fb.o 可能是针对 i.MX 3 系列芯片的 Framebuffer 驱动程序,而 mxsfb.o 可能是针对 i.MX 6/7 系列芯片的 Framebuffer 驱动程序。

我们在mxsfb.c中mxsfb_probe函数的后面添加复位代码,如下图修改:

/* 100ask */printk("100ask, %s %s %d\n", __FILE__, __FUNCTION__, __LINE__);rst_gpio = of_get_named_gpio(pdev->dev.of_node, "reset-gpios", 0);if (gpio_is_valid(rst_gpio)) {ret = gpio_request(rst_gpio, "lcdif_rst");if (ret < 0) {dev_err(&pdev->dev,"Failed to request GPIO:%d, ERRNO:%d\n",(s32)rst_gpio, ret);} else {gpio_direction_output(rst_gpio, 0);msleep(2);gpio_direction_output(rst_gpio, 1);dev_info(&pdev->dev,  "Success seset LCDIF\n");}}

修改完后,重新编译得到zImage和100ask_imx6ull-14x14.dtb,更新开发板,重启完成

移植触摸屏驱动

一、确定触摸屏型号

还是那句话,如果有触摸屏数据手册,看手册就好了。

如果没有手册,怎么办?

触摸屏的主控芯片一般都是I2C接口的,那么我们可以把屏接到板子上,用i2cdetect检测出I2C设备的地址,根据地址就可以知道它的型号。

注意:100ASK_IMX6ULL不能直接连接其他厂家的屏,需要转接板。

接上屏幕后,启动开发板进入Linux,执行如下命令:

[root@imx6ull:~]# i2cdetect -y 1

命令解析:“-y”表示 Disable interactive mode,简单地说就是“别让我确认了,赶紧执行”;“1”表示I2C总线1(从0开始)。这个命令是在查找连接到 I2C 总线1上的设备。在命令输出中,每行代表 I2C 地址,每列代表一个地址中的设备是否存在。如果某个地址的设备存在,会显示其地址;如果不存在,会显示 "--"。

结果如下:

上图中,

“--”表示没有这个地址对应的I2C设备;

“UU”表示这个地址的I2C设备已经有驱动在使用占用它了,那这个I2C设备肯定是存在的;

其他数值表示该地址对应的I2C设备是存在的,并且还没有驱动程序跟它匹配。

根据上图,我们可以知道0x38就是触摸屏设备,为什么!为什么不是0x60?你可以把屏幕取下,再重新执行命令,就可以看到“38”消失了。

根据0x38,我们得找到对应的芯片型号,怎么找?去内核设备树目录里找。

$ cd arch/arm/boot/dts/
$ grep "@38" * -nR

可以得到很多结果,比如:

地址为0x38的I2C芯片有不少,比如HDMI PHY,还有ft5306、ft5x06。你在百度搜一下“ft5306”,它确实就是触摸屏芯片。所以这款触摸屏的主控芯片就是ft5x06。x表示某些数字,可能有多个型号,我们暂时没不用去细分。

二、在设备树中指定触摸IC信息

IMX6ULL跟触摸IC的连接图如下:

所以,我们要确定的信息是:

a. 它接在哪个I2C控制器上?

b. 它的I2C地址是?

c. 复位引脚使用哪个GPIO?低电平有效还是高电平有效?

d. 中断引脚使用哪个GPIO?低电平有效还是高电平有效?

不知道怎么写?没关系,参考!

a. 对于ft5x06,设备树节点中有哪些内容?

b. 那些内容怎么适配100ASM_IMX6ULL板子?即怎么改成100ASK_IMX6ULL所用的GPIO引脚

前面说过,根据I2C设备的地址0x38,执行如下命令:

$ cd arch/arm/boot/dts/

$ grep "@38" * -nR

我们可以得到很多结果,打开跟imx6ull最相近的imx6ul-tx6ul.dtsi,可以看到如下代码:

我们把这个结点的内容先复制下来,粘贴到哪里去?

100ASK_IMX6ULL也配有触摸屏,我们用的型号是gt9xx,把这个结点放到gt9xx结点相同位置去就可以了,如下图所示:

100ASK_IMX6ULL接标配的LCD时,触摸IC是gt9xx,用的引脚假设是 AAA;

那么同一个底板接上另一块LCD时,虽然触摸IC型号不同,但是它仍然用的是同一个引脚AAA。

所以,新加的节点,其内容可以参考gt9xx节点的内容。

下图就是改好的样子:

重新编译设备树,更新到板子上,发现触摸屏还是不能用。

这还得往内核里加驱动。

三、配置内核修改驱动

这设备节点对应哪个驱动啊?它有这个属性:

compatible = "edt,edt-ft5x06"

在内核drivers/input/touchscreen目录下搜搜"edt,edt-ft5x06":

$ grep "edt,edt-ft5x06" * -nr

什么都没搜到,再搜“edt-ft5x06”:

$ grep "edt-ft5x06" * -nr
edt-ft5x06.c:1071:      { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
Kconfig:667:      module will be called edt-ft5x06.
Makefile:31:obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06)        += edt-ft5x06.o

第二行显示驱动程序是“edt-ft5x06”,第四行显示内核配置项是CONFIG_TOUCHSCREEN_EDT_FT5X06。这行命令出现在 Makefile 中的第 31 行,它的作用是根据内核配置选项 CONFIG_TOUCHSCREEN_EDT_FT5X06 来决定是否将 edt-ft5x06.o 加入到编译目标中。

具体来说,obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o 这一行告诉 Make 工具:如果配置选项 CONFIG_TOUCHSCREEN_EDT_FT5X06 被启用(即被设置为 y 或者 m),那么将 edt-ft5x06.o 加入到目标中。否则,如果该选项未启用(即被设置为 n),则忽略这个文件。

这样的设计通常用于根据用户的内核配置选项来选择性地编译某些驱动程序或功能模块,以便根据需求和硬件配置来优化内核的大小和功能。

所以我们需要配置内核,去把CONFIG_TOUCHSCREEN_EDT_FT5X06配置为y。

在内核目录下执行“make  menuconfig”,menuconfig:文本界面的配置工具,通过终端运行 make menuconfig 命令来启动,然后ctrl+“/”搜索“CONFIG_TOUCHSCREEN_EDT_FT5X06”,提示名就是我们要置y的配置文件

在菜单里找到它,把它配置为y,如下图:

重新编译内核zImage,更新到板子上,启动。

发现触摸屏有反应,但是点不准,还得调试。

四、调试:找出问题

Tslib是触摸屏的库,自带有很多工具:

        a. ts_print_raw :打印触摸屏原始数据

        b. ts_print :打印经过较准的数据

        c. ts_test_mt:测试电容屏,点击触摸屏,同时就会在LCD上显示触点位置

我们先把系统自带的QT系统去掉,在开发板执行:

# mv /etc/init.d/S07hmi  /root/

# reboot

然后设置环境变量,执行ts_test_mt:

export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=/usr/lib/ts
ts_test_mt

可以在LCD屏幕上看到提示,你点击某个位置,正常的话在该位置就会显示一个标号。

我们发现有意思的现象:从左往右点,标号从上边移动到下边;从上往下点,标号从左边移动到右边。

猜测:XY坐标对调了。

再试一下,执行 ts_print_raw,然后从左往右点,现象如下:

从左往右点,x坐标应该发生变化,y坐标保持不变;但是从上图看来,这是相反的。

所以,确实是xy坐标对调了。

五、解决问题

可以从应用层面解决,也可以从驱动层面解决。二选一就好了,不要同时做。

应用层修改/etc/ts.conf

如下图加上xyswap就可以了:

驱动层修改设备树:

有时候我们并不愿意、不能修改应用层的东西,那可以修改设备树:

六、其他情况

100ASK_IMX6ULL标配的屏,带的触摸IC是gt9xx;但是别家的LCD即使同样使用gt9xx,但是它的xy值是反转的。

什么意思呢?

你从左往右点,正常来说x值是从小变大,但是有些屏是从大变小。

你从上往下点,正常来说y值是从小变大,但是有些屏是从大变小。

这时候,你同样可以修改设备树,或是修改/etc/ts.conf。

怎么修改设备树?

参考内核文档:Documentation/devicetree/bindings/input/touchscreen,该目录下有很多I2C触摸芯片的设备树说明,比如有goodix.txt,对应gt9xx芯片;有edt-ft5x06.txt。

要让x反转,或是y反转,在设备节点中加入这样的属性值就可以:

touchscreen-inverted-x = <1>;

touchscreen-inverted-y = <1>;

有时为了测试方便,就是想临时改一下/etc/ts.conf,怎么做?

这个文件本身是有些注释的,可以参考:

“x0=1024”的意思就是:x坐标,0表示1024;

“y0=600”的意思是:y坐标,0表示600。

 gt9xx芯片固件更新

gt9xx芯片功能强大,可以写入配置信息让它支持不同分辨率的触摸屏。

但是出厂的触摸屏IC一般都已经写好配置信息了,我们不应该让驱动程序去修改这些配置信息。

可以在设备树中加上这一句,禁止驱动去修改配置信息:

goodix,driver-send-cfg = <0>;

这是我们调试过程中碰到的一个坑。

总结:

移植LCD驱动的同时也要触摸屏的驱动;

对于LCD驱动的移植

LCD的驱动在内核中很完善,驱动程序不用大改,只需要修改设备树,也就是修改硬件资源,根据具体的LCD屏幕修改参数。步骤为:

确定所用LCD屏幕的分辨率,找到LCD厂家的设备树文件源码,可以在dts中直接搜索display-timings或者时序参数关键词找到对应的LCD详细时序和信号极性,替换到自己的设备树文件对应位置中。因为有转接板的原因,引脚的设置就不改了,由转接板完成引脚对应工作,但要记得检查LCD复位引脚,可以查看imx6ull芯片手册确定LCD的复位引脚是哪一个IO口,在设备树中节点添加并添加复位驱动代码,避免出现LCD初始化启动问题。

关于驱动程序的内核配置也要检查一下,以免驱动不加载。检查方式是看驱动程序所在目录的Makefile里的对应宏有没有被定义也就是有没有被置y或m。在内核目录下执行Make menuconfig命令进入图像化界面,查找宏的路径并检查。

对于触摸屏的驱动移植

拿到一个触摸屏,要先知道它的数据,有手册看手册,没有的话就测试,触摸屏的主控芯片一般都是IIC接口的,那把屏幕接到板子上,在开发板Linux中,用i2cdetect可以检测出iic设备的地址,然后再dts目录下执行grep "@38" * -nR,可以看到所有dts文件中的地址为38的设备,要确定具体是哪一个,可以凭经验,也可以百度设备名。

对于设备树的修改,仿照其他地址为38的iic设备节点(从与开发板型号相似的dtsi文件中找)为基础模板,对比着开发板原配节点修改。虽然iic芯片不同,因为板子没变,所以用到的引脚也和原配的一样

根据节点compatible,在触摸屏驱动文件中搜索驱动文件,找到驱动之后也要配置内核,重新编译内核,更新内核,启动。

资料来源:http://wiki.100ask.net

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/825313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT国内怎么用

2022年11月&#xff0c;OpenAI发布了ChatGPT&#xff0c;这标志着大型语言模型在自然语言处理领域迈出了巨大的一步。ChatGPT不仅在生成文本方面表现出了惊人的流畅度和连贯性&#xff0c;更为人工智能应用开启了全新的可能性。 ChatGPT的推出促进了人工智能技术在多个领域的广…

No spring.config.import property has been defined

运行Springcloud项目出现下面错误&#xff1a; Description: No spring.config.import property has been defined Action: Add a spring.config.importnacos: property to your configuration. If configuration is not required add spring.config.importoptional:nac…

mac电脑mysql下载与安装

mysql下载地址 历史下载地址 MySQL :: Download MySQL Community Server (Archived Versions) mac 版下载 mac版本分为 Intel 处理器 和 M系列处理器。 从 8.0.26开始&#xff0c; mysql 支持M系列处理器。 以前的都只有Intel 处理器的。 Intel 处理器选择 x86_64 M 系列处理…

内置管线升级到SBP,如何复用之前打包的AssetBundle

1&#xff09;内置管线升级到SBP&#xff0c;如何复用之前打包的AssetBundle 2&#xff09;安卓真机&#xff0c;在Unity 2021.3.31版本下Buffer数据异常 3&#xff09;URP里CullResults.CreateSharedRendererScene下面的消耗 4&#xff09;移动端是否支持曲面细分着色 这是第3…

Seaborn:推荐一个好用的Python可视化工具

1. 引言 Seaborn 是建立在 matplotlib 基础上的数据可视化库&#xff0c;并与 Python 中的 pandas 数据结构紧密结合。可视化是 Seaborn 的核心部分&#xff0c;有助于直观的理解数据。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 安装 Seaborn库主要提供以下功能…

羊大师解析,夏天羊奶有什么搭配,可以解暑吗?

羊大师解析&#xff0c;夏天羊奶有什么搭配,可以解暑吗&#xff1f; 羊大师发现夏天羊奶的搭配方式多样&#xff0c;不仅可以提供丰富的营养&#xff0c;还有助于解暑。以下是一些推荐的搭配方式&#xff1a; 羊奶蜂蜜&#xff1a;蜂蜜的清甜口感可以改善羊奶的膻味&#xff…

学习笔记<2024.4.15-2024.4.21>:Attention Is All You Need

Transformer中Self-Attention以及Multi-Head Attention详解 (https://www.bilibili.com/video/BV15v411W78M/?spm_id_from333.337.search-card.all.click&vd_sourcef32decb03075b4a1833fe5c47c11ba94)

网络变压器(网络隔离变压器)是如何影响网通设备的传输速率的呢?

Hqst华轩盛(石门盈盛)电子导读&#xff1a;今天介绍网络变压器&#xff08;网络隔离变压器/网络滤波器&#xff09;是如何影响网通设备的传输速率的 一、网络变压器&#xff08;网络隔离变压器/网络滤波器&#xff09;的工作原理 网络变压器&#xff08;网络隔离变压器/网络滤…

【网络运维知识】—路由器与交换机区别

【网络运维知识】—路由器与交换机区别 一、路由器&#xff08;Router&#xff09;和交换机&#xff08;Switch&#xff09;对比1.1 功能1.2 转发方式1.3 范围1.4 处理方式 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 路由器&#xff08…

Xftp下载,安装与使用

1.下载网址 家庭/学校免费 - NetSarang Website (xshell.com) 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;jbgy 2.安装 3.使用 Linux终端ifconfig 4.问题 4.1 中文乱码

MyBatis操作数据库(4)

动态sql 动态sql是MyBatis的强大特性之一, 能够完成不同条件下的sql拼接. <if>标签 在注册用户的问题时, 可能会有这样的一个问题:就是说注册时有一些信息是必填的, 而有一些信息是选填的. 那么如果在添加用户的时候有不确定字段的传入, 程序应该如何实现呢? 这时就…

算法与数学

学过数据结构的对这个应该都不会感到陌生&#xff0c;但是乍一看原来是数学&#xff0c;然而事实就是如此。二分法的数学源头就是这个。 还有前缀和的 我们这里所说的前缀和其实就是我们在高中学的数列中的Sn(前n项和)&#xff0c;只是我们这里需要将S1 , S2 , S3 , S4 …… S…

Android apk包使用360加固工具的加固步骤

1&#xff0c;准备好已经签名打包的apk包。 2&#xff0c;在360加固官方网站下载加固exe软件。三六零天御-企业移动应用安全一站式服务平台 3&#xff0c;步骤一&#xff0c;添加加固包&#xff0c;进行加固&#xff0c;并输出加固包&#xff1a; 4&#xff0c;步骤二&#…

idea项目启动异常:Command line is too long.

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; idea中启动项目报错&#xff1a; 解决方案 在idea 的运行配置中&#xff0c;修改enviroment下的shorten command line 为jar manifest 注&#xff1a; 有时shorten command line 可能不是默认存在的…

[2021最新]Java时间戳和日期时间互转换

代码&#xff1a; import java.text.ParseException; import java.text.SimpleDateFormat;public class MainProcess {public static void main(String[] args) throws ParseException {// 1.set formatSimpleDateFormat timeSmat new SimpleDateFormat("yyyy-MM-dd HH:…

「sentinel」流量控制组件的应用

「sentinel」流量控制组件的应用 Sentinel版本QPS 一、初识Sentinel1、Sentinel2、Sentinel 和 Hystrix对比3、雪崩问题 二、环境搭建1、下载安装Sentinel2、微服务整合Sentinel 三、流量控制1、簇点链路2、流控设置3、流控模式直接关联链路 4、流控效果流控效果解释 四、热点限…

css div添加滚动条(附加源码)

问题描述 先看效果图。 每个商品通过后台接口查询出来&#xff0c;前端v-for进行显示&#xff0c;所以这块我要添加一个滚动条&#xff0c;我不确定有多少个商品。 解决方案 实现思路&#xff1a;div设置高度为1000rpx&#xff08;我这边是举例&#xff0c;根据实际场景去设…

思维树(Tree of Thoughts)的概念

思维树&#xff08;Tree of Thoughts&#xff0c;简称ToT&#xff09;是一种利用大型语言模型进行问题解决的框架。这个框架借鉴了人类认知研究的成果&#xff0c;特别是关于人类在做决策时的两种思维方式&#xff1a;快速、自动、无意识的模式&#xff08;称为“系统1”&#…

GNU Radio创建Zadoff-Chu序列C++ OOT块

文章目录 前言一、ZC序列是什么&#xff1f;二、创建自定义的 C OOT 块1、创建 OOT 模块2、创建 OOT 块3、修改 C 文件4、编译及安装 OOT 块 三、测试1、grc 图2、运行结果①、时域图②、时域幅值模图③、IQ 曲线 四、其他五、资源自取 前言 本文实现在 GNU Radio 中创建 Zado…

JDK8、JDK11、JDK17和JDK21这几个版本更新的主要特性

文章目录 1.JDK82.JDK113.JDK174,JDK21 1.JDK8 JDK8是Java的一个重大更新版本&#xff0c;引入了一系列新特性和改进&#xff0c;主要包括&#xff1a; Lambda表达式&#xff1a;Lambda表达式允许我们以简洁、函数式的方式编写代码&#xff0c;使代码更易于理解和维护。-Stream…