【简介】
S32K3 作为Cortex-M7 架构的芯片,对于中断的管理和其他的M系列的芯片也是一致的,都是通过M核的NVIC进行管理的。S32K3 系列芯片的驱动管理说是在IntCtrl_Ip 来管理的。
我们在S32DS 中可以配置对应的中断的开启和设置中断优先级。
本地使用UART6 中断来接收串口数据,本地通过如下配置开启UART6的中断。
我们添加如下代码配置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 }