gpt4 book ai didi

c - STM32F103处理嵌套中断的优先级

转载 作者:行者123 更新时间:2023-11-30 16:24:10 25 4
gpt4 key购买 nike

我可以在STM32F10x库中找到与NVIC_Init相关的问题,该问题与处理嵌套中断的优先级相关。我们知道,任何优先级值等于或高于 BASEPRI(在本例中为 11)的中断都可以调用 FromISR() FreeRTOS API 函数。

FreeRTOS 使用 15 级(最低优先级)。

#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY    15

换句话说,FreeRTOS 允许我们以 15-11 优先级从 ISR 调用 API 函数(请参阅 xQueueSendToBackFromISR)。当我们初始化 NVIC 时,我们使用级别 #11

#define    WRTU2_DMA1_SPI2_IRQ_PRIORITY     (configLIBRARY_KERNEL_INTERRUPT_PRIORITY-4*)
/* DMA1 Channel4 interrupt setting */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = WRTU2_DMA1_SPI2_IRQ_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = WRTU2_DMA1_SPI2_IRQ_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

所以,我们应该没问题。但问题是存在的。我决定检查 NVIC_Init。

根据STM32数据表中的信息,优先级寄存器为0xe000e40e(NVIC channel 14属于DMA1_Channel4中断)。

在 NVIC 初始化后,我可以从该寄存器读取 0x00 。这意味着 NVIC channel #14 在系统中具有最高优先级。

它会导致所有问题。

我添加了最简单的修复NVIC->IP[DMA1_Channel4_IRQn] = 0xF0;并且系统不会再出现故障。这样,我们当前的问题就解决了。

当然,我尝试分析NVIC_Init中发生了什么

**
* @brief Initializes the NVIC peripheral according to the specified
* parameters in the NVIC_InitStruct.
* @param NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains
* the configuration information for the specified NVIC peripheral.
* @retval None
*/
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;

/* Check the parameters */
assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));
assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));

if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
{
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;

tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;

NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;

/* Enable the Selected IRQ Channels --------------------------------------*/
NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
else
{
/* Disable the Selected IRQ Channels -------------------------------------*/
NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
}
}

因此,我将类似的测试代码添加到我的应用程序中,看看它如何转换所有值

uint32_t NVIC_IRQChannelPreemptionPriority=0xFF,NVIC_IRQChannelSubPriority=0xFF;
int32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
tprintf("\n\rSCB->AIRCR=0x%08x",SCB->AIRCR);

tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tprintf("\n\rtmppriority=0x%08x",tmppriority);
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;

tprintf("\n\rtmppre=0x%08x",tmppre);
tprintf("\n\rtmpsub=0x%08x",tmpsub);


tmppriority = (uint32_t)NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
tprintf("\n\rtmppriority=0x%08x",tmppriority);

有日志

SCB->AIRCR=0xfa050000
tmppriority=0x00000007
tmppre=0xfffffffd
tmpsub=0x00000000
tmppriority=0x00000000

注意,即使我为两个输入参数指定 0xFF,它也会返回 0x00。

我对这种行为感到非常惊讶。这是一个库函数。

人们使用它很多年了。所以,我真的很困惑我能在那个函数中找到问题。

可能与应用中断和复位控制寄存器(SCB_AIRCR)有关地址偏移:0x0C复位值:0xFA05 0000所需权限:特权AIRCR 为异常模型提供优先级分组控制,为数据提供字节序状态访问和重置系统的控制。

注意,在库源中我可以看到#define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000)

因此,看起来我们在 16 位半字节中有某种 BIG 与 LITTLE ENDIAN 字节顺序。

您对这个问题有什么建议或了解吗?

最佳答案

我发现了问题,问题是我应该使用 NVIC_SetPriorityGrouping(3); 3 表示 cortex-m3。

然后它提供4位抢占优先级和0位次优先级。最后,当我像这样启动时,它按我的预期工作。

  /* DMA1 Channel4 interrupt setting */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

关于c - STM32F103处理嵌套中断的优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53700659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com