当前位置: 首页 > news >正文

驱动开发面试复习

创建字符设备

1 创建设备号
alloc_chrdev_region
2.创建cdev
cdev_init
3.添加一个 cdev,完成字符设备注册到内核
cdev_add
4.创建类
class_create
5.创建设备
device_create

1.内核空间与用户空间数据

copy_from_user 和copy_to_user 俩个函数来完成。
copy_from_user 函数是将用户空间的数据拷贝到内核空间。
copy_to_user 函数是将内核空间的数据拷贝到用户空间

2.container_of 函数

通过结构体变量中某个成员的首地址进而获得整个结构体变量的首地址
container_of(ptr,type,member)
参数含义:
ptr 是结构体变量中某个成员的地址。
type 是结构体的类型
member 是该结构体变量的具体名字

3.并发与竞争

3.1什么是竞争?

多个程序同时访问一个共享资源产生的问题就叫做竞争。竞争产生的根本原因就是 Linux 系统的并发访问

竞争产生的原因如下所示:
(1)多线程的并发访问
(2)中断程序的并发访问
(3)抢占式并发访问

3.2什么是并发?

所谓并发,就是通过算法将 CPU 资源合理地分配给多个任务,当一个任务执行 I/O 操作
时,CPU 可以转而执行其它的任务,等到 I/O 操作完成以后,或者新的任务遇到 I/O 操作时,CPU 再回到原来的任务继续执行

3.3解决竞争问题

原子操作、自旋锁、信号量、互斥体

原子操作只能对整形变量或者位进行保护,而对于结构体或者其他类型的共享资源,原子操作就力不从心了

自旋锁是为了保护共享资源提出的一种锁机制。自旋锁(spin lock)是一种非阻塞锁,也就是说,如果某线程需要获取锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在不断的消耗 CPU 的时间,不停的试图获取锁

自旋锁死锁发生存在两种情况
进程 A 拥有自旋锁,中断到来,CPU 执行中断函数,中断处理函数,中断处理函数需要获得自旋锁,访问共享资源,此时无法获得锁,只能自旋,从而产生死锁

对于中断引发的死锁,最好的解决方法就是在获取锁之前关闭本地中断,Linux 内核在
“/include/linux/spinlock.h”文件中提供了相应的 API 函数

信号量也是解决竞争的一种常用方法,与自旋锁不同的是,信号量会使等待的线程进入休眠状态,适用于那些占用资源比较久的场合

互斥锁会导致休眠,所以在中断里面不能用互斥锁。同一时刻只能有一个线程持有互斥锁,并且只有持有者才可以解锁,并且不允许递归上锁和解锁

4.Linux 定期器

硬件为内核提供了一个系统定时器来计算流逝的时间(即基于未来时间点的计时方式,以当前时刻为计时开始的起点,以未来的某一时刻为计时的终点),内核只有在系统定时器的帮助下才能计算和管理时间,但是内核定时器的精度并不高,所以不能作为高精度定时器使用。并且内核定时器的运行没有周期性,到达计时终点后会自动关闭。如果要实现周期性定时,就要在定时处理函数中重新开启定时器

补充:高级定时器

5.Linux 内核打印

dmseg 命令
查看 kmsg 文件,cat /proc/kmsg
调整内核打印等级cat /proc/sys/kernel/printk

6.驱动调试方法

printk 函数打印
dump_stack 函数
WARN_ON(condition)函数

7.中断

中断是指在 CPU 正常运行期间,由外部或内部事件引起的一种机制。当中断发生时,CPU会停止当前正在执行的程序,并转而执行触发该中断的中断处理程序。处理完中断处理程序后,CPU 会返回到中断发生的地方,继续执行被中断的程序。中断机制允许 CPU 在实时响应外部或内部事件的同时,保持对其他任务的处理能力

7.1中断的上下半部

中断上文是中断服务程序的第一部分
它主要处理一些紧急且需要快速响应的任务,包括保存寄存器状态、更新计数器等,以便在中断处理完成后能够正确地返回到中断前的执行位置

中断下文是中断服务程序的第二部分
中断下文负责处理那些不能立即完成的、需要更多时间的任务。这些任务可
能包括复杂的计算、访问外部设备或进行长时间的数据处理等

中断下文的一种实现方式——tasklet
Tasklet 绑定的函数在同一时间只能在一个 CPU 上运行,因此不会出现并发冲突,tasklet 绑定的函数中不能调用可能导致休眠的函数,否则可能引起内核异常

一般步骤:
首先定义了 my_tasklet_handler 作为 tasklet 的处理函数。
然后,声明了一个名为 my_tasklet 的 tasklet 结构体,
并使用 tasklet_init 函数对其进行初始化。调用 tasklet_schedule 函数,我们调度(触发)了 my_tasklet 的执行。调度 tasklet 只是将 tasklet 标记为需要执行,并不会立即执行 tasklet 的处理函数。实际的执行时间取决于内核的调度和处理机制

7.2中断子系统框架

由上到下分别为用户层、通用层、硬件相关层和硬件层

7.3中断控制器 GIC

中断控制器 GIC(Generic Interrupt Controller)是中断子系统框架硬件层中的一个关键组件,用于管理和控制中断,接收来自各种中断源的中断请求,并根据预先配置的中断优先级、屏蔽和路由规则,将中断请求分发给适当的处理器核心或中断服务例程

