1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/phytium_embedded-phytium-zephyr-sdk

Клонировать/Скачать
README.md 10 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
李乔中 Отправлено 26.06.2024 06:55 6b09dce

Interrupt 测试

1. 例程介绍

dynamic_isr.c

test_isr_dynamic函数的目的是验证动态中断服务例程(ISR)安装的功能。这是内核中断测试的一部分,特别是在支持动态中断连接的系统上非常关键。以下是该测试函数完成的主要验证步骤:

  1. 查找未使用的软件ISR表项:该测试通过遍历软件ISR表(_sw_isr_table),寻找一个未被使用的项,即其中断服务例程指针等于 z_irq_spurious的项。z_irq_spurious是一个用于处理无效或未配置的中断的“伪”ISR。
  2. 安装动态ISR:找到未使用的表项后,测试使用 arch_irq_connect_dynamic函数安装一个新的动态ISR。该函数允许在运行时动态地连接中断服务例程,不需要在编译时预先定义。测试中,动态ISR为 dyn_isr函数,它接受一个指向整数 i的指针作为参数。
  3. 验证ISR安装成功:安装动态ISR后,测试通过检查软件ISR表的相应项来验证ISR是否成功安装。成功的标志是表项的中断服务例程指针等于 dyn_isr,并且参数 arg与传递给 arch_irq_connect_dynamic的参数相匹配。

dynamic_shared_irq.c

  • test_dynamic_shared_irq_disconnect_write

此函数的目标是验证动态共享中断(ISR)在断开(disconnect)一个ISR/arg对后的行为。测试流程如下:

  1. 预先设置:首先确保中断服务例程(ISR)通过之前的设置步骤已经被动态地注册到了指定的IRQ位置。
  2. 中断解除共享:通过调用 arch_irq_disconnect_dynamic函数,从共享的中断源中移除一个特定的ISR/arg对。此操作后,中断应该不再被视为“共享”的,因为它只剩下一个ISR/arg对。
  3. 验证中断解除共享后的状态:检查软件ISR表(_sw_isr_table)中的项是否更新为剩余的ISR/arg对,确保中断现在直接连接到了剩余的ISR,而不是通过共享机制。
  4. 触发中断:使能并触发中断,然后验证剩余的ISR是否被正确调用。
  5. 检查结果:对比预期结果和实际调用情况,确保只有剩余的ISR/arg对被调用,其他ISR没有被误调。
  • test_dynamic_shared_irq_write

此函数的目的是测试动态共享中断在多个ISR/arg对注册后的行为。具体测试步骤包括:

  1. 预先设置:与上一个测试类似,确保通过之前的设置步骤,已经有多个ISR被动态地注册到指定的IRQ。
  2. 触发中断:使能并触发相关的两个中断(fixture.irq1fixture.irq2),这两个中断分别有不同的ISR/arg对注册。
  3. 延时等待:提供足够的时间确保中断处理完成。
  4. 检查执行结果:验证预期的ISR/arg对是否都被按顺序正确调用。这包括检查全局变量 test_vector与预期的结果 result_vector是否匹配,以此来确保每个注册的ISR都按预期执行了。
  • nested_irq.c

test_nested_isr函数主要目的是验证中断嵌套的功能。中断嵌套允许一个正在执行的中断服务例程(ISR)被更高优先级的中断打断,当高优先级的ISR处理完成后,较低优先级的ISR继续执行。这是实时操作系统(RTOS)中一个重要的特性,确保系统能够响应更紧急的任务,同时保持较低优先级任务的状态。以下是该测试函数执行的关键步骤:

  1. 初始化:确定用于测试的两个中断线(IRQs)编号。这些中断被分配了不同的优先级,其中 irq_line_0具有较低的优先级,而 irq_line_1具有更高的优先级。
  2. 连接并启用中断:使用 arch_irq_connect_dynamic函数动态地连接两个中断服务例程(isr0isr1)到对应的中断线,并使能这些中断。这一步确保当中断触发时,对应的ISR能够被执行。
  3. 触发较低优先级的中断:通过 trigger_irq函数触发 irq_line_0,启动 isr0的执行。在 isr0中,首先设置验证令牌 isr0_result,然后触发更高优先级的 irq_line_1,启动 isr1的执行。
  4. 执行较高优先级的ISR:在 isr1中,设置验证令牌 isr1_result并返回。此时,由于 isr1具有更高的优先级,isr0的执行将被暂停,直到 isr1执行完成。
  5. 中断嵌套验证:在 isr0中继续执行,验证 isr1_result令牌确保 isr1已经成功执行。然后,isr0完成剩余的处理并返回。
  6. 最终结果验证:在测试线程中,验证 isr0_result令牌以确保 isr0也已经成功执行。

prevent_irq.c

