Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Exception 配置优先级位分配后如何诊断不精确的总线故障,Cortex M3 STM32F10x w uC/OS-III_Exception_Embedded_Arm_Interrupt_Cortex M3 - Fatal编程技术网

Exception 配置优先级位分配后如何诊断不精确的总线故障,Cortex M3 STM32F10x w uC/OS-III

Exception 配置优先级位分配后如何诊断不精确的总线故障,Cortex M3 STM32F10x w uC/OS-III,exception,embedded,arm,interrupt,cortex-m3,Exception,Embedded,Arm,Interrupt,Cortex M3,我在为ST Microelectronics STM32F103(ARM Cortex-M3 r1p1)编写的应用程序中遇到了一个问题。RTOS是uC/OS-III;开发环境是IAR EWARM v。6.44; 它还使用ST标准外围设备库v。1.0.1 这个应用程序不是新的;它已经在开发和现场至少一年了。它使用两个UART、I2C和一个或两个定时器。最近,我决定回顾中断优先级分配,并重新安排优先级作为回顾的一部分(事情似乎进展顺利) 我发现初始化代码(包括RTO)中没有显式分配组和次优先级位,因

我在为ST Microelectronics STM32F103(ARM Cortex-M3 r1p1)编写的应用程序中遇到了一个问题。RTOS是uC/OS-III;开发环境是IAR EWARM v。6.44; 它还使用ST标准外围设备库v。1.0.1

这个应用程序不是新的;它已经在开发和现场至少一年了。它使用两个UART、I2C和一个或两个定时器。最近,我决定回顾中断优先级分配,并重新安排优先级作为回顾的一部分(事情似乎进展顺利)

我发现初始化代码(包括RTO)中没有显式分配组和次优先级位,因此为了使应用程序与另一个应用程序(相同的产品,不同的处理器)一致,并使用新的优先级方案,我添加了对NVIC_PriorityGroupConfig()的调用,传入NVIC_PriorityGroup_2。这将应用程序中断和复位控制寄存器(INTROR)中的PRIGOUP值设置为5,为组(抢占)优先级分配2位,为子优先级分配2位

这样做之后,我在执行时得到一个不精确的总线故障异常,不是立即的,而是很快的。(更多关于我怀疑它发生在什么地方的信息)因为它不精确(BFSR.increciserr断言),所以在BFAR中没有任何用处(BFSR.BFARVALID clear)

STM32F系列组实现4位优先级。虽然我在任何地方都没有发现明确提到过这一点,但它显然是最重要的优先事项。这一假设似乎通过文件(第134页,STM32F10xxx/20xxx/21xxx/L1xX Cortex-M3编程手册(第15491号文件,第5版),第4.4.5节,应用中断和控制寄存器(SCB_-Airtr),表45,优先级分组,第134页)中给出的优先级组表得到验证

在ARM方案中,优先级值包括一定数量的组或抢占优先级位和一定数量的子优先级位。组优先级位为高位;次优先级较低。3位的Airr.PRIGROUP值控制如何定义每个组的位分配。PRIGROUP=0配置7位组优先级和1位子优先级;PRIGROUP=7配置0位组优先级和8位子优先级(因此优先级都是子优先级,对于具有可设置优先级的异常不会发生抢占)

Airr.PRIGROUP的重置值定义为0

对于STM32F10x,由于只实现了较高的4位,因此PRIGROUP=0、1、2、3似乎都应该是等效的,因为它们都对应于组优先级的>=4位

基于这种假设,我还尝试使用NVIC_PriorityGroup_4的值调用NVIC_PriorityGroupConfig(),该值对应于PRIGROUP值3(4位组优先级,无子优先级)

此更改还导致总线故障异常

不幸的是,我认为STM32F103是r1p1,因此没有实现辅助控制寄存器(ACTLR;在r2p0中引入),因此我无法尝试DISDEFWBUF位(在默认内存映射访问期间禁用写入缓冲区,以牺牲一些性能降低为代价,使所有总线故障精确)

我几乎可以肯定总线故障发生在ISR中,最有可能发生在UART ISR中。我在代码中的特定位置设置了一个断点,启动了应用程序,在执行到达断点之前出现了总线故障;但是,如果我在调试器中单步执行代码,我可以到达并通过该断点的位置,如果我允许它从那里执行,我将在继续后的一小段时间内看到总线故障

下一步将是尝试确定ISR产生总线故障的原因,以便我可以对其进行检测和/或尝试捕获其调用并逐步解决

因此,我的问题是:

1)关于如何更智能地识别不精确总线故障异常的来源,有人有什么建议吗?

2)当PRIGROUP=0是重置默认值时,为什么设置PRIGROUP=3会改变系统的行为?(PRIGROUP=0表示7位组,1位次优先级;PRIGROUP=3表示4位组,4位次优先级;STM32F10x仅实现优先级的上4位。)

非常非常感谢大家提前提供的任何洞察或非空指针


(当然,如果我事先弄清楚了,我会用任何可能对遇到相同情况的其他人有用的信息更新这篇文章。)

即使BFAR无效,您仍然可以读取总线故障ISR中的其他相关寄存器:

void HardFault_Handler_C(unsigned int* hardfault_args)
{
    printf("R0    = 0x%.8X\r\n",hardfault_args[0]);         
    printf("R1    = 0x%.8X\r\n",hardfault_args[1]);         
    printf("R2    = 0x%.8X\r\n",hardfault_args[2]);         
    printf("R3    = 0x%.8X\r\n",hardfault_args[3]);         
    printf("R12   = 0x%.8X\r\n",hardfault_args[4]);         
    printf("LR    = 0x%.8X\r\n",hardfault_args[5]);         
    printf("PC    = 0x%.8X\r\n",hardfault_args[6]);         
    printf("PSR   = 0x%.8X\r\n",hardfault_args[7]);         
    printf("BFAR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED38);
    printf("CFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED28);
    printf("HFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED2C);
    printf("DFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED30);
    printf("AFSR  = 0x%.8X\r\n",*(unsigned int*)0xE000ED3C);
    printf("SHCSR = 0x%.8X\r\n",SCB->SHCSR);                
    while (1);
}
如果在执行过程中发生此特定硬故障中断时无法使用
printf
,请将上述所有数据保存在全局缓冲区中,以便在到达
while(1)
时查看

以下是如何将此ISR连接到中断向量的完整描述(尽管,正如我从您的问题中了解到的,您已经实现了它):

您可以在以下网站上找到您已经知道的信息:


我粗略地检查了堆叠的数据,但当时我看到的似乎没有意义。我将重新调查(我一直希望有一个更直接的方法我忽略了)。试图编辑我最后的评论,时间不够了:顺便说一句,我已经有了Keil app note(209)。对于其他可能看到它的人:请仔细注意,p。进入SCB->SHCSR以启用使用、内存和总线故障的4不正确-应为0x00070000,而不是0x00007000。(尽管根据编译器和/或操作系统的不同,可能会有一些宏或函数更适合于清晰地使用。)根据个人经验,在包含4字节变量(
int
float
)或8字节变量的结构上查找任何操作-