7.4中断线程化

将中断处理程序从主线程中独立出来,创建一个专门的线程来处理这些中断事件。
这样,主线程就不再受到中断的干扰,可以专注于自己的工作,不再频繁地被打断。
中断线程化的核心思想是将中断处理和主线程的工作分开,让它们可以并行执行。中断线程负责处理中断事件,而主线程负责执行主要的工作任务。这样一来,不仅可以减少切换的开销,还可以提高整个程序的响应速度和性能

中断线程化的处理仍然可以看作是将原来的中断上半部分和中断下半部分。上半部分还是用来处理紧急的事情,下半部分也是出路比较耗时的操作,但是下半部分会交给一个专门的内核线程来处理。这个内核线程只用于这个中断。当发生中断的时候,会唤醒这个内核线程,然后由这个内核线程来执行中断下半部分的函数

request_threaded_irq是 Linux 内核中用于请求并注册一个线程化的中断处理函数的函数

int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags, const char *devname, void *dev_id);

handler:是在发生中断时首先要执行的处理程序,非常类似于顶半部,该函数最后会返回 IRQ_WAKE_THREAD 来唤醒中断,一般 handler 设为 NULL,用系统提供的默认处理

thread_fn:线程化的中断处理函数,非常类似于底半部。如果此处设置为 NULL 则表示没有使用中断线程化

8平台总线模型

平台总线(Platform bus)是 Linux 内核中提供的一种虚拟总线,用于管理和组织与特定硬件平台相关的设备和驱动。它充当了平台设备(platform device)和平台驱(platform driver)之间的桥梁,负责将它们进行匹配和绑定。
在这里插入图片描述
平台总线优势如下所示:
(1)设备与驱动的分离
设备代码放在device.c 文件中(或者设备树),驱动代码放在 driver.c 文件中
(2)提高代码的重用性:平台总线模型使得相同类型的设备可以共享相同的驱动代码
(3)减少重复性代码:在传统的设备驱动模型中,如果有多个相同类型的设备存在,就
需要为每个设备编写独立的驱动代码

9.虚拟文件系统 ConfigFS

9.1常用的虚拟文件系统

虚拟文件系统提供了一个内核抽象层,使得应用程序可以通过统一的文件访问接口操作不同类型的文件和设备
procfs 是一个虚拟文件系统,提供了对系统内核运行时状态的访问接口。它以文件和目录的形式表示内核中的进程,设备,驱动程序和其他系统信息。通过读取和写入 procfs 中的文件,可以获取和修改有关系统状态的信息
sysfs 是一个虚拟文件系统,用于表示系统中的设备,驱动程序和其他内核对象
configfs 是一个虚拟文件系统,用于动态配置和管理内核对象,允许用户在运行时添加,修改和删除内核对象,而无需重新编译内核或重新启动系统

10.设备模型基本框架-kobject 和 kset

11.pinctrl子系统

12.GPIO 子系统

13.输入子系统

在 Linux 中,input 子系统是专门为处理输入类设备而设计的一个子系统或框架
Input 子系统可以分为事件处理层、设备驱动层、核心层三层

固定输入设备的设备节点:
不同厂家和型号的外设在内核启动时加载的顺序可能会不同。例如,触摸板和 USB 转串口等设备,这会导致在/dev/input 目录下创建的 evdevx 节点(其中 x=0,1,2,3…)不同

解决思路如下:通过分析 evdev.c 驱动程序,我们确定设备节点是在 evdev_connect 函数中创建的。因此,只需要在 evdev_connect 函数中针对需要固定设备节点的设备单独创建一个设备节点即可
在这里插入图片描述

14.调节LCD

在这里插入图片描述

  1. 查看外设Datasheet,了解电子特性、启动时序、屏幕参数
  2. 查看原理图,确定相关IO引脚
  3. 修改DTS
  4. 编译&运行&调试

