如何以编程方式在M0 +上驱动ISR

时间:2017-12-06 20:35:42

标签: c unit-testing arm embedded isr

我正在为Arm M0 +上运行的嵌入式项目编写一些Unity单元测试。我的一些API依赖于它们是否从ISR上下文中调用。所以我想以编程方式驱动一个中断。在伪代码中,我希望我的测试看起来像:

// set (global) flag indicating what ISR should do
// trigger the ISR
// control transfers to ISR which branches off of (global) flag and computes result, store in some global
// control now returns to here, where I can assert the nature of the global result

我需要指导的部分是如何触发ISR。我在M3文档中看到了一些关于软件中断触发器的参考文献,但我没有找到类似M0 +的内容。

A"解决方法"解决方案可能是获取一个未使用的计时器,使用它的ISR,然后将其设置为0,然后启动它以驱动中断。或者也许是我配置的未使用引脚的类似方案?是否有更直接的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

根据@ user58697和@andymango的提示,我想出了以下方案。

-1确定对于我的电路板(SAMD21),IRQ 21没有外设。

-2在我的resetVectors.c文件中复制其他别名虚拟处理程序,我添加了:

void PV21Handler             ( void ) __attribute__ ((weak, alias("Dummy_Handler")));

-3修改了DeviceVectors结构,将.pvReserved21设置为:

__attribute__ ((section(".vectors")))
const DeviceVectors exception_table = {
    ...
    ...
    .pvReserved21           = (void*) PV21Handler,
    ...
    ...
};

-4实现了一个实际执行某项操作的void PV21Handler(void){}函数

-5使用以下命令启用中断:

NVIC_EnableIRQ(21);
// this comes from the core_cm0plus.h file

-6最后用:

触发中断
while (NVIC_GetPendingIRQ(21)) {  }
NVIC_SetPendingIRQ(21);
while (NVIC_GetPendingIRQ(21)) {  }

清除状态的轮询是必要的,因为在设置中断和它实际发生之间似乎有一点点延迟,所以要获得真正的优势,我必须先将它断言为低。