版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tiantao2012/article/details/86743142
在liteos中通过LOS_HwiCreate来注册一个中断,举例如下:
UINT32 Example_Interrupt(VOID)
{
UINTPTR uvIntSave;
uvIntSave = LOS_IntLock();
Example_Exti0_Init();
#核心是调用这个函数来新建中断,第一个形参是中断号
LOS_HwiCreate(6, 0, 0, User_IRQHandler, 0);//create interrupt
LOS_IntRestore(uvIntSave);
return LOS_OK;
}
继续看看
LITE_OS_SEC_TEXT_INIT UINT32 LOS_HwiCreate( HWI_HANDLE_T uwHwiNum,
HWI_PRIOR_T usHwiPrio,
HWI_MODE_T usMode,
HWI_PROC_FUNC pfnHandler,
HWI_ARG_T uwArg )
{
UINTPTR uvIntSave;
#这个数组保存这个所有中断号对应的中断处理函数
if (m_pstHwiForm[uwHwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)osHwiDefaultHandler)
{
return OS_ERRNO_HWI_ALREADY_CREATED;
}
uvIntSave = LOS_IntLock();
#根据中断号更新m_pstHwiForm数组中中断号对应的中断处理函数
#if (OS_HWI_WITH_ARG == YES)
osSetVector(uwHwiNum, pfnHandler, uwArg);
#else
osSetVector(uwHwiNum, pfnHandler);
#endif
#使能这个中断
NVIC_EnableIRQ((IRQn_Type)uwHwiNum);
#设置这个中断的优先级
NVIC_SetPriority((IRQn_Type)uwHwiNum, usHwiPrio);
LOS_IntRestore(uvIntSave);
return LOS_OK;
}
可见osSetVector 中更新了两个数组,其中数组m_pstHwiForm 的中每个回调函数都是osInterrupt
在osInterrupt;中会调用pfnVector
#define osSetVector(uwNum, pfnVector) \
m_pstHwiForm[uwNum + OS_SYS_VECTOR_CNT] = osInterrupt;\
m_pstHwiSlaveForm[uwNum + OS_SYS_VECTOR_CNT] = pfnVector;
#endif
为什么会在LOS_HwiCreate中会判断中断的默认处理函数是osHwiDefaultHandler
if (m_pstHwiForm[uwHwiNum + OS_SYS_VECTOR_CNT] != (HWI_PROC_FUNC)osHwiDefaultHandler)
{
return OS_ERRNO_HWI_ALREADY_CREATED;
}
这个是因为在下面的函数中会默认对m_pstHwiForm中的所有中断号赋一个初值,所以这里增加一个判断是
防止中断的重复注册
LITE_OS_SEC_TEXT_INIT VOID osHwiInit()
{
UINT32 uwIndex;
for(uwIndex = OS_SYS_VECTOR_CNT; uwIndex < OS_VECTOR_CNT; uwIndex++)
{
m_pstHwiForm[uwIndex] = (HWI_PROC_FUNC)osHwiDefaultHandler;
}
/* Interrupt vector table location */
SCB->VTOR = (UINT32)m_pstHwiForm;
#if (__CORTEX_M >= 0x03U) /* only for Cortex-M3 and above */
NVIC_SetPriorityGrouping(OS_NVIC_AIRCR_PRIGROUP);
#endif
return;
}