- 博客(56)
- 收藏
- 关注
原创 Linux驱动开发-①regmap②IIO子系统
结构体iio_dev来表示具体的IIO设备,整体的驱动框架,还是要看设备,比如spi设备,创建的就是spi_driver。icm20608c_read_raw的返回值,决定读到的数据值,返回值IIO_VAL_INT为1,读到的数据按照整形返回,只有val,没有val2,返回值IIO_VAL_INT_PLUS_MICRO为2,按照val+val2/1000000反馈, 返回值IIO_VAL_INT_PLUS_NANO为2,按照val+val2/1000000000,返回值为负,读取错误。
2025-04-17 17:01:18
1113
原创 Linux驱动开发-网络设备驱动
PC1准备好,PC2也准备好,就建立其连接。在三次握手建立连接后,PC1发送一个数据包,Seq为a+1,Ack为b+1,载荷长度为12,当PC2接收到这个数据包后,会给PC1反馈一个Seq为b+1,Ack为PC1的Seq(a+1)+载荷(12),即a+1+12,PC2的载荷为0,此数据包发送给PC1,表示PC2接收到PC1发送的数据包了。:确认号,对收到的报文进行确认,序列号和确认号,是为了保证每个发送过去的包,对方都能收到,我发出一个带有序列号的包,对方就要回一个带有确认号的包,这俩号是有一定关系的。
2025-04-13 19:54:57
861
原创 Linux驱动-块设备驱动
块设备驱动的关键结构在于:结构体gendisk,表示一个块设备,包含设备号,分区,操作函数集,相对于字符设备驱动区别在于:有I/O调度的块设备:(I/O调度意思就是在应用层对块设备进行操作时候,这个调度模块会把对块设备的操作转化为请求request,然后放到请求队列当中,因此在处理时候,主要是对请求队列中的bio请求进行操作),请求队列模式:通过 blk_init_queue 初始化请求队列,由调度器管理 request,再分发给驱动,如磁盘设备。没有I/O调度的设备:EMMC以及SD卡,
2025-04-09 22:34:16
525
原创 Linux驱动-①电容屏触摸屏②音频③CAN通信
*总体流程:**当触摸后,触发了中断,进入中断处理函数中,先设置出了slot即id,第几次按到了,然后设置其state状态,虽然在前面,但是这些数据要先放到内核的缓冲区中,这个函数的上下和最终数据输出并不是一样的顺序,然后上报x y值,然后调用这个sync一下,就是发送数据,然后当触摸屏释放,还会触发一次中断,从而引起 input_mt_slot(dev->input, id);(比如手划过后,会有1,2,3,4,5,点信息,上报完1,给一个sync,再上报2,再给一个sync信号…
2025-04-05 16:38:36
688
原创 Linux驱动开发-①I2C驱动②spi驱动③uart驱动
kmalloc即动态分配内存,正常一个应用程序运行,会产生两个栈空间,用户栈(位于用户空间,用于存储函数调用、局部变量等用户态数据)和内核栈(位于内核空间,当进程通过系统调用或中断进入内核态时使用),执行read或者write函数时,cpu从用户态切换到内核态,在内核开辟栈空间,这个空间一般比较小,为8kb或者16kb,因此在read或者write函数中,①如果创建比较大的结构体变量或者是数组数据以及其他数据时候,其大小可能会超过栈空间,采用kmalloc函数在其他内存中开辟出空间,来放这些数据。
2025-03-30 19:26:31
946
原创 Linux驱动开发-①platform平台②MISC字符驱动框架③input框架
的子系统,针对一类设备而创建的框架,比如按键、键盘、鼠标、触摸屏,和这个misc感觉上也差不多,input适用的更多,能省去创建主设备号次设备号和节点的创建工作(主设备号已经定了,子系统的所有设备主设备号都为 13)。其次支持设备树,支持设备的热插拔(驱动在内核配置好后,比如有设备连接上,通过compatible属性,驱动能够自动的控制设备),并且一个驱动能控制多个设备。MISC字符驱动框架目的就是为了让字符设备少占用点主设备号,让字符设备的主设备号为10,不同的字符设备用的次设备号不同。
2025-03-24 21:39:37
702
原创 Linux驱动开发-①中断②阻塞、非阻塞IO和异步通知
应用程序:这个key_signal就类似于中断函数, signal(SIGIO,key_signal)相当于中断函数注册的意思,从而在应用程序中,将应用程序对应的进程号给内核,并且打开异步通知,内核中驱动程序判断按键按下后,将信号传递给这个应用程序进程,执行key_signal函数,读取按键值。类似于中断的思想,当驱动中判断出按键按下,发送一个信号,到应用对应的进程中,从而引起应用程序执行读取按键的操作,在应用程序中,类似于中断的方式。:在中断上下文中,当前 CPU 会禁用抢占,直到中断处理完成。
2025-03-21 20:32:50
760
原创 Linux驱动开发-①pinctrl 和 gpio 子系统②并发和竞争③内核定时器
②中断可以用,因为中断不能休眠。信号量就相当于设置一个变量,初始值,我进行这个操作时,这个变量会设置为另一个值,其他线程或者内核看到这个变量不是初始值,不会在外面一直等待,而是去执行其他操作,等我执行完这个操作后,会将这个变量变回初始值,然后通知线程和内核来执行这个操作,适合锁持有时间较长的情况。执行这一步,不被其他线程或者内核影响,相当于我在执行这个操作时候,让一个标准位置0,其他线程或者内核想执行这个操作,一看这个标志位为0,就执行不了,等到这个操作被我执行完后,把标志位置1,从而其他可以去执行。
2025-03-16 23:10:21
825
1
原创 Linux驱动开发-设备树
设备树:设备按照树这种结构,来描述板子上的设备信息的文件,目的是和linux内核分离开,用专属的文件格式来描述,这个文件称为设备树(.dts)。主干是系统总线,分支有GPIO控制器,SPI控制器,IIC控制器等,然后再分支,比如IIC控制器又分为IIC1和IIC2,然后继续分支,IIC1上搭载具体的设备。
2025-03-11 11:19:51
922
原创 Linux驱动开发-字符设备驱动开发LED设备
注销时候使用两个函数,要有先后顺序,先cdev_del(删除字符设备,使其从内核的设备列表移出) ,再unregister_chrdev_region(释放设备号,使其从内核设备号池中移除),如果先释放设备号,可能出现内核在删除字符设备时无法正确找到字符设备,导致cdev_del失败或者内核崩溃,或者不使用cdev_del,会导致字符设备仍然在内核的设备列表中。顺序是,首先摧毁设备节点,其次摧毁类,如果先摧毁类,设备在销毁过程中可能会尝试访问已经被销毁的类的相关信息,从而导致内核崩溃或者产生错误信息。
2025-03-07 16:47:27
1174
原创 Linux驱动开发-字符设备驱动开发
在传统方式中,硬件信息直接硬编码在内核源码中,导致内核难以支持多种硬件平台,使用设备树后,硬件信息独立于内核源码,内核通过解析设备树文件获取硬件信息。:C库函数内部会调用系统调用,将请求传递给内核,每个系统调用都有一个唯一的系统调用号,系统调用参数通过寄存器传递给内核,通过软中断触发从用户空间到内核空间的切换,内核会根据系统调用号找到对应的处理函数,执行具体操作,然后将结果返回给用户空间。驱动类型:①字符设备驱动:以字节流方式访问设备,包括,IIC,SPI,按键,键盘,鼠标,串口和LED。
2025-03-04 22:12:25
966
原创 Linux系统移植之根文件系统构建
根文件系统就好像是汽车的框架,显示屏,方向盘和座椅,提供了linux系统操作,使用的界面和工具。主要包括:①系统工具:ls,cp,rm等命令,bin文件。②配置文件:/etc目录下的配置文件,比如设置什么开机自启等。③库文件:/lib中,负责程序运行所需的共享库。④设备文件:/dev目录下的文件。⑤用户文件:/home目录下的问价。
2025-03-01 11:39:58
935
原创 Linux系统移植之Linux内核启动流程和移植
start_kernel最后调用函数rest_init函数,内核初始化的最后阶段,初始化进程,将内核态转到用户态,启动用户空间的第一个进程,通常是init进程。①创建内核线程:创建一个内核线程来执行函数,该函数负责启动用户空间的第一个进程(通常是 init 进程)。创建另一个内核线程来执行kthreadd函数,该函数负责管理内核线程的创建和销毁。②启动调度器:调用启用调度器,使系统能够进行任务调度。③切换到空闲任务:调用函数,使当前 CPU 进入空闲状态,等待调度器分配任务。
2025-02-27 21:22:36
956
原创 Ubuntu中出现对control.tar.zst未知压缩
乌班图中,使用终端命令sudo apt-get ****,安装不了软件,报错对control.tar.zst使用未知压缩,进入.dtb目录下,使用dpkg命令也安装不了,也是一样报错。,即将下面镜像添加到etc/apt/souces.list中,将原来的删除或屏蔽即可。查看到这个乌班图版本:16.04.5,官方的源已经停止支持了,换用阿里的源文件。
2025-02-24 13:34:34
636
原创 Linux系统移植之对NXP的Uboot修改后移植
对于该板子具体就是:①告诉uboot这个板子的信息是:IMX6ULL芯片,用emmc存储,有俩网卡,,②告诉uboot启动的时候从emmc加载内核,网卡初始化好,③启动时候将这些参数传递到内核中。bootcmd保存uboot默认命令,当uboot倒计时结束后,会执行bootcmd中的命令,一般用于启动Linux内核,比如读取EMMC中的镜像文件zImage和设备树文件到DDR(DRAM)中,然后调用bootz 启动内核。LCD驱动修改,①使用的GPIO,查看IO的配置是否正确,这个在.c文件中修改即可。
2025-02-23 19:21:32
843
原创 Linux系统移植之Uboot启动流程
第一阶段初始化硬件,采用的汇编语言。第二阶段更为复杂的初始化和内核加载,采用C语言。uboot启动,先找到入口(第一行程序),通过链接脚本u-boot.lds找到程序的入口地址,即文件中的_start,如下:由于 Flash 等存储设备的读写速度较慢,为了提高程序的执行效率,通常会将 U-Boot 的第二阶段代码从 Flash 复制到 RAM 中执行。复制的起始地址和长度需要根据具体的硬件和 U-Boot 配置来确定。在完成硬件初始化和代码复制后,程序会跳转到 U-Boot 第二阶段的入口点,开始执行
2025-02-20 21:40:19
978
1
原创 Linux系统移植之Uboot作用以及相关命令
②其次uboot开始运行,对板子上的软硬件做进一步的初始化,将linux内核,设备树(dtb),根文件系统(rootfs)从外部存储器放到内部(比如启动方式位SD卡,对于这个正点原子的板子,会将SD卡中的linux内核和设备树放到DRAM中),然后跳转到linux中运行。2.硬件初始化,先初始化处理器,设置工作模式,寄存器等,在进行硬件初始化,比如内存控制器,串口,网络接口,配置这些设备的寄存器,对各种软件和硬件的初始化,其实就是寄存器的相关配置。nm [.b.w.l] 地址 修改单个地址的数据。
2025-02-16 21:54:44
1034
原创 Linux-Ubuntu之裸机驱动最后一弹PWM控制显示亮度
从12.5号到1.6号,中间去海南出差17天,耗时差不多一个月,把这个正点原子的二期视频给看完,程序都敲了一遍,感觉比51是难上一成,51学了20天,看完视频基本上能自己把代码完整敲完,不用对着,这个真整不了,说是裸机开发,感觉更像是学习寄存器控制,好多好多寄存器的位要去控制,还要去函数嵌套,实现各种功能,不过也学习了各种C语言的知识,像宏还能去利用函数,枚举类型和结构体的嵌套,各种函数的调用,指针和数组的使用很多吧。
2025-01-06 21:45:12
501
原创 Linux-Ubuntu之SPI串行通信陀螺仪和加速度计
相同点:①都是串行通信,数据按位传输,②都是主从架构,一个主设备作为控制中心,多个从设备响应并进行数据的传输。读取的数据包括加速度、陀螺仪值和芯片温度,程序其实和I2C的类似,先在SPI的函数中,进行对SPI相关寄存器初始化,包括使能,设置写入寄存器后寄存器发送,设置通道,时钟分频以及其他先关寄存器配置,再说明读写函数,这个读写函数比I2C简单,发送时:直接判断寄存器状态是否为空,空了就往RXDATA中写数据,自动就实现数据发送,接收时:判断寄存器状态是否来数据了,来了数据就将RXDATA中的数据读取。
2025-01-06 13:01:47
1281
原创 Linux-Ubuntu之I2C通信
开始信号→发送设备的地址,说明进行读写操作,虽然整体是读操作,但是这两步要进行还是写,因此在七位设备地址后面跟的是写标志位→设备发送ACK应答信号→再发送开始信号→发送要读取数据寄存器的地址→设备发送ACK应答信号→重新发送start信号→发送设备地址+读标志位→设备发送ACK应答信号→主机从设备的寄存器中读取数据→主机发送NO ACK信号,表示读取完成→主机发送STOP停止信号。读操作和写操作,前面两个环节是一样的,不一样在于后面两个部分,读操作要再次写入设备的地址,最后对设备的寄存器数据进行读取。
2025-01-04 20:42:21
1008
原创 Linux-Ubuntu之RTC实时时钟显示
这个RTC的和计数器差不多,往对应寄存器中放入初始化的时间,然后在时钟的作用下,进行累加,实现计时,首先对初始化的寄存器进行配置,将要放入的年月日时分秒转化为整形数据,把这个整形数据放入到寄存器中,便可进行计时,然后读时间,将寄存器中的值读出来,转化为年月日时分秒,将其放入数组中,运用屏幕显示字符函数,进行显示。也设置为指针类型,并且数据打印出来是1,在屏幕上就是无法显示。
2025-01-02 20:16:43
437
原创 Linux-Ubuntu之RGBLCD显示屏
这个意思是先把aaaa强制类型转换成无符号整形指针,即地址为0X11223344,在前面再加*,意思就是这个指针指向的内容,即先强制转化为指针后,再往这个地址对应的内容进行赋值。
2025-01-01 21:13:36
901
原创 Linux-Ubuntu之串口通信
串口通信利用接口是这个TTL,下载程序用的是OTG,先连接OTG下载程序,然后再连接到TTL接口,利用SecureCRT观察串口通信,这个Secure就像是板子的串口显示屏,能观察发送和接收的信息。添加include文件夹,然后将Makefile文件进行对应修改,添加相应路径,在主函数中调用printf和scanf的stdio头文件,在软件上输入数值,实现串口的输入发送,终于感觉能进行交互了。利用函数uart_setbaudrate进行设置,串口引入的时钟为80MHZ。
2024-12-27 18:27:41
903
原创 Linux-Ubuntu之EPIT定时器实验和精准按键消抖
使用EPIT寄存器包括设置时钟源,分频值,工作模式,计数器值,使能比较中断,加载值和比较值,这些寄存器的配置。主要原理就是:在设置好频率后,EPIT 是一个向下计数器,也就是说给它一个初值,它就会从这个给定的初值开始递减,直到减为 0,计数寄存器里面保存的就是当前的计数值。这个与前面不一样在于,在按键中去调用定时器功能,即在按键初始化函数中,调用定时器的初始化函数,相当于实现的是中断的嵌套,在按键的中断中,使用定时器中断,在定时器中断中,判断到一定值后(具体时间),即延时,按键仍为低电平,判断按键按下。
2024-12-23 22:49:48
445
原创 Linux-Ubuntu之按键中断实验
按键中断实验,先在汇编中进行说明,然后对中断初始化,GPIO进行配置,最后具体说明实现这个中断会执行什么样操作。模块实现起来比较多,原理相对前面来说复杂一些。
2024-12-23 22:34:44
382
原创 Linux-ubuntu之主频和时钟配置
时钟利用树这种结构,将24MHZ的晶振,利用寄存器进行相关数值和使能配置,实现倍频,然后在利用各种分频实现不同频率的时钟,就像先由晶振产生PLL时钟源,再利用类似门控的选择信号以及分频,到AHB,再对AHB频率进行选择分频,实现IPG 和 PERCLK时钟 ,从而应用。就像由一个源头,再依次往下,形成使用各种外设和设备的时钟信号。
2024-12-19 17:01:42
552
原创 Linux-Ubuntu裸机之开发蜂鸣器和按键
gpio_init函数主要是对GDIR结构体进行定义,说明其输入还是输出,如果为输入,读取输入的值,利用函数gpio_read,如果想输出,直接在进行写0或1。具体使用的时候,要带入函数的实参,即知道是输入输出,然后放到函数里面,让gpio_init函数对GDIR进行赋值以及相关操作。按键:配置寄存器,设置电气属性,配置GDIR为输入,GPIO1-IO18,按键按下,低电平。蜂鸣器:配置寄存器,设置电气属性,配置GDIR为输出,GPIO5-IO01,低电平响。
2024-12-18 22:43:16
394
原创 Linux-ubuntu点LED灯C语言版
一,C语言点灯1.寄存器配置设置为SVC模式,复用寄存器设置GPIO1-IO003,设置电气属性,设置为输出模式。2.软件汇编语言对模式设置,并且将堆栈指针指向主程序:.global _start_start:/*设置为svr模式 */ mrs r0,cpsr /*读取cpsr现在状态 */ bic r0,r0,#0x1f orr r0,r0,#0x13 msr cpsr,r0/*SP堆栈指针 */ ldr sp,=0x80200000
2024-12-17 12:55:14
877
原创 【Linux-ubuntu通过USB传输程序点亮LED灯】
*header和uuu文件:链接: https://pan.baidu.com/s/1r66P0TqRS74JrOyyks-pHQ 提取码: 6666。为了以后检查方便,反编译:arm-linux-gnueabihf-objdump -D led.elf > led.dis。③将设备确保插到ubuntu上,并且USB线插到正点原子开发板的OTG接口,不是TTL接口。⑤在终端运行make后,再运行make run,即可。④确保SD卡要拔出,并且将拨码开关的2打开,on。
2024-12-12 11:25:30
634
原创 Linux-ubuntu之shell脚本、Makefile和Vim工具
但是这样还是麻烦,执行文件太多,不可能全给写上去吧,因此要有什么来替代,因此采用%这个好东西,代表这一类,%.0:%.c→将所有.c类型的转化为.o类型的,并且在前面,也能将所有的.o类型文件进行表示:objects=main.o input.o calcu.0。,cmd1||cmd2,当cmd1执行切正确,那么cmd2不执行,否则执行。其次Makefile的=号和C语言的赋值不一样,比如b= 8,a=b,b=2,按照c语言的逻辑,a为8,但是在Makefile中,a等于b的最终值,为2。
2024-12-09 21:41:11
683
原创 Linux-Ubuntu相关指令以及操作
一个文件的权限,通常有读(r),写(w),执行(x),使用ls -l查看文件的权限,如果文件权限不够,常用:chmod 777 文件名,赋予文件最大权限。比如a.c文件的权限 -rw-rw-r,对于用户组的权限读和写,对于用户组也是读和写,对于其他用户的权限只有读,777的意思就是 111 111 111 ,即对用户,用户组和其他用户都有读,写和执行的权限。-c创建压缩文件 -v显示压缩过程 -j 用bzip2格式进行压缩 -z用gzip进行压缩 -f 备份压缩文件 -x解压。
2024-12-09 20:05:44
442
原创 Linux-ubuntu环境配置
①上网问题:这个后期还要继续学一下关于网络相关配置的原理,因为连得是校园WIFI,主机IP地址10.110.255.159,桥接模式内部乌班图连不上,只能选用NAT模式,并且此时内部IP是192.168.242.1,和主机都不在一个网段,竟然通信上了,这个确实不太理解,校园网有点牛皮。②U盘插入后,不能识别,并且虚拟机右下角的切换角标变灰。这些都是文件夹里面有的,然后对着正点原子视频安装就行,虚拟机的破解码,去百度搜一个能用就行,中间遇见俩问题。①乌班图里面不能上网,②插入U盘后,这个系统识别不了。
2024-12-06 17:08:38
284
原创 C51-杂记
对这段时间学习的总结:从点灯,听响,看管,按键,点阵,电机,中断,定时,通信(传感器的通信,红外遥控的通信,板子内部比如I²C的通信,RS422和RS485的通信),显示,学习各种硬件的使用原理,各种通信方式,根据时序图控制信号以及建立整体工程对几个模块的联合调用,比如将温度传感器数据放到显示屏上显示,利用红外遥控器控制处于不同的工作模式等等,感觉还是学了点基础的应用,算是给做linux开发打下基础吧。不过过几天又要去海试了,哎,没办法,就当旅游吧,可别浪费太多时间啊。
2024-12-05 21:50:51
526
原创 C51-LCD12864显示屏
LCD12864分辨率是128×64个像素,可以显示4行8列个汉字(每个汉字占16×16个像素),使用方式和LCD1602方式相同,前期对其进行初始化命令,然后找到每一个显示位置的地址,再传输显示的数据即可。不同在于与LCD1602的行列不同,汉字是两个字节,字符型数据是一个字节。一,LCD12864显示屏。
2024-12-05 16:44:43
508
原创 C51-液晶显示屏
LCD1602其实和数码管显示差不多,数码管通过三八译码器确定位选,然后往里面输入显示数值,这个液晶显示屏也类似,先确定显示的地方,然后确定显示的值。因此关键是数据在显示屏上怎么样去显示的问题,比如数据超过16个字节,怎么样实现换行显示,以及怎么样在显示屏的制定位置显示。然后是设置数据的显示,先找位置,再输入显示数据,如果第一行显示完毕,继续往第二行显示。写命令RS=0,写数据RS=1,写数据时候,E由低电平,延时,高电平,延时,写数据,低电平。
2024-12-04 22:22:59
182
原创 C51-ADC模数转换和PWM波实现呼吸灯
程序:主要利用定时器中断,设置这个定时器中断的进入时间,然后在中断中设置计次,这个计次即(周期=进入次数×每次进入的周期),然后在中断内设置在占空比内,PWM输出高电平,占空比外输出低电平。XPT2046芯片转换方式:逐次逼近型,N为位寄存器对于其最高的bit置1,到N位D/A转换器变为模拟信号,输入到比较器,比较器将U0与真实输入Ux模拟信号进行比较,如果Ux大于U0,通过逻辑控制电路将寄存器的这个最高位置1,然后依次对其余位进行操作,得到数字信号,放到输出缓冲区上。,还有其他基础设置,进行配置。
2024-12-03 21:46:55
1254
原创 C51-红外遥控直流电机
如果没有问题,再判断高电平的时间,如果高电平时间超过2000ms,证明不是1,也有问题,因此在低电平满足的情况下,高电平时间t, 2000us>t>600us,满足这种情形下,是1,否则是0。引导码这个类似于数据包头,有两个值得注意的,①前期为为低电平9ms,要判断是不是一直为低电平,若一直为低电平,证明这帧数据不对,就不用继续判断了。红外遥控器发送红外信号,接收装置将这个红外信号转化为数据帧,其中包括引导码,地址码和发地址码,控制码和控制反码,里面用到的是这个控制码,即红外遥控器上面不同的数据。
2024-12-02 22:24:26
596
原创 C51-DS1302芯片显示时间
对比这三个实验IIC实现EPROM的读写,温度传感器,时钟显示,原理基本上都是通过时钟线,到对应的设备内部的寄存器中,来进行数据的读写操作,每次传输一个字节传输,温度传感器有一些不同,它不通过时钟线控制,直接用数据传输线,初始化,响应,读0读1,写0写1按照特定的格式进行判断,这样相对也比较麻烦,要控制高低电平的响应时间。控制寄存器的格式如下:第六位一般设置低电平,通过1-5位控制是哪个寄存器,比如00000秒寄存器,00001分寄存器,第0位控制读写操作。
2024-12-02 15:10:30
237
原创 C51-温度传感器显示
这个实验跟上面的EPROM其实差不多,都是根据电平信号控制数据的传输,EPROM主要是通过时钟信号控制,这个是通过自己带的引脚控制,这个也最麻烦,控制这个电平信号的初始化(复位以及响应)和读写操作,处理过程中,主要对数据的读写,重要的是读完后,对特定格式数据的处理,把它转化为想要的数据格式,然后是去展示这个数据,利用数码管。写的时候,若为1,低电平延时2us,然后为高电平,延时60ms,写1,低电平延时60,然后高电平,延时2us.SKIP ROM 命令(0XCC)→。的典型温度读取过程为:复位→发。
2024-12-01 17:52:42
580
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人