屏幕参数:
在这里插入图片描述
常见问题

  1. 在点亮屏后刚开始有开机 logo 闪烁,向右偏移了近半个屏幕的长度,等问题。
    重新确认 clock-frequence 后发现少打了一个 0 ,修改后解决了闪烁大偏移的问题。
  2. 画面偏移
    稍微降低 hs_clk ,由 504 降低到 496 解决。
  3. 垂直方向会显示多一点内容。
    调整 VFP 后解决,将 VFP 增大为 15 。
  4. 有黑边
    稍微增大 VBP 后解决,将 VBP 增大为 15。
  5. 开机 android 最左边会被裁剪一部分
    增大 HBP 后解决,将 HBP 由 10 增加到 30。
  6. 显示偏移、图像位置偏差
    timing 中的参数设置有误。优先确认。
    看着图像调节前扫、回扫进行左右上下移动
  7. 白屏
    随机出现白屏有可能是静电问题,把LCD拿到头发上擦几下,如果很容易出现白屏那肯定就是静电问题了。另外一个在有Backend IC的情况下,也有可能bypass没处理好。
    結束開機logo至android動畫出現之間出現閃屏或者閃白光的情況。原因:在這個時間點kernel會會對屏再次初始化,我們可以軟件上屏蔽第一次初始化動作從而解决。
  8. 屏在进出睡眠或者显示过程中白屏
    喚醒屏幕閃白光問題,說白了是背光早亮了,很有可能是下序列mdelay太久,改小點就沒有這個問題了。根本原因屏幕初始化序列下慢了。
    sleep out(0x11)和 display on(0x29)之间需要 mdelay(120ms)左右。
  9. 花屏
    说明 lcd 初始化成功,但是没有 rgb 刷过来。
    timing 中的参数设置有误。优先确认 pclk。
    花屏 还可能是总线速度有问题。
    开机就花屏最简单的解决方式是,在 Init 结束的地方加一个刷黑屏的功能。也可以在睡眠函数里加延时函数。
  10. 屏幕闪烁
    pclk 有问题
    在最开始的时候,我的 pclk 漏了一个 0 ,为之前的 1/10 此时就有图像闪烁问题。
    proch 有问题
    在调试完后,我尝试将 proch 增加到极限,发现会出现图像闪烁的问题。
  11. 屏幕抖动
    测时序,延时不足
  12. 屏幕闪动
    通过调节电压来稳定,一般调节的电压为VRL、VRH、VDV和VCM
  13. 唤醒闪屏问题
    这是由於每次重新RST下序列過程delay久了導致,适當減少delay時間
  14. 屏幕唤醒显示灰色底面
    寄存器没有使能外部升压电路
  15. 水波纹
    通常都是rgb interface polarity導致,需要調整pclk hsync vsync de極性使之符合平台極性
  16. 调节对比度
    VRL、VRH、VDV和VCM,这些电压也可以用来调节亮暗(对比度)
    也可以通过调节Gamma值来实现,要调节的对象为 PRP、PRN、VRP、VRN 等
  17. 确认有没有 framebuffer 输出
    要是改动了display这块的clk很有可能没有buffer输出的,可以通过cat /dev/graphyics/fb0 查看有没有输出字符
    如果有说明是 mipi 还没有调通,如果没有说明是 fb 有问题

15.调节TP

TP驱动主要是通过IIC和IC通,通过输入子系统上报触摸事件

tp调试时的问题排查
1.当我们调试出现问题时,首先检查电压;
2.在porbe 函数里面加一句打印,确认驱动已经正常注册进系统了;
3.确认中断是否注册上了,可以adb shell cat /proc/interrupters,
getevent工具可以监听中断事件,如果没有就查下打印,一般申请中断失败,都是IO 口被其他驱动或虚拟设备占用;
4.如果注册上了,但是触摸没中断.就用示波器勾下中断脚是否有波形,如果没有就代表触摸屏本身有问题,换一个试一下;
5.如果有波形,但是adb shell cat /proc/interrupters,中断号对应的中断数没有增加,一般都是中断脚被复用为其他作用,比如PWM;
6.一般这时候上层都会有点出来,大致分为三种情况:

  • 出现鼠标,或者只有一个圆圈出来,这个是属于input 创建时候的有问题,可以参考正常的驱动;
  • 出现上下或左右反了,这个是要改驱动里面的上报函数;
  • 如果上下左右正常了,但是会出现无法画到四个边的情况,这个是属于TP 里面的软件问题,需要联系TP 厂的FAE,进行修改;

16.调节WIFI

STA 模式 和 AP 模式
Sta模式: Station, 类似于无线终端,sta本身并不接受无线的接入,它可以连接到AP,一般无线网卡即工作在该模式。
AP模式: Access Point,提供无线接入服务,允许其它无线设备接入,提供数据访问,一般的无线路由/网桥工作在该模式下。AP和AP之间允许相互连接

在使用的过程主要是wpa_suplicant和hostapd两个命令去设置为STA和AP模式
如果需要在设置为AP模式下还需要该热点能上网的话,就还需要桥接网口或者4G让该热点能上网

设置为STA模式:

ifconfig wlan0 up
wpa_supplicant -i wlan0 -Dnl80211 -c /etc/wpa_supplicant.conf -t &
udhcpc -iwlan0 -q

设置为AP模式:

ifconfig wlan0 up
hostapd hostapd.conf &
ip link set dev ap-br0 up
ip link set eth0 master ap-br0

SDIO 接口的 WiFi,首先,它是一个 SDIO卡 设备,然后具备了 WiFi 的功能,所以 SDIO 接口的 WiFi 驱动就是在 WiFi 驱动外面套上了一个 SDIO 驱动 的外壳

mmc 子系统
设备驱动层(WiFi 设备):
|
核心层(向上向下提供接口) 注册mmc总线,SDIO总线
|
主机驱动层(实现 SDIO 驱动)主要是针对不同的芯片使用的host的控制器,在这里面当和设备树匹配之后,会创建一个host,把这个host添加到mmc总线上,会检测卡是否插入(中断检测某个GPIO,轮询检测),检测到卡之后,会注册SDIO驱动到添加到host

WiFi驱动移植流程

  1. BSP已支持WiFi
  2. BSP未支持WiFi
    WiFi驱动放到kernel里面
    将供应商提供rtl8821CU WiFi驱动复制到kernel/drivers/net/wireless/rockchip_wlan/这个目录下面,同时修改当前目录下的Kconfig文件和Makefile文件

常见排查问题:

检查DTS
关注时钟、IO、WiFi_chip_type

