这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】中断管理

共1条 1/1 1 跳转至

【S32K3XX】中断管理

高工
2025-08-27 21:50:09     打赏

【简介】

S32K3 作为Cortex-M7 架构的芯片,对于中断的管理和其他的M系列的芯片也是一致的,都是通过M核的NVIC进行管理的。S32K3 系列芯片的驱动管理说是在IntCtrl_Ip 来管理的。

image.png

我们在S32DS 中可以配置对应的中断的开启和设置中断优先级。

image.png

本地使用UART6 中断来接收串口数据,本地通过如下配置开启UART6的中断。

image.png

我们添加如下代码配置UART 的接收中断

/********************************************************************************************************
 *                                  Private Variable Definitions                                        *
 *******************************************************************************************************/
UartRecvType uart_rx;

/* User includes */
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
int main(void)
{
/* Initialize the clock driver */
Clock_Ip_Init(Clock_Ip_aClockConfig);

C40_Ip_Init(&C40_Ip_InitCfg);

/* Initialize all pins using the Port driver */
Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS_PortContainer_0_BOARD_InitPeripherals, g_pin_mux_InitConfigArr_PortContainer_0_BOARD_InitPeripherals);

/* Initialize interrupt */
IntCtrl_Ip_Init(&IntCtrlConfig_0);

/* Init Ringbuffer */
static uint8_t uart_rx_buff[128] = {0};
RingBuffer_Init(&uart_rx.ringbuff,uart_rx_buff,128);

Lpuart_Uart_Ip_Init(6,&Lpuart_Uart_Ip_xHwConfigPB_6);

/* Enable the LPUART transmitter */
Lpuart_Uart_Ip_SetTransmitterCmd(IP_LPUART_6,true);
/* Enable the LPUART receiver */
Lpuart_Uart_Ip_SetReceiverCmd(IP_LPUART_6, true);

/* open uart rx data full event */
Lpuart_Uart_Ip_SetIntMode(IP_LPUART_6, LPUART_UART_IP_INT_RX_DATA_REG_FULL, true);
/* Install LPUART irq handler */
IntCtrl_Ip_InstallHandler(LPUART6_IRQn,&LPUART_UART_IP_6_IRQHandler,NULL_PTR);

Lpuart_Uart_Ip_AsyncReceive(6,&uart_rx.data,1);

/* Enable LPUART interrupt. */
IntCtrl_Ip_EnableIrq(LPUART6_IRQn);

mini_printf("hello world..\r\n");

littleshell_main_entry(NULL);

return 0;
}


uint8_t uartgetchar(uint8_t* pdata)
{
return RingBuffer_Read(&uart_rx.ringbuff,pdata,1);
}

void uart6_callback_handler(const uint8 HwInstance, const Lpuart_Uart_Ip_EventType Event, void *UserData)
{
(void)HwInstance;
UartRecvType * Puart = (UartRecvType *)UserData;
if(Event == LPUART_UART_IP_EVENT_RX_FULL)
{
/* Get date and write to ringbuffer */
RingBuffer_Write(&Puart->ringbuff,&Puart->data,1);
}
/* Start to recive uart data */
if(Event == LPUART_UART_IP_EVENT_END_TRANSFER)
Lpuart_Uart_Ip_AsyncReceive(6,&Puart->data,1);
}

此时debug时UART 中断已经被触发。

S32K3 系列中断的管理,接口也不多只有几个接口,接下来我们针对中断管理的接口代码实现上进行解析。

中断使能接口:

void IntCtrl_Ip_EnableIrqPrivileged(IRQn_Type eIrqNumber)
{

#if (INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON)
/* Check IRQ number - dev_irqNumber is used to avoid compiler warning */
DevAssert(0 <= (sint32)eIrqNumber);
DevAssert((sint32)eIrqNumber <= (sint32)INT_CTRL_IP_IRQ_MAX);
#endif /*(INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON) */
/* Enable interrupt */
#if ((INT_CTRL_IP_CORTEXR == STD_ON) || (INT_CTRL_IP_CORTEXA == STD_ON))
#if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64)
S32_GICD->GICD_ISENABLER[((uint32)(eIrqNumber) >> 5U)] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
#else
uint32 cpuId;
if ((uint32)(eIrqNumber) < GIC500_MIN_SPI_ID)
{
cpuId = IntCtrl_Ip_gic500_convertAffinityToLinearId(IntCtrl_Ip_read_MPIDR());
#if (INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(GIC500_CPU_COUNT > cpuId);
#endif /*(INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON) */
IP_GIC500->CPU[cpuId].GICR_SGII.ISENABLER0 = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
}
else
{
S32_GICD->GICD_ISENABLER[((uint32)(eIrqNumber) >> 5U) - 1U] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
}
#endif
#else
S32_NVIC->ISER[(uint32)(eIrqNumber) >> 5U] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
#endif
}

上述接口可以使能对应的irq,代码实现中兼容了M架构和R架构的中断控制器。

以下接口设置中断优先级。

void IntCtrl_Ip_EnableIrqPrivileged(IRQn_Type eIrqNumber)
{

#if (INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON)
/* Check IRQ number - dev_irqNumber is used to avoid compiler warning */
DevAssert(0 <= (sint32)eIrqNumber);
DevAssert((sint32)eIrqNumber <= (sint32)INT_CTRL_IP_IRQ_MAX);
#endif /*(INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON) */
/* Enable interrupt */
#if ((INT_CTRL_IP_CORTEXR == STD_ON) || (INT_CTRL_IP_CORTEXA == STD_ON))
#if (MCAL_PLATFORM_ARM == MCAL_ARM_AARCH64)
S32_GICD->GICD_ISENABLER[((uint32)(eIrqNumber) >> 5U)] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
#else
uint32 cpuId;
if ((uint32)(eIrqNumber) < GIC500_MIN_SPI_ID)
{
cpuId = IntCtrl_Ip_gic500_convertAffinityToLinearId(IntCtrl_Ip_read_MPIDR());
#if (INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON)
DevAssert(GIC500_CPU_COUNT > cpuId);
#endif /*(INT_CTRL_IP_DEV_ERROR_DETECT == STD_ON) */
IP_GIC500->CPU[cpuId].GICR_SGII.ISENABLER0 = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
}
else
{
S32_GICD->GICD_ISENABLER[((uint32)(eIrqNumber) >> 5U) - 1U] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
}
#endif
#else
S32_NVIC->ISER[(uint32)(eIrqNumber) >> 5U] = (uint32)(1UL << ((uint32)(eIrqNumber) & (uint32)0x1FU));
#endif
}



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]