ILI2511触摸驱动EMC测试内核栈崩溃问题排查求助
ILI2511触摸驱动EMC测试崩溃定位与驱动适配求助
背景
我们使用ILI2511触摸控制器,触摸触发中断后主机通过I2C轮询获取数据。EMC测试期间,控制器频繁触发中断并上报错误触摸位置,但内核出现栈崩溃panic。相关代码片段:
中断初始化代码
error = devm_request_threaded_irq(dev, client->irq, NULL, ili251x_irq, IRQF_ONESHOT, client->name, data);
中断底半部处理代码
static irqreturn_t ili251x_irq(int irq, void *irq_data) { struct ili251x_data *data = irq_data; struct i2c_client *client = data->client; struct touchdata touchdata; int error; error = ili251x_read_reg(client, REG_TOUCHDATA, &touchdata, sizeof(touchdata) - sizeof(struct finger)*TOUCHDATA2_FINGERS); /* more code */ if (!error) ili251x_report_events(data, &touchdata); else dev_err(&client->dev, "Unable to get touchdata, err = %d\n", error); return IRQ_HANDLED; }
ili251x_read_reg()调用I2C控制器完成数据读取。
崩溃转储信息
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ili251x_irq+0x200/0x2e4 [ 691.053700] 000: CPU0: stopping [ 691.056854] 000: CPU: 0 PID: 0 Comm: swapper/0 Tainted: G O 5.4.106-rt54-ge578cc0824 #1 [ 691.066197] 000: Hardware name: Generic DRA74X (Flattened Device Tree) [ 691.072749] 000: Backtrace: [ 691.075634] 000: [ 691.077561] 000: [<c0b93090>] (dump_backtrace) from [<c0b93408>] (show_stack+0x20/0x24) [ 691.085606] 000: r7:c120dd44 r6:60000193 r5:00000000 r4:c12996e4 [ 691.091718] 000: [<c0b933e8>] (show_stack) from [<c0ba0d04>] (dump_stack+0x98/0xac) [ 691.099408] 000: [<c0ba0c6c>] (dump_stack) from [<c0210798>] (handle_IPI+0x404/0x47c) [ 691.107275] 000: r7:c120dd44 r6:00000004 r5:c129ebc4 r4:c12a8270 [ 691.113387] 000: [<c0210394>] (handle_IPI) from [<c0202340>] (gic_handle_irq+0x9c/0xa0) [ 691.121428] 000: r10:c12a8000 r9:c1201ed0 r8:fa213000 r7:fa212000 r6:fa21200c r5:c125a574 [ 691.129722] 000: r4:c120df34 [ 691.132694] 000: [<c02022a4>] (gic_handle_irq) from [<c0201a78>] (__irq_svc+0x58/0xa0) [ 691.140643] 000: Exception stack(0xc1201ed0 to 0xc1201f18) [ 691.146148] 000: 1ec0: 00000000 0041cd04 00000000 c022879c [ 691.154793] 000: 1ee0: c1200000 c120d730 00000000 c120d778 c129e63d c105ea48 c12a8000 c1201f2c [ 691.163437] 000: 1f00: c1201f0c c1201f20 c02283fc c0209b34 a0000013 ffffffff [ 691.170513] 000: r9:c1200000 r8:c129e63d r7:c1201f04 r6:ffffffff r5:a0000013 r4:c0209b34 [ 691.178719] 000: [<c0209b04>] (arch_cpu_idle) from [<c0ba713c>] (default_idle_call+0x3c/0x48) [ 691.187282] 000: [<c0ba7100>] (default_idle_call) from [<c026ced8>] (do_idle+0xe4/0x150) [ 691.195407] 000: [<c026cdf4>] (do_idle) from [<c026d26c>] (cpu_startup_entry+0x28/0x2c) [ 691.203444] 000: r9:c105ea48 r8:00000001 r7:c12a8000 r6:00000000 r5:00000002 r4:000000ce [ 691.211649] 000: [<c026d244>] (cpu_startup_entry) from [<c0ba0ee4>] (rest_init+0xd4/0xdc) [ 691.219859] 000: [<c0ba0e10>] (rest_init) from [<c1000b88>] (arch_call_rest_init+0x18/0x1c) [ 691.228249] 000: r5:00000001 r4:c12a8054 [ 691.232268] 000: [<c1000b70>] (arch_call_rest_init) from [<c10010e0>] (start_kernel+0x4dc/0x51c) [ 691.241091] 000: [<c1000c04>] (start_kernel) from [00000000>] (0x0) [ 691.247478] 001: ---[ end Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ili251x_irq+0x200/0x2e4 ]--- [ 691.259201] 001: ------------[ cut here ]------------
当前使用5.4.y RT内核,驱动来自社区的ili251x版本;尝试上游ili210x驱动可生成输入数据但触摸无响应,ilitek_ts_i2c驱动不支持ILI2511,另有第三方ILI2511驱动未测试。
一、内核栈崩溃定位方法
1. 理解崩溃信息中的地址含义
ili251x_irq+0x200/0x2e4 解析:
ili251x_irq:触发崩溃的中断处理函数名称+0x200:崩溃发生在该函数起始地址偏移0x200字节的位置0x2e4:整个ili251x_irq函数的总长度(字节)
即崩溃点位于函数执行到约70%的位置。
2. 定位具体代码行
使用addr2line工具结合带调试符号的内核镜像,将虚拟地址转换为代码行:
# 先获取ili251x_irq的起始地址,加上0x200得到崩溃地址 addr2line -e vmlinux <崩溃虚拟地址>
3. 重点排查方向
- I2C读取异常:EMC干扰可能导致
ili251x_read_reg读取到错误长度的数据,破坏栈上的touchdata结构体,进而覆盖栈保护字。需检查ili251x_read_reg的返回值处理,确保实际读取字节数与请求长度一致。 - 栈变量安全:将栈上的
struct touchdata touchdata改为堆分配(用devm_kzalloc),避免栈空间被异常数据溢出覆盖。 - RT内核中断栈:RT内核的中断栈通常较小,频繁中断可能导致栈溢出,可检查内核配置中
CONFIG_IRQ_STACK_SIZE的值是否足够。 - 数据校验:在读取触摸数据后添加合法性校验(比如坐标范围、触摸点数是否合理),避免错误数据流入事件上报逻辑。
二、ILI2511驱动适配建议
1. 修复现有ili251x驱动
- 增强
ili251x_read_reg的错误处理:校验实际读取的字节数,若与请求长度不符则返回错误,不处理无效数据。 - 迁移栈变量到堆:把
struct touchdata改为堆分配,减少栈溢出风险。 - 添加数据合法性校验:在调用
ili251x_report_events前,检查触摸数据的坐标、点数是否在合理范围内。
2. 适配上游ili210x驱动
从hexdump的输入事件对比看,两个驱动的事件类型和格式存在差异:
- ili251x上报
EV_MSC(类型0x03)事件,而ili210x上报EV_ABS(类型0x02)事件 - 需修改ili210x驱动的触摸数据解析逻辑,匹配ILI2511的寄存器输出格式;同时调整输入设备的初始化参数(如ABS_X/ABS_Y的范围),确保用户空间能正确识别触摸事件。
3. 测试第三方驱动
尝试移植NewhavenDisplay提供的ILI2511专用驱动到5.4 RT内核,注意适配内核API差异(比如I2C传输函数、输入子系统接口)。
内容的提问来源于stack exchange,提问作者Christian Leeb
相关产品推荐
相关产品推荐