test_prevent_interruption函数的主要目的是验证内核是否能够有效地阻止中断的发生。这是通过锁定中断并进行忙等待(busy-wait)来实现的,以检验系统计时器中断在中断锁定期间是否被处理;此外,这个测试还验证了在解锁中断后系统计时器中断是否能被正确处理。以下是该测试执行的关键步骤:

  1. 锁定中断:使用 irq_lock函数锁定系统中断。这一步骤是为了阻止任何中断的发生,包括系统计时器中断。
  2. 初始化并启动计时器:通过 k_timer_initk_timer_start函数初始化并启动一个计时器。计时器在指定的延迟后应触发 timer_handler函数。
  3. 忙等待:在中断锁定的状态下执行忙等待一段时间。如果中断没有被锁定,这段时间内计时器的中断应该会触发。但由于中断被锁定,我们预期 timer_handler中设置的 handler_result不会在此期间被更新。
  4. 验证计时器中断是否被锁定:检查 handler_result变量,确认在中断锁定期间计时器的中断处理程序是否没有被执行。如果 handler_result在忙等待期间未被更新,则表明计时器中断未被处理,验证了中断锁定的有效性。
  5. 解锁中断:使用 irq_unlock函数解锁中断。此操作后,之前锁定的中断应该能够被处理。
  6. 再次忙等待:在解锁中断后再次执行忙等待,以便系统有机会处理任何挂起的中断,特别是我们之前启动的计时器中断。
  7. 验证计时器中断是否被处理:再次检查 handler_result变量,确认在解锁中断后计时器的中断处理程序是否被执行。如果此时 handler_result被更新为预期的令牌,则表明在解锁中断后计时器中断被正确处理。

static_shared_irq.c

test_static_shared_irq_write 函数的主要目的是验证静态共享中断(static shared interrupts)的功能。这个测试检验了是否可以成功地共享中断,即当触发了它们注册的中断时,是否能调用多个中断服务程序(ISR)及其参数(arg)对。

功能验证步骤:

  1. 中断连接:通过 IRQ_CONNECT宏,函数连接了两个不同的ISR(test_isr_0test_isr_1)到同一个中断号 GIC_IRQ1上,并连接了 test_isr_2到另一个中断号 GIC_IRQ2上。这模拟了在实际应用中,多个设备可能需要在同一个中断线上注册它们的处理函数的场景。
  2. 中断验证:函数验证了在 _sw_isr_table中对应 GIC_IRQ1的条目是否正确地设置为了共享中断处理函数 z_shared_isr,并且 GIC_IRQ2是否保留了它的原始ISR(test_isr_2)。
  3. 参数验证:进一步验证了 _sw_isr_tableGIC_IRQ1GIC_IRQ2对应条目的参数(arg)是否正确设置。特别是对于 GIC_IRQ1,期望它的参数指向共享ISR表中的一个条目,而 GIC_IRQ2的参数应直接是 test_isr_2的参数。
  4. 客户端数量验证:检查了与 GIC_IRQ1关联的共享ISR条目中的客户端数量是否正确地反映了两个ISR的注册,以及 GIC_IRQ2是否没有共享客户端,因为它没有共享ISR。
  5. 触发中断:通过 trigger_irq函数触发了 GIC_IRQ1GIC_IRQ2对应的中断,并等待一段时间,以便ISR有机会执行。
  6. 结果验证:通过比较 test_vectorresult_vector的值,验证了当中断被触发时,所有注册的ISR是否都被正确地执行了。这个向量数组用于记录ISR执行的验证标记,以确保它们如预期那样被调用。
  7. 中断禁用与断开连接:最后,通过 irq_disablearch_irq_disconnect_dynamic函数禁用并断开之前连接的ISR,以清理测试环境。

2. 如何使用例程

本例程需要以下硬件,

  • E2000D/Q Demo板

2.1 硬件配置方法

保障串口正常工作后,不需要额外配置硬件

2.2 SDK配置方法

  • 本例子已经提供好具体的编译指令,以下进行介绍:
  1. west build -b e2000q_demo_smp ./ -DOVERLAY_CONFIG=prj.conf,编译命令, 使用west工具构建当前目录下的Zephyr项目,指定目标板为e2000q_demo_smp,并使用prj.conf配置文件覆盖默认配置 ,最终生成的执行文件将会保存在./build/zephyr/zephyr.elf
  2. west build -t clean, 清除缓存 ,使用west工具的clean目标清理Zephyr构建系统可能生成的任何其他临时文件或缓存

2.3 构建和下载

  • 编译例程

west build -b e2000q_demo_smp ./ -DOVERLAY_CONFIG=prj.conf

  • 编译主机测侧设置重启tftp服务器
sudo service tftpd-hpa restart
  • 开发板侧使用bootelf命令跳转
setenv ipaddr 192.168.4.20  
setenv serverip 192.168.4.50 
setenv gatewayip 192.168.4.1 
tftpboot 0x90100000 zephyr.elf
bootelf -p 0x90100000

2.4 输出与实验现象

  • 所有用例均提供一系列可变配置,可在例程全局变量中修改

2.4.1 测试动态ISR

isr_test dynamic_isr

dynamic_isr_result

2.4.2 测试动态共享IRQ

isr_test dynamic_shared_irq

dynamic_shared_irq_result

2.4.3 测试嵌套ISR

isr_test nested_irq

nested_irq_result

2.4.4 测试中断防护

isr_test prevent_irq

prevent_irq_result

2.4.5 测试静态共享IRQ写入

isr_test static_shared_irq

static_shared_irq_result

3. 如何解决问题

4. 修改历史记录

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/phytium_embedded-phytium-zephyr-sdk.git
git@api.gitlife.ru:oschina-mirror/phytium_embedded-phytium-zephyr-sdk.git
oschina-mirror
phytium_embedded-phytium-zephyr-sdk
phytium_embedded-phytium-zephyr-sdk
master