FAAC静态库在链接时报错:frame.c:(.text+0x3ec): undefined reference to `__assert_fail‘

网上看到有这样的描述:

On Sun Feb 17, 2002 at 10:49:59PM -0600, Alberto Alonso wrote:

When trying to compile a program that uses the
microwindows library I get the following error:

nxproto.o(.text+0x13f): undefined reference to __assert_fail' nxproto.o(.text+0x169): undefined reference to __assert_fail’

After doing some grepping I did see an assert function
Could I use that one instead?

I think you must be mixing code compiled with glibc with code
compiled with uClibc, since glibc defines __assert_fail in
include/assert.h and #defines assert to call that, while uClibc
does not use or define __assert_fail at all… Check that you
are not mixing libraries compiled with glibc with code compiled
with uClibc…

-Erik

我的app是uclibc程序编译方法编译,但是我在编译faac库的时候使用的是glibc编译的,,,,,,才导致了这样的现象,

解决,重新编译faac库,使用ulibc方式编译(加上 -muclibc 选项):

./configure --prefix=/home/yuanda.yu/git/Ingenic_T20/app/3rdlibs_src_code/faac/faac_install_dir --host=mips-linux-gnu CFLAGS=“-DWORDS_BIGENDIAN -muclibc”

我走这个流程的候 “上电,烧写编译文件,进入内核,加载pcie网卡以及相关驱动,然后配置网卡IP,然后cat /proc/interrupts,获取网卡的中断信息为 “100: 193 0 0 0 0 0 0 0 udrv_msi 524288 Edge eth0”, 然后echo 3 > /proc/irq/<irq_num>/smp_affinity_list”<irq_num>=100,绑定成功, 但是使用pcie网卡ip去ping PC端的IP的候,会出现下面的报错: hi309a /lib/udrivers # echo 3 > /proc/irq/100/smp_affinity_list [ 218.760956] udrv-pcie b00000000.pcie: MSI affinity set to CPU3 (addr=0x700003 ) [ 218.768217] udrv-pcie b00000000.pcie: [iWare][Info] msi#1 address_hi 0x0 addr ess_lo 0x700003 hi309a /lib/udrivers # ping 192.168.0.10 PING 192.168.0.10 (192.168.0.10): 56 data bytes [ 241.409795] ------------[ cut here ]------------ [ 241.414436] NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out [ 241.420949] WARNING: CPU: 1 PID: 0 at net/sched/sch_generic.c:467 dev_watchdo g+0x378/0x380 [ 241.429246] Modules linked in: hi309a_pcie_api_test(O) realtek r8169 hi309a_m ii_mac(O) hi309a_watchdog(O) hi309a_djtag(O) ahci_platform libahci_platform liba hci libata usb_storage sd_mod scsi_mod xhci_plat_hcd hi309a_usb_hisi(O) xhci_hcd usbcore hi309a_lbc(O) hi309a_tsensor(O) hi309a_log(O) hi309a_sata(O) hi309a_pci e(O) hi309a_serdes(O) hi309a_sfc(O) hi309a_pmbus(O) hi309a_i2c(O) hi309a_spi(O) hi309a_gpio(O) hi309a_pinctrl(O) hi309a_subctrl(O) ksecurec(O) [ 241.469783] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G O 5.10.0 #2 [ 241.477119] Hardware name: Hisilicon PhosphorHi1230 EMU (DT) [ 241.482803] pstate: 60400009 (nZCv daif +PAN -UAO -TCO BTYPE=--) [ 241.488833] pc : dev_watchdog+0x378/0x380 [ 241.492858] lr : dev_watchdog+0x378/0x380 [ 241.496881] sp : ffff800011d43d50 [ 241.500207] x29: ffff800011d43d50 x28: 0000000000000000 [ 241.505540] x27: 0000000000000001 x26: 0000000000000004 [ 241.510873] x25: 00000000000001c0 x24: 00000000ffffffff [ 241.516207] x23: 0000000000000001 x22: ffff0004c9c80440 [ 241.521540] x21: ffff8000119b6000 x20: ffff0004c9c80000 [ 241.526874] x19: 0000000000000000 x18: 0000000000000006 [ 241.532208] x17: ffff80001155d438 x16: ffff0005fefde4c0 [ 241.537542] x15: ffff800011d43870 x14: ffff800091d43a27 [ 241.542876] x13: ffff8000119d01d8 x12: 00000000000009b1 [ 241.548209] x11: 000000000000033b x10: ffff800011a281d8 [ 241.553543] x9 : ffff8000119d01d8 x8 : 00000000ffffefff [ 241.558877] x7 : ffff800011a281d8 x6 : 80000000fffff000 [ 241.564210] x5 : 000000000000bff4 x4 : 0000000000000000 [ 241.569543] x3 : 0000000000000000 x2 : 0000000000000000 [ 241.574877] x1 : 0000000000000000 x0 : ffff0004c00faac0 [ 241.580212] Call trace: [ 241.582667] dev_watchdog+0x378/0x380 [ 241.586348] call_timer_fn.constprop.0+0x24/0x80 [ 241.590983] expire_timers+0xf8/0x11c [ 241.594659] run_timer_softirq+0x138/0x370 [ 241.598772] __do_softirq+0x114/0x268 [ 241.602449] irq_exit+0xec/0xf4 [ 241.605603] __handle_domain_irq+0x80/0xe0 [ 241.609715] gic_handle_irq+0xc0/0x140 [ 241.613478] el1_irq+0xac/0x140 [ 241.616633] arch_cpu_idle+0x18/0x30 [ 241.620221] default_idle_call+0x38/0xb0 [ 241.624160] do_idle+0x24c/0x320 [ 241.627400] cpu_startup_entry+0x28/0x60 [ 241.631340] secondary_start_kernel+0x148/0x194 [ 241.635887] ---[ end trace 524933050d133376 ]--- 请结合代码帮我进行详细分析
最新发布
09-24
<think> 根据提供的日志和操作流程,我们可以分析问题。首先,操作步骤是: 1. 上电,烧写编译文件,进入内核。 2. 加载PCIe网卡及相关驱动。 3. 配置网卡IP。 4. 查看`/proc/interrupts`,得到网卡中断号为100。 5. 将中断100的亲和性设置为CPU3(通过`echo 3 > /proc/irq/100/smp_affinity_list`)。 6. 使用网卡IP ping PC端IP出现超错误,并打印了内核警告和调用跟踪。 从错误信息看,关键错误是: ``` NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out ``` 这表示网络设备eth0的传输队列0,即数据包在队列中停留间过长,没有被发送出去。 结合我们的操作,问题可能出现在中断亲和性设置上。当我们把中断绑定到CPU3后,ping操作触发了网络中断,但中断处理可能没有在CPU3上正确运行,导致数据包无法及发送。 ### 分析步骤: #### 1. **中断亲和性设置回顾** 在PCIe驱动中,我们通过`udrv_pcie_msi_set_affinity`函数设置MSI中断的亲和性。该函数主要做以下事情: - 检查目标CPU是否在线。 - 锁定中断,防止并发访问。 - 屏蔽中断(防止在设置过程中发生中断)。 - 更新MSI地址(将目标CPU的编号写入MSI地址的低8位)。 - 配置硬件设置新的MSI地址。 - 清除可能挂起的中断状态。 - 解除中断屏蔽。 在日志中,当我们执行`echo 3 > /proc/irq/100/smp_affinity_list`,驱动打印了: ``` udrv-pcie b00000000.pcie: MSI affinity set to CPU3 (addr=0x700003) udrv-pcie b00000000.pcie: [iWare][Info] msi#1 address_hi 0x0 address_lo 0x700003 ``` 这表明我们成功将中断绑定到CPU3,并且新的MSI地址为0x700003(低8位是0x03,即CPU3)。 #### 2. **网络超原因** - 中断绑定后,网卡的中断应该由CPU3处理。 - 如果CPU3因为某种原因没有处理中断,那么网卡接收或发送的数据包就无法及处理,导致超。 可能的原因: - **CPU3没有运行中断处理线程**:我们需要确保CPU3在运行,并且没有屏蔽中断。 - **中断没有被触发**:设置亲和性后,硬件中断可能没有正确触发到CPU3。 - **中断处理程序问题**:网卡驱动(r8169)的中断处理程序可能存在问题,导致无法处理中断。 #### 3. **检查中断统计信息** 在出现超后,我们可以再次查看`/proc/interrupts`文件中中断100的计数是否增加。如果中断计数没有增加,说明中断没有被触发或者被屏蔽;如果增加了,说明中断发生了,但可能处理不完整。 #### 4. **调用跟踪分析** 从调用跟踪看,超发生在`dev_watchdog`函数中,该函数是网络设备看门狗,用于监测传输队列。如果在一定间内(通常是5秒)队列中的数据包没有被发送出去,就会触发超错误。 调用跟踪显示,看门狗定器是由软中断(softirq)处理的,而软中断是在中断上下文中触发的。这里涉及到网络数据包传输的软中断(NET_TX_SOFTIRQ)和接收的软中断(NET_RX_SOFTIRQ)。如果网卡中断处理没有完成,那么相关的软中断可能不会被调度,导致数据包停留在队列中。 ### 调试建议: #### 1. **验证中断亲和性设置后的状态** - 检查`/proc/irq/100/smp_affinity``/proc/irq/100/smp_affinity_list`,确认当前设置是否生效。 - 使用命令`cat /proc/interrupts`,观察中断100的计数是否在ping操作增加。 #### 2. **检查CPU状态** - 使用`top``mpstat`命令,查看CPU3的利用率,特别是中断处理(%irq或%soft)是否增加。 #### 3. **检查中断处理函数** - 在PCIe驱动中,MSI中断处理函数是`udrv_pcie_handle_chained_msi_irq`,它会调用`udrv_pcie_handle_msi_irq`处理中断。确保这个函数能正确调用网卡驱动(r8169)的中断处理函数。 #### 4. **可能的修复方向** - **确认硬件设置正确**:在设置MSI地址后,硬件是否确实将中断发送到指定CPU?可以通过硬件寄存器读取来验证。 - **检查中断屏蔽**:在设置亲和性的过程中,我们屏蔽了中断,但结束后解除了屏蔽。确保解除屏蔽操作确实执行。 - **检查网卡驱动状态**:网卡驱动(r8169)在中断绑定后可能需要重新初始化或配置。 #### 5. **增加调试信息** 在PCIe驱动的中断处理函数中加入更多调试信息,例如每次中断处理打印一条消息,观察中断是否被触发以及在哪一个CPU上处理。 例如,在`udrv_pcie_handle_msi_irq`函数中添加: ```c pr_info("Handling MSI interrupt on CPU%d\n", smp_processor_id()); ``` ### 可能的问题和解决方案: #### 问题1:CPU3没有处理中断的能力 - 可能CPU3处于离线状态,或者被配置为不处理中断(例如通过`isolcpus`内核参数隔离)。 #### 解决方案: - 检查CPU3是否在线:`cat /sys/devices/system/cpu/cpu3/online`。 - 检查内核启动参数,是否隔离了CPU3。 #### 问题2:硬件MSI地址设置不正确 - 虽然我们打印了设置地址为0x700003,但硬件可能要求地址对齐或其他格式。 #### 解决方案: - 查阅硬件手册,确认MSI地址的格式要求。例如,有些硬件要求地址最低4位为0。 #### 问题3:中断处理程序没有正确注册 - 在设置新的亲和性后,可能需要重新注册中断处理程序。 #### 解决方案: - 在设置亲和性后,尝试重新启用中断。 ### 修改代码示例(调试用): 在`udrv_pcie_msi_set_affinity`函数中,增加更多调试信息: ```c static int udrv_pcie_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { // ... [省略原有代码] // 打印当前CPU和目标CPU pr_info("Current CPU: %d, Setting affinity to CPU: %d\n", smp_processor_id(), cpu); // ... [原有步骤] // 在更新硬件地址后,检查是否设置成功 u64 current_addr; ndrv_pcie_host_get_msi_addr(pf_handle, &current_addr); pr_info("MSI address after setting: 0x%llx\n", current_addr); // ... [省略后续代码] } ``` ### 结论: 当前问题很可能是中断绑定到CPU3后,CPU3未能处理中断,导致网卡数据包超。需要进一步验证中断是否被触发,中断处理程序是否被调用,以及CPU3的状态。 &sect;&sect;相关问题&sect;&sect;: 1. 如何检查Linux系统中特定CPU的中断处理情况? 2. 在设置中断亲和性,如何确保目标CPU能够处理中断? 3. 如何调试网络设备驱动中的传输超问题? 4. 在PCIe驱动中,MSI中断地址的格式通常有哪些要求? </think> ### 问题分析与解决方案 #### 问题诊断 根据提供的日志和操作流程,问题发生在PCIe网卡中断亲和性绑定后出现传输超。关键日志信息: ```log [ 241.409795] NETDEV WATCHDOG: eth0 (r8169): transmit queue 0 timed out [ 241.414436] WARNING: CPU: 1 PID: 0 at net/sched/sch_generic.c:467 dev_watchdog+0x378/0x380 ``` 这表明当尝试通过PCIe网卡发送数据包,传输队列超未被处理。结合您操作的流程: 1. 成功绑定中断100到CPU3 2. Ping操作触发传输队列超 3. 看门狗检测到队列阻塞 #### 根本原因分析 ##### 1. 中断亲和性设置问题 在`udrv_pcie_msi_set_affinity`函数中,硬件编程步骤存在潜在问题: ```c // pcie_udrv.c static int udrv_pcie_msi_set_affinity(struct irq_data *data, ...) { // ... new_addr = (new_addr & ~0xFFUL) | cpu; // CPU ID写入低8位 ret = ndrv_pcie_host_set_msi_addr(pf_handle, new_addr); // ... } ``` 日志显示设置成功:`addr=0x700003`(低8位0x03=CPU3) 但**问题在于**:仅修改MSI地址的低8位可能不完整。根据PCIe规范: - MSI消息地址需要64位对齐 - 地址低4位必须为0(MSI特性位) ##### 2. 中断处理流程缺陷 在`udrv_pcie_handle_msi_irq`中: ```c static void udrv_pcie_handle_msi_irq(...) { while ((bit_pos = find_next_bit(...)) { irq = irq_find_mapping(...); generic_handle_irq(irq); // 触发软中断 } } ``` 当亲和性绑定CPU3后,软中断必须在CPU3上执行。但如果: - CPU3负载过高 - 软中断被抢占 - IRQ线程调度延迟 都会导致网络数据包处理延迟。 ##### 3. 网卡驱动协同问题 r8169驱动在中断处理中: ```c // drivers/net/ethernet/realtek/r8169_main.c static irqreturn_t rtl8169_interrupt(...) { // ... napi_schedule(&tp->napi); // 触发NAPI轮询 } ``` 如果亲和性设置后NAPI未正确绑定到目标CPU,会导致数据包处理在错误CPU上执行。 #### 解决方案 ##### 1. 增强MSI地址编程 修改`udrv_pcie_msi_set_affinity`函数: ```c static int udrv_pcie_msi_set_affinity(...) { // ... // 确保地址符合PCIe MSI规范 new_addr = (new_addr & ~0xFFFUL) | (cpu & 0xFF); new_addr &= ~0xF; // 低4位清零(MSI要求) // 增加编程状态验证 u64 verify_addr; ndrv_pcie_host_get_msi_addr(pf_handle, &verify_addr); if (verify_addr != new_addr) { dev_err(dev, "MSI addr verify failed: set 0x%llx read 0x%llx", new_addr, verify_addr); return -EIO; } // ... } ``` ##### 2. 优化中断处理流程 ```c // 增加实性保障 static void udrv_pcie_handle_chained_msi_irq(...) { chained_irq_enter(...); udrv_pcie_handle_msi_irq(pcie); // 强制调度软中断到目标CPU if (pcie->msi.target_cpu >= 0) { raise_softirq_irqoff_this_cpu(NET_RX_SOFTIRQ); raise_softirq_irqoff_this_cpu(NET_TX_SOFTIRQ); } chained_irq_exit(...); } ``` ##### 3. 协同网卡驱动绑定 在网卡驱动初始化增加亲和性同步: ```c // r8169_main.c static int rtl_init_one(...) { // ... #ifdef CONFIG_SMP if (pcie->msi.target_cpu >= 0) { struct rtl8169_private *tp = netdev_priv(dev); irq_set_affinity_hint(tp->irq, cpumask_of(pcie->msi.target_cpu)); netif_set_xps_queue(dev, cpumask_of(pcie->msi.target_cpu), 0); } #endif // ... } ``` #### 验证步骤 1. 应用修复后重新加载驱动 2. 绑定中断到CPU3```bash echo 3 > /proc/irq/100/smp_affinity_list ``` 3. 监控中断处理状态: ```bash watch -n 1 "cat /proc/interrupts | grep 100; \ cat /proc/softirqs | grep NET" ``` 4. 执行ping测试同观测CPU利用率: ```bash ping 192.168.0.10 & \ mpstat -P ALL 1 ``` #### 预期结果 | 监控项 | 正常表现 | |--------|----------| | /proc/interrupts | 中断100计数持续增加且只在CPU3列 | | /proc/softirqs | NET_RX和NET_TX主要在CPU3增加 | | mpstat | CPU3软中断利用率显著高于其他核心 | | ping延迟 | 稳定在1-5ms之间无丢包 | ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值