&sdio0 {clock-frequency = <100000000>; /*时钟修改的地方 如果SDIO读写识别,可调整时钟*/clock-freq-min-max = <200000 100000000>; /*时钟修改的地方*/supports-sdio; /*SDIO功能*/bus-width = <4>; /*4线模式,调试可改为1线测试*/disable-wp;cap-sd-highspeed; /*highspeed的SDIO外设*/cap-sdio-irq; /*SDIO中断*/keep-power-in-suspend; /*睡眠不断电*/mmc-pwrseq = <&sdio_pwrseq>; /*电源控制*/non-removable;num-slots = <1>;pinctrl-names = "default";pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;sd-uhs-sdr104; /* SDIO3.0 模式*/status = "okay";
};sdio_pwrseq: sdio-pwrseq {compatible = "mmc-pwrseq-simple";clocks = <&rk808 1>; /*提供32.768 LPO*/clock-names = "ext_clock"; /*外部时钟源*/pinctrl-names = "default";pinctrl-0 = <&WiFi_enable_h>;/** On the module itself this is one of these (depending* on the actual card populated):* - SDIO_RESET_L_WL_REG_ON* - PDN (power down when low)*///控制WiFi电源的GPIOreset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>; /* GPIO0_B2 */
};wireless-wlan {compatible = "wlan-platdata";rockchip,grf = <&grf>;WiFi_chip_type = "ap6255";sdio_vref = <1800>;//控制WiFi中断的GPIOWiFi,host_wake_irq = <&gpio0 3 GPIO_ACTIVE_HIGH>; /* GPIO0_a3 */status = "okay";
};wireless-bluetooth {compatible = "bluetooth-platdata";clocks = <&rk808 1>;clock-names = "ext_clock";//WiFi-bt-power-toggle;uart_rts_gpios = <&gpio2 19 GPIO_ACTIVE_LOW>; /* GPIO2_C3 */pinctrl-names = "default", "rts_gpio";pinctrl-0 = <&uart0_rts>;pinctrl-1 = <&uart0_gpios>;//BT,power_gpio  = <&gpio3 19 GPIO_ACTIVE_HIGH>; /* GPIOx_xx */BT,reset_gpio    = <&gpio0 9 GPIO_ACTIVE_HIGH>; /* GPIO0_B1 */BT,wake_gpio     = <&gpio2 26 GPIO_ACTIVE_HIGH>; /* GPIO2_D2 */BT,wake_host_irq = <&gpio0 4 GPIO_ACTIVE_HIGH>; /* GPIO0_A4 */status = "okay";
};
  1. 排查DTS对应的GPIO设置
    确定复用引脚已配置、方向配置、测试高低电平

使用io命令shell
io -4 -w 0xFF77e008 0x0fff0000
sysfs使用echo命令shell

echo xxx > /sys/class/gpio/export
echo out > /sys/class/gpio/gpioxxx/direction
echo 0 > /sys/class/gpio/gpioxxx/value
echo 1 > /sys/class/gpio/gpioxxx/value

使用debugfs查看

  1. 检查电压电平
    电源电压,VDDIO、VBAT的电压,WiFi_REG_ON上电及复位控制信号
    电源控制:
echo 0 > /sys/class/rkWiFi/power //对WiFi模块掉电 
echo 1 > /sys/class/rkWiFi/power //对WiFi模块上电 
echo 1 > /sys/class/rkWiFi/driver //命令会调用模块的驱动的初始化操作,初始化成功后

看到wlan0 节点;

如果执行上面命令对模块进行上下电,而实际测量对应管脚不受控,可以通过io 命令读取对应的寄存器,确认是否写入,如果正确写入但是实际测量不受控请检查硬件部分;
对于sdio接口的模块,执行” echo 1 > /sys/class/rkWiFi/driver”命令 ,正常情况下 sdio_clk 和sdio_cmd 能够测量到相关波形,内核打印上能够看到如下打印,如果没有测量到波形也没有看到如下打印,根据配置文档检查是否正确配置sdio;

WL_REG_ON 主要用于上电,休眠的时候,请保持该GPIO上电,否则会丢失WiFi内部的状态,导致WiFi唤醒失败;
WL_HOST_WAKE 主要用于WiFi设备有数据的时候,唤醒CPU,进入中断,关于中断流程上面已经说过。

  1. 检查时钟
    32.768K的LPO, 37.4M晶振主时钟,SDIO_CLK、SDIO_CMD 的波形
    同时测量执行echo 1 > /sys/class/rkWiFi/driver 时 外部晶体是否有起振,如果扫描时没有起振检查下硬件;同时建议测量外部晶体频偏,频偏比较大情况下,会出现能扫描到模块但是初始化失败;除检查晶振外,正基系列还需要外部32k,测量32k的峰峰值(峰峰值>=0.7VDDIO && 峰峰值 <= 1VDDIO);【注:频偏和峰峰值一定要测量检查,频偏过大峰峰值不对会影响WiFi(扫描连接热点)和蓝牙(扫描连接设备))】

  2. 尝试单线模式
    如果降低clk依然不行,考虑使用sdio单线模式方法如下
    &sdio {

    bus-width = <1>;

使用 sdio 单线模式。如果单线模式可以而使用4线模式不行,检查硬件sdio_data0~sdio_data3 四根线的线序是否弄错;
如果降低clk,使用单线模式均不可以检查下是否是使用最新的sdk代码和最新的WiFi驱动(ftp服务器上有相关patch);
上述检查均无结果,check 图纸 是否周围器件有贴错器件;

  1. 检查模块能否处于工作状态
    netcfg wlan0 up 或busybox ifconfig wlan0 up //执行完成后检查 wlan0 是否处于up状态;如果没有处于up状态;做如下检查确认
    1 确认相关固件是否存在(正基系列,通过看内核日志可以看到),固件不存在考虑到ftp下载固件;此时如果还报其他错误从两个方面排查1 上电时序,2检查sdio部分走线;
    2 尝试使用原始最新的sdk代码做测试;(有客户出现过,上层做了相关修改导致WiFi初始化成功,但是执行netcfg wlan0 up 报告无法识别 ioctl 命令等奇怪错误,原生sdk生成的sysytem.img 没有问题)
    执行iwlist wlan0 scanning ,测试扫描热点是否正常(3368平台下执行iwlist 命令有问题,忽略此步骤)

  2. 确认Android层是否能够打开
    述检查各个步骤可以工作,而通过上层settings界面打开失败;以下几个方面排查
    1 dts中的WiFi_type配置是否正确;cat /sys/class/rkWiFi/chip 确认 下 打印的结果和你的模块是否匹配
    2 确认 wpa_supplicant 相关服务是否生成,libhardware_leacy 启动的wpa服务是否正确;
    3 抓取logcat 日志上传readmine

其他问题
无法连接热点
1.无法连接热点,正基系列模块检查确认晶振频偏和32k峰峰值;
rtl模块考虑驱动配置是否正确,是否匹配;
2.检查确认p2p wlan0 的mac地址是否一致如果检查是否有调用rockchip_WiFi_mac_addr读取mac地址,如果有考虑直接在该函数中return -1;
3.检查确认是否有做RF指标测试以及天线匹配测试
4.上述检查没有问题,做如下测试 (首先用给手机连接所测试的热点做确认)
1 连接无加密热点
2 连接加密热点 测试能否连接成功,并记录对应的logcat 日志与内核日志(开机到打开WiFi以及连接热点的整个过程)
softap 无法打开(正基系列的)
1.查看打开热点时的内核日志,确认下 下载固件是否正确 ,正基系列的模块 softap 下载的固件一般是带ap后缀结尾的;
2.固件下载没有问题 ,考虑使用原始的sdk代码做测试
P2P 问题
P2p 无法打开:确认是否有p2p节点,有p2p节点的检查确认mac地址是否与wlan0 一样,如果一样按照热点问题中的step 2 处理;
第一次开机能够打开,重启后无法打开:考虑检查上电时序,目前遇到都是rtl的模块出现过,问题在于chipen 脚不受控,建议做成受控,在重启时对chipen脚下电;可以通过如下方法实现net/rfkill-wlan.c中的rfkill_wlan_driver 中增加shutdown函数 在该函数中对chip_en 下电;
休眠唤醒出现WiFi无法打开:
1 对比检查休眠唤醒前后 sdio 的iomux 是否发生变更
2 对比 休眠前后以及休眠中 WiFi的外围供电是否发生变更吞吐率问题
8. pcb检查,一定要让模块原厂检查确认 pcb是否存在问题
9. RF指标确认是否ok
10. 天线是否做过匹配
11. Sdio 接口的可以考虑 提到sdio的clk 启用sdio3.0【前提 平台支持 sdio3.0 ,模块支持sdio3.0】
12.常用指令

  • 打开和关闭WiFi
    打开WiFi指令
    svc WiFi enable
    关闭WiFi指令
    svc WiFi disable
    查看wpa_supplicant是不是已经起来了
    ps | grep WiFi

  • 打开和关闭蓝牙BT:
    关闭:adb shell settings put global bluetooth_on 0
    打开:adb shell settings put global bluetooth_on 1
    查询:adb shell settings get global bluetooth_on

  • 查询蓝牙开启状态:
    adb shell settings get global bluetooth_on
    =》0: 未开启 1: 已开启

  • 获取mac地址:

17.调节蓝牙

蓝牙一般是使用串口接口
常见问题是无法打开蓝牙,可以手动拉bluez
比如使用hci命令去手动up一个hci节点,加载蓝牙固件,如果能正常扫描到蓝牙,基本可以确认硬件没什么问题;其次就是要注意时钟问题,也可能导致打不开蓝牙

18.调节4G

4G按照供应商提供的文档操作,像更新最新的代码,添加VID,PID到USB里面,设置PPPD拨号的VPN,在Linux系统的话基本可以搞定,不需要加载ridl库,这个是在Android中需要添加的,也是比较麻烦的。

19.调节网口

网口用的是MDIO,和RMII接口
在这里插入图片描述
内部 MAC 通过 MII/RMII 接口来与外部的 PHY 芯片连接,完成网络数据传输
MDIO 和MDC 这两根线访问 PHY 芯片的任意一个寄存器

一般内核中可以使用通用的网口驱动就可以使能以太网,不过芯片商一般都会做一些针对自己家的主控的修改

一般来说主要是针对网口的灯做一些定制,这部分就要通过查看PHY芯片的手册,修改对应的寄存器的值,phy_register_fixup_for_uid 函数,这是一个linux 中的通用函数,用于修正设置指定uid的PHY,比如:

topeet@ubuntu:~/RK_android11/rk_android11.0_sdk_211130/kernel$ git diff drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index cff46c49b72f..b08899e69dea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -58,6 +58,13 @@#define        STMMAC_ALIGN(x)         ALIGN(ALIGN(x, SMP_CACHE_BYTES), 16)#define        TSO_MAX_BUFF_SIZE       (SZ_16K - 1)+
+#define RTL_8211F_PHY_ID 0x001cc916
+#define RTL_8211F_PHY_ID_MASK 0x001fffff
+#define RTL_8211F_PAGE_SELECT 0x1f
+#define RTL_8211F_LCR_ADDR 0x10
+#define RTL_8211F_EEELCR_ADDR 0x11
+/* Module parameters */#define TX_TIMEO       5000static int watchdog = TX_TIMEO;
@@ -4260,6 +4267,30 @@ static int stmmac_hw_init(struct stmmac_priv *priv)return 0;}+static int phy_rtl8211f_led_fixup(struct phy_device *phydev)
+{
+       u32 val, val2;
+       pr_info("terry in : %s\n", __func__);
+       /*switch to page0xd04*/
+       phy_write(phydev, RTL_8211F_PAGE_SELECT, 0xd04);
+       /*set led1(green) Link 10/100/1000M, and set led2(yellow) Link
+       10/100/1000M+Active*/
+       val = phy_read(phydev, RTL_8211F_LCR_ADDR);
+       val |= (1<<5);
+       val |= (1<<8);
+       val &= (~(1<<9));
+       val |= (1<<10);
+       val |= (1<<11);
+       phy_write(phydev, RTL_8211F_LCR_ADDR, val);
+       /*set led1(green) EEE LED function disabled so it can keep on when linked*/
+       val2 = phy_read(phydev, RTL_8211F_EEELCR_ADDR);
+       val2 &= (~(1<<2));
+       phy_write(phydev, RTL_8211F_EEELCR_ADDR, val2);
+       /*switch back to page0*/
+       phy_write(phydev,RTL_8211F_PAGE_SELECT, 0xa42);
+       return 0;
+}
+/*** stmmac_dvr_probe* @device: device pointer
@@ -4452,6 +4483,11 @@ int stmmac_dvr_probe(struct device *device,netdev_warn(priv->dev, "%s: failed debugFS registration\n",__func__);#endif
+       /* register the PHY board fixup */
+       ret = phy_register_fixup_for_uid(RTL_8211F_PHY_ID, RTL_8211F_PHY_ID_MASK, phy_rtl8211f_led_fixup);
+       if (ret) {
+               dev_warn(priv->device, "Cannot register PHY board fixup, terry in :%s.\n", __func__);
+       }return ret;

