|
|
|
@ -25,7 +25,9 @@
|
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
* --------------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
关于LiteOS中硬件中断处理的部分,涉及了中断的注册、删除、触发、使能、禁止等操作
|
|
|
|
|
*/
|
|
|
|
|
#include "los_hwi_pri.h"
|
|
|
|
|
#include "los_hwi.h"
|
|
|
|
|
#include "los_memory.h"
|
|
|
|
@ -61,7 +63,7 @@ const HwiControllerOps *g_hwiOps = NULL;
|
|
|
|
|
|
|
|
|
|
typedef VOID (*HWI_PROC_FUNC0)(VOID);
|
|
|
|
|
typedef VOID (*HWI_PROC_FUNC2)(INT32, VOID *);
|
|
|
|
|
|
|
|
|
|
//OsIrqNestingActive:用于在处理中断期间激活中断嵌套计数器,避免在处理时钟中断时进行抢占
|
|
|
|
|
STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
|
|
|
|
@ -71,7 +73,7 @@ STATIC INLINE VOID OsIrqNestingActive(UINT32 hwiNum)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsIrqNestingInactive:用于在处理中断结束后禁用中断嵌套计数器
|
|
|
|
|
STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
|
|
|
|
|
{
|
|
|
|
|
#ifdef LOSCFG_ARCH_INTERRUPT_PREEMPTION
|
|
|
|
@ -80,17 +82,17 @@ STATIC INLINE VOID OsIrqNestingInactive(UINT32 hwiNum)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsIrqNestingCntGet:获取当前CPU的中断嵌套计数值
|
|
|
|
|
size_t OsIrqNestingCntGet(VOID)
|
|
|
|
|
{
|
|
|
|
|
return g_intCount[ArchCurrCpuid()];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsIrqNestingCntSet:设置当前CPU的中断嵌套计数值
|
|
|
|
|
VOID OsIrqNestingCntSet(size_t val)
|
|
|
|
|
{
|
|
|
|
|
g_intCount[ArchCurrCpuid()] = val;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//InterruptHandle:处理中断的实际函数,根据中断号调用对应的中断处理函数
|
|
|
|
|
STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
|
|
|
|
|
{
|
|
|
|
|
hwiForm->respCount++;
|
|
|
|
@ -114,7 +116,7 @@ STATIC INLINE VOID InterruptHandle(HwiHandleInfo *hwiForm)
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsIntHandle:中断处理入口函数,负责处理中断前的一些准备工作,如调用中断处理前的钩子函数等
|
|
|
|
|
VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
|
|
|
|
|
{
|
|
|
|
|
size_t *intCnt = NULL;
|
|
|
|
@ -148,7 +150,7 @@ VOID OsIntHandle(UINT32 hwiNum, HwiHandleInfo *hwiForm)
|
|
|
|
|
OsCpupIrqEnd(hwiNum);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsIntEntry:中断向量入口函数,根据中断号调用对应的中断处理函数
|
|
|
|
|
VOID OsIntEntry(VOID)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps != NULL) && (g_hwiOps->handleIrq != NULL)) {
|
|
|
|
@ -156,7 +158,7 @@ VOID OsIntEntry(VOID)
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsHwiCpIrqParam:根据传入的中断参数结构体分配内存,并将参数信息拷贝到新分配的内存中
|
|
|
|
|
STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
|
HWI_IRQ_PARAM_S *paramByAlloc = NULL;
|
|
|
|
@ -169,6 +171,7 @@ STATIC HWI_ARG_T OsHwiCpIrqParam(const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
return (HWI_ARG_T)paramByAlloc;
|
|
|
|
|
}
|
|
|
|
|
#ifndef LOSCFG_SHARED_IRQ
|
|
|
|
|
//OsHwiDel:删除指定的中断处理函数
|
|
|
|
|
STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
UINT32 intSave;
|
|
|
|
@ -190,7 +193,7 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *hwiForm, const HWI_IRQ_PARAM_S *irqParam,
|
|
|
|
|
HWI_UNLOCK(intSave);
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsHwiCreate:创建中断处理函数,并将其添加到中断处理链表中
|
|
|
|
|
STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
|
|
|
|
|
const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
@ -218,6 +221,7 @@ STATIC UINT32 OsHwiCreate(HwiHandleInfo *hwiForm, HWI_MODE_T hwiMode, HWI_PROC_F
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
#else /* LOSCFG_SHARED_IRQ */
|
|
|
|
|
//函数OsFreeHwiNode:用于释放中断处理函数节点,并在需要时禁止该中断
|
|
|
|
|
STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret = LOS_OK;
|
|
|
|
@ -240,7 +244,8 @@ STATIC INLINE UINT32 OsFreeHwiNode(HwiHandleInfo *head, HwiHandleInfo *hwiForm,
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsHwiDel:用于删除硬件中断处理函数,它首先判断中断是否是共享中断
|
|
|
|
|
//如果不是,则直接释放该中断的处理函数节点;如果是共享中断,则遍历链表找到对应的设备ID,然后释放该中断的处理函数节点
|
|
|
|
|
STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UINT32 irqId)
|
|
|
|
|
{
|
|
|
|
|
HwiHandleInfo *hwiFormPrev = NULL;
|
|
|
|
@ -290,7 +295,8 @@ STATIC UINT32 OsHwiDel(HwiHandleInfo *head, const HWI_IRQ_PARAM_S *irqParam, UIN
|
|
|
|
|
HWI_UNLOCK(intSave);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//OsHwiCreate:用于创建硬件中断处理函数,它首先判断中断是否是共享中断,并检查是否已经存在具有相同设备ID的中断处理函数节点,如果存在则返回错误
|
|
|
|
|
//然后申请内存并初始化新的中断处理函数节点,将其添加到链表中
|
|
|
|
|
STATIC UINT32 OsHwiCreate(HwiHandleInfo *head, HWI_MODE_T hwiMode, HWI_PROC_FUNC hwiHandler,
|
|
|
|
|
const HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
@ -359,7 +365,9 @@ size_t IntActive()
|
|
|
|
|
LOS_IntRestore(intSave);
|
|
|
|
|
return intCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiCreate 函数:用于创建硬件中断处理函数
|
|
|
|
|
//它会注册一个中断处理函数,并将其与指定的硬件中断号相关联
|
|
|
|
|
//可以设置中断的优先级、硬件中断模式和处理函数
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
|
|
|
|
|
HWI_PRIOR_T hwiPrio,
|
|
|
|
|
HWI_MODE_T hwiMode,
|
|
|
|
@ -396,7 +404,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiCreate(HWI_HANDLE_T hwiNum,
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiDelete 函数:用于删除已经创建的硬件中断处理函数
|
|
|
|
|
//通过指定硬件中断号,可以将之前注册的中断处理函数从系统中删除
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqParam)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -417,7 +426,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDelete(HWI_HANDLE_T hwiNum, HWI_IRQ_PARAM_S *irqP
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiTrigger 函数:用于手动触发指定的硬件中断
|
|
|
|
|
//调用该函数后,会立即触发对应的硬件中断,使得系统执行相应的中断处理函数
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->triggerIrq == NULL)) {
|
|
|
|
@ -427,7 +437,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiTrigger(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->triggerIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiEnable 函数:用于使能指定的硬件中断
|
|
|
|
|
//调用该函数后,系统将允许对应的硬件中断产生,并执行相应的中断处理函数
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->enableIrq == NULL)) {
|
|
|
|
@ -437,7 +448,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiEnable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->enableIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiDisable 函数:用于禁止指定的硬件中断
|
|
|
|
|
//调用该函数后,系统将阻止对应的硬件中断产生,屏蔽其影响
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->disableIrq == NULL)) {
|
|
|
|
@ -447,7 +459,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiDisable(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->disableIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiClear 函数:用于清除指定的硬件中断
|
|
|
|
|
//在某些平台上,硬件中断发生后可能需要手动清除中断标志位,以便正确处理后续的中断
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->clearIrq == NULL)) {
|
|
|
|
@ -457,7 +470,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiClear(HWI_HANDLE_T hwiNum)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->clearIrq(hwiNum);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiSetPriority 函数:用于设置硬件中断的优先级
|
|
|
|
|
//通过指定硬件中断号和优先级,可以调整硬件中断的触发顺序
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T priority)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqPriority == NULL)) {
|
|
|
|
@ -468,6 +482,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetPriority(HWI_HANDLE_T hwiNum, HWI_PRIOR_T prio
|
|
|
|
|
return g_hwiOps->setIrqPriority(hwiNum, priority);
|
|
|
|
|
}
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SMP
|
|
|
|
|
//LOS_HwiSetAffinity函数:用于设置硬件中断的处理CPU亲和性
|
|
|
|
|
//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来设置中断的处理CPU亲和性
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->setIrqCpuAffinity == NULL)) {
|
|
|
|
@ -477,7 +493,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSetAffinity(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
|
|
|
|
|
return g_hwiOps->setIrqCpuAffinity(hwiNum, cpuMask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//LOS_HwiSendIpi函数:用于发送硬件中断处理请求给指定的CPU
|
|
|
|
|
//它首先检查硬件中断操作函数指针是否为空,然后调用具体的操作函数来发送中断处理请求
|
|
|
|
|
LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
{
|
|
|
|
|
if ((g_hwiOps == NULL) || (g_hwiOps->sendIpi == NULL)) {
|
|
|
|
@ -490,6 +507,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_HwiSendIpi(HWI_HANDLE_T hwiNum, UINT32 cpuMask)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_LOWPOWER
|
|
|
|
|
//LOS_IntWakeupHookReg函数:用于注册中断唤醒回调函数
|
|
|
|
|
//它将传入的回调函数赋值给全局变量g_intWakeupHook,以便在中断唤醒时调用该回调函数
|
|
|
|
|
LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
|
|
|
|
|
{
|
|
|
|
|
g_intWakeupHook = hook;
|
|
|
|
@ -497,6 +516,8 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_IntWakeupHookReg(WAKEUPFROMINTHOOK hook)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Initialization of the hardware interrupt */
|
|
|
|
|
//OsHwiInit函数:用于初始化硬件中断
|
|
|
|
|
//它会调用具体的平台相关函数来进行硬件中断的初始化操作
|
|
|
|
|
LITE_OS_SEC_TEXT_INIT VOID OsHwiInit(VOID)
|
|
|
|
|
{
|
|
|
|
|
ArchIrqInit();
|
|
|
|
|