另外还可以使用ethtool工具去修改

20.调节红外遥控

21.emmc

22.nfc

23.串口

异步全双工,低–>高
通用异步收发器即通用的串行、异步通信总线,该总线有两条数据线,实现全双工的发送和接收
在这里插入图片描述
说明:一次只能发送一个字节,检验位可以有可以无,每次发送都是这样的格式

串口通信存在的问题:
1)串口只是规定了协议,即帧格式,用高电平表示1,低电平表示0,但是在不同的处理器中这个定义是不一样的机电气特性不一样,所以这两个处理器是不能直接连
2)抗干扰能力差,使用的是 TTL 信号表示0和1,
3)通信距离短,只能用于一个电路板上的两个不同芯片之间的通信

由于串口通信存在的问题就出现了RS232、RS485协议,但是软件编程还是串口那样编程,因为改的只是硬件上的电性

24.IIC

串行同步半双工 高---->低
起始:在SCL为高电平时,SDA由高变低
停止:在SCL为高电平时,SDA由低变高

时序
在这里插入图片描述

25.SPI

全双工、同步串行,高—>低
在这里插入图片描述

26.PWM

27.mipi

MIPI(Mobile Industry Processor Interface)
MIPI联盟下面有不同的WorkGroup,分别定义了一系列的手机内部接口标准,比如:
摄像头接口CSI(DisplaySerialInterface)、
显示接口DSI(DisplayCommandSet)、
射频接口DigRF、
麦克风/喇叭接口SLIMbus等
可以看出无论是CSI还是DSI还是其他都是mipi接口

MIPI CSI2一般会有1对I2C通信引脚,1对MIPI差分时钟引脚和1~4对MIPI差分数据信号引脚,如图所示:
在这里插入图片描述

28.secure boot

29.JNI AIDL

30.ALSA

31.rtc

RTC中文叫实时时钟,是Linux内核比较简单的字符驱动,Linux系统中一切于时间有关的功能都依赖于RTC

在这里插入图片描述

hwclock -f /dev/rtc0 -w

代码流程:
在这里插入图片描述
主要是通过IIC通信,然后初始化RTC芯片,设置函数操作集rtc_class_ops,该函数里的函数指针会对应到接口文件的函数,这样上层就可以去读取、设置rtc时间

32. iio

33.看门狗

看门狗有内部看门狗、外部看门狗
作用:防止代码跑偏,死机,能狗重启.
原理:
外部看门狗,一上电就会计时,如果在规定的时间内,主控主芯片没有去改变外部看门狗芯片的电平(该步骤叫喂狗),就会产生一个复位电平到主控芯片,从而复位。
内部看门狗,也叫软件看门狗,通过软件定时器模拟的喂狗操作,可以通过提供的接口文件去改变设置喂狗的时间。

通常:
喂狗需要在u-boot和kernel两个地方喂狗

相关文章:

驱动开发面试复习

创建字符设备 1 创建设备号 alloc_chrdev_region 2.创建cdev cdev_init 3.添加一个 cdev,完成字符设备注册到内核 cdev_add 4.创建类 class_create 5.创建设备 device_create 1.内核空间与用户空间数据 copy_from_user 和copy_to_user 俩个函数来完成。 copy_from_user 函数…...

监测数据计算与换算:确保工程安全的关键步骤

在工程项目中&#xff0c;监测数据的计算与换算是一项至关重要的工作&#xff0c;它直接关系到工程的安全与稳定。本文将从确定基准值、数据计算与换算、异常值处理以及数据存储等方面&#xff0c;探讨监测数据计算与换算的主要工作内容。 添加图片注释&#xff0c;不超过 140 …...

Vue项目实战--空间论坛(1)

环境准备 安装好node.js,Vue后 添加插件 router---路由&#xff0c;多页面的应用 vuex---在多个组件之间维护同一个数据 添加依赖 bootstrap---美工 popperjs/core vue项目介绍 views-----对应vue文件&#xff0c;页面 router-----路由&#xff0c;页面&#xff0c;c…...

linux内核驱动——字符设备实现两个终端单向收发

linux内核驱动——字符设备实现两个终端单向收发 参考 Ubuntu18.04添加内核模块&#xff08;字符设备&#xff09; 创建内核驱动文件chat_dev.c&#xff1a; #include <linux/init.h> //定义了module_init #include <linux/module.h> //最基本的头文件&a…...

读取CSV数据并写入MySQL

import pandas as pd #import tushare as ts from sqlalchemy import create_engineimport baostock as bs #### 登陆系统 #### lg bs.login() # 显示登陆返回信息 print(login respond error_code:lg.error_code) print(login respond error_msg:lg.error_msg) #### 获取沪深…...

centos7.4下升级最新的ssh

一 安装telnet服务器 安装telnet服务器目的&#xff0c;防止我们升级失败的时候&#xff0c;可以通过telnet登录&#xff0c;而不至于上机房。 由于我们是临时启动&#xff0c;所以只要简单的使用&#xff0c;不要通过xinetd来进行守护。 命令如下&#xff1a; yum -y install …...

Java实现的双向链表示例

双向链表&#xff08;Doubly Linked List&#xff09;是一种链式数据结构&#xff0c;每个节点都包含两个指针&#xff0c;一个指向前一个节点&#xff0c;一个指向后一个节点。双向链表与单向链表相比&#xff0c;除了有前向指针外&#xff0c;还有一个额外的后向指针&#xf…...

生物电信号测量技术

引言 生物电信号是生物体内的电活动产生的电流或电压信号&#xff0c;它反映了生物体的生理状态和活动。生物电信号测量技术是一种用于记录和分析这些信号的方法&#xff0c;广泛应用于医学、生物学、神经科学等领域。本文将介绍几种常见的生物电信号测量技术&#xff0c;并讨…...

【开源】JAVA+Vue.js实现创意工坊双创管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员端2.2 Web 端2.3 移动端 三、系统展示四、核心代码4.1 查询项目4.2 移动端新增团队4.3 查询讲座4.4 讲座收藏4.5 小程序登录 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的创意工坊双创管理…...

Python基于opencv的人脸识别上课签到考勤系统,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…...

ucode usage使用方法

需结合代码和main函数的命令行去快速理解该库&#xff1b; main.c 和example中的代码示例 源代码的地址&#xff1a;https://github.com/jow-/ucode.git 翻译地址&#xff1a;https://github.com/jow-/ucode/blob/master/docs/tutorials/01-usage.md ucode命令行提供了一系列的…...

HCIA-HarmonyOS设备开发认证V2.0-习题

目录 习题一习题二习题三&#xff08;待续...&#xff09;坚持就有收获 习题一 # HarmonyOS简介 1. 以下哪几项属于OpenHarmony的技术特性&#xff1f;&#xff08;&#xff09;A. 统一OS&#xff0c;弹性部署B. 一次开发&#xff0c;多端部署C. 硬件互助&#xff0c;资源共享…...

【深度学习笔记】优化算法——随机梯度下降

随机梯度下降 在前面的章节中&#xff0c;我们一直在训练过程中使用随机梯度下降&#xff0c;但没有解释它为什么起作用。为了澄清这一点&#xff0c;我们刚在 :numref:sec_gd中描述了梯度下降的基本原则。本节继续更详细地说明随机梯度下降&#xff08;stochastic gradient d…...

oss-fuzz-gen:一款基于LLM的模糊测试对象生成与评估框架

关于oss-fuzz-gen oss-fuzz-gen是一款基于LLM的模糊测试对象生成与评估框架&#xff0c;该工具可以帮助广大研究人员使用多种大语言模型&#xff08;LLM&#xff09;生成真实场景中的C/C项目以执行模糊测试。 该工具基于Google的OSS-Fuzz平台实现其功能&#xff0c;并对生成的…...

深度神经网络 基本知识 记录

资料&#xff1a;https://www.bilibili.com/video/BV1K94y1Z7wn/?spm_id_from333.337.search-card.all.click&vd_source14a476de9132ba6b2c3cbc2221750b99 计划&#xff1a;3~4天 杂 人工智能包括ML&#xff0c;ML包括DL机器学习需要人工大量参与&#xff0c;DL模拟人的…...

基于Springboot免费搭载轻量级阿里云OSS数据存储库(将本地文本、照片、视频、音频等上传云服务保存)

一、注册阿里云账户 打开https://www.aliyun.com/&#xff0c;申请阿里云账户并完成实名认证&#xff08;个人&#xff09;。这种情况就是完成了&#xff1a; 二、开通OSS服务 点击立即开通即可。 三、创建Bucket 申请id和secert&#xff1a; 进去创建一个Accesskey就会出现以…...

RK3568 Android12 适配抖音 各大APP

RK3568 Android12 适配抖音 各大APP SOC RK3568 system:Android 12 平台要适配抖音和各大APP 平台首先打开抖音发现摄像头预览尺寸不对只存在右上角,我将抖音APP装在手机上预览,发现是全屏 一开始浏览各大博客 给出的解决方法是修改framework 设置为全屏显示: framewo…...

[渗透教程]-022-内网穿透的高性能的反向代理应用

frp 简介 frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 项目地址 https://github.com/fatedier/frp安装 linux 配置方式见如下链接🔗 frp安装配置…...

【计算机网络】深度学习HTTPS协议

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【计算机网络】深度学习HTTPS协议 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一:HTTPS是什么二:HTTPS的工作过程三:对称加密四:非对称加密五:中间人攻击1…...

C盘新建的文件夹内需要管理员权限才能新建和删除解决问题记录

命令行输入命令gpedit.msc 如果执行成功那么直接看第二步 如果出现不存在此文件 那么用记事本将一以下代码粘贴进去&#xff0c;后缀命名为cmd。文件名无所谓&#xff0c;双击运行 echo offpushd "%~dp0"dir /b C:\Windows\servicing\Packages\Microsoft-Windows-Gr…...

2024年【道路运输企业安全生产管理人员】考试报名及道路运输企业安全生产管理人员免费试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 道路运输企业安全生产管理人员考试报名参考答案及道路运输企业安全生产管理人员考试试题解析是安全生产模拟考试一点通题库老师及道路运输企业安全生产管理人员操作证已考过的学员汇总&#xff0c;相对有效帮助道路运…...

四面体单元悬臂梁的Matlab有限元编程 | 实体单元 | Matlab源码 | 理论文本

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…...

BurpSuite2024.2.1

1.更新介绍 此版本引入了特定的API 扫描功能&#xff0c;并将 Bambdas 合并到 Logger 捕获过滤器中。我们还改进了 DOM Invader 和 Burp Suite 导航记录器的功能&#xff0c;并进行了许多其他改进和错误修复。 API扫描 我们引入了特定的 API 扫描功能。您现在可以上传 OpenAP…...

【投稿优惠|火热征稿】2024年计算机技术与自动化发展国际会议 (ICCTAD 2024)

2024年计算机技术与自动化发展国际会议 (ICCTAD 2024) 2024 International Conference on Computer Technology and Automation Development (ICCTAD 2024) 【会议简介】 2024年计算机技术与自动化发展国际会议( ICCTAD 2024)将在中国武汉盛大开幕&#xff01;这是一场在自动化…...

LeetCode.232. 用栈实现队列

题目 232. 用栈实现队列 分析 先了解一下栈和队列的特点&#xff1a; 栈&#xff1a;先进后出队列&#xff1a;先进先出 想用栈实现队列的特点&#xff0c;就需要使用两个栈。因为两个栈就可以将列表倒序。 假设第一个栈 s1 [1,2,3]&#xff0c;第二个栈 s2 [] 。若循环…...

SpringBoot集成ElasticSearch(ES)

ElasticSearch环境搭建 采用docker-compose搭建&#xff0c;具体配置如下&#xff1a; version: 3# 网桥es -> 方便相互通讯 networks:es:services:elasticsearch:image: registry.cn-hangzhou.aliyuncs.com/zhengqing/elasticsearch:7.14.1 # 原镜像elasticsearch:7.…...

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用

基于STC12C5A60S2系列1T 8051单片机的TM1638键盘数码管模块的数码管显示应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍TM1638键盘数码管模块概述TM1638键盘数码管…...

Qt插件之输入法插件的构建和使用(一)

文章目录 输入法概述输入法插件实现及调用输入键盘搭建定义样式自定义按钮实现自定义可拖动标签数字符号键盘候选显示控件滑动控件手绘输入控件输入法概述 常见的输入法有三种形式: 1.系统级输入法 2.普通程序输入法 3.程序自带的输入法 系统级输入法就是咱们通常意义上的输入…...

慢SQL调优-索引详解

Mysql 慢SQL调优-索引详解 前言一、慢查询日志设置二、explain查看执行计划三、索引失效四、索引操作五、profile 分析执行耗时 前言 最新的 Java 面试题&#xff0c;技术栈涉及 Java 基础、集合、多线程、Mysql、分布式、Spring全家桶、MyBatis、Dubbo、缓存、消息队列、Linu…...