/********************************************************************************************************** * Copyright(C) 2017, Heilongjiang TYW Co.,Ltd. * * @Filename: Popup_Scheduler.c * * @Description: 报警调度 * * @Functions List: * * * @History: Version: V0.0.1 Date: 2018?1?29? 16?13? Author: myliu Modification: creat **********************************************************************************************************/ /********************************************************************************************************** * Include */ #include "Popup_Lib.h" #include "Popup_List.h" #include "Sound_List.h" #include "Popup_Message_List.h" #include "Popup_Scheduler.h" #include "rh850_macros.h" /********************************************************************************************************** * Constants and defines */ #define MAX_MEM_NUM 128u /*512bytes*/ /********************************************************************************************************** * Local variables */ #pragma alignvar(8) static CommMemBuf_t CommBuf[MAX_MEM_NUM]; static struct PopupList *FatalListHead = POPUPLIB_NULL; static struct PopupList *HintListHead = POPUPLIB_NULL; static struct PopupList *WarningListHead = POPUPLIB_NULL; static struct PopupList *ExceptionListHead = POPUPLIB_NULL; static PopupSchedulingStruct s_PopupScheduling; /********************************************************************************************************** * Local functions */ static struct PopupList *Popup_Polling_Next ( struct PopupList *CurPopup ); static void Popup_Update_Status ( uint16_t PopupID ); static void Popup_Fatal_Request ( uint16_t PopupID ); static void Popup_Hint_Request ( uint16_t PopupID ); static void Popup_Warning_Request ( uint16_t PopupID ); static void Popup_Exception_Request ( uint16_t PopupID ); static struct PopupList *Popup_Select ( uint16_t PopupID ); static void Popup_Delete_Request ( uint16_t PopupID ); static void Popup_Cal_CutGrade ( uint16_t NewPopupID ); static void Popup_Cal_CutGrade_loc ( uint16_t NewPopupID ); static uint8_t Popup_Compare_Priority ( uint16_t PopupID1, uint16_t PopupID2 ); static uint16_t Popup_Get_Last_Masked_Warning ( void ); static uint16_t Popup_Get_Previous_Masked_Warning ( uint16_t PopupID ); static uint16_t Popup_Get_Next_Masked_Warning ( uint16_t PopupID ); static void Popup_IRQ_Enable(void); static void Popup_IRQ_Disable(void); /********************************************************************************************************** * Global variables */ /********************************************************************************************************** * Global functions */ /********************************************************************************************************** *@Function: Popup_Scheduler_Init *@Description: 初始化弹出信息调度器 *@Input: MY_MemInit / CommMemInit *@Output: none. *@Calls: none. *@Return: none. *@Note: 存在内存管理函数,要求必须在硬件初始化之后,应用开始之前,进行初始化操作,且只能上电初始化一次 **********************************************************************************************************/ void Popup_Scheduler_Init ( void ) { PopupList_Opt_t PopupListOpt = {0}; PopupListOpt.CommMemBuf = CommBuf; PopupListOpt.MaxCommMenSize = MAX_MEM_NUM; PopupListOpt.pPopupAttributeTable = PopupAttributeTable; PopupListOpt.IRQ_Disable = Popup_IRQ_Disable; PopupListOpt.IRQ_Enable = Popup_IRQ_Enable; PopupList_Init(&PopupListOpt); /*初始化参数值*/ s_PopupScheduling.Timer = 0u; s_PopupScheduling.NewPopupID = POPUP_NONE; s_PopupScheduling.CurPopupID = POPUP_NONE; s_PopupScheduling.PollPopupID = POPUP_NONE; s_PopupScheduling.CurStatus = POPUP_STATUS_OFF; s_PopupScheduling.CutGrade = POPUP_CUT_NOT; s_PopupScheduling.SndReqCode = 1u; s_PopupScheduling.CurMaskedID = POPUP_NONE; s_PopupScheduling.WarningExist = FALSE; } /********************************************************************************************************** *@Function: Popup_Scheduler_OFF *@Description: PopupList_Destroy *@Input: MY_MemInit / CommMemInit *@Output: none. *@Calls: none. *@Return: none. *@Note: 进入休眠状态的时候,要关闭调度器,清掉所有触发的信息 **********************************************************************************************************/ void Popup_Scheduler_OFF ( void ) { /*1、删除全部重要类信息*/ FatalListHead = PopupList_Destroy ( FatalListHead ); /*2、删除全部提示类信息*/ HintListHead = PopupList_Destroy ( HintListHead ); /*3、删除全部报警类信息*/ WarningListHead = PopupList_Destroy ( WarningListHead ); /*4、删除全部特殊类信息*/ ExceptionListHead = PopupList_Destroy ( ExceptionListHead ); /*5、初始化参数值*/ s_PopupScheduling.Timer = 0u; s_PopupScheduling.NewPopupID = POPUP_NONE; s_PopupScheduling.CurPopupID = POPUP_NONE; s_PopupScheduling.PollPopupID = POPUP_NONE; s_PopupScheduling.CurStatus = POPUP_STATUS_OFF; s_PopupScheduling.CutGrade = POPUP_CUT_NOT; s_PopupScheduling.SndReqCode = 1u; s_PopupScheduling.CurMaskedID = POPUP_NONE; s_PopupScheduling.WarningExist = FALSE; } /********************************************************************************************************** *@Function: Popup_Scheduling_Service *@Description: 调度弹出信息,更新当前显示的信息名称,接口函数 * 可能发生切换的条件: * 1、当前显示信息被删除/屏蔽 * 2、产生优先级高的新消息 * 3、显示时间到 *@Input: CommMemInit *@Output: none. *@Calls: none *@Return: none *@Note: 该服务函数必须每100ms被调用一次 **********************************************************************************************************/ void Popup_Scheduling_Service ( void ) { struct PopupList *CurPopup = POPUPLIB_NULL; struct PopupList *NextPopup = POPUPLIB_NULL; uint8_t IsReturn = 0u; /*2、当前无显示,且无新信息,直接返回,否则,显示时间累加*/ if ( s_PopupScheduling.CurPopupID >= POPUP_MAX ) { if ( s_PopupScheduling.NewPopupID < POPUP_MAX ) { s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; } } else { CurPopup = Popup_Select ( s_PopupScheduling.CurPopupID ); if ( s_PopupScheduling.Timer < 0xFFu ) { s_PopupScheduling.Timer++; } } /*3、根据切换等级,做相应的处理*/ switch ( s_PopupScheduling.CutGrade ) { case POPUP_CUT_IMMEDIATELY: break; case POPUP_CUT_WAIT_TIME_MIN: #if POPUP_DEFINE_FIRST_DISPLAY if ( s_PopupScheduling.CurStatus == POPUP_STATUS_FIRST ) { if ( s_PopupScheduling.Timer < POPUP_DISP_TIME_MIN ) { IsReturn = 1u; } } #else if ( s_PopupScheduling.Timer < POPUP_DISP_TIME_MIN ) { IsReturn = 1u; } #endif break; case POPUP_CUT_WAIT_TIME_NORMAL: #if POPUP_DEFINE_FIRST_DISPLAY if ( s_PopupScheduling.CurStatus == POPUP_STATUS_FIRST ) { if ( s_PopupScheduling.Timer < POPUP_DISP_TIME_NORMAL ) { IsReturn = 1u; } s_PopupScheduling.NewPopupID = POPUP_NONE; } #else if ( s_PopupScheduling.Timer < POPUP_DISP_TIME_MIN ) { IsReturn = 1u; } #endif break; case POPUP_CUT_NOT: if ( s_PopupScheduling.Timer < POPUP_DISP_TIME_NORMAL ) { IsReturn = 1u; } break; default: break; } if (IsReturn == 0u) { /*4 清除切换等级*/ s_PopupScheduling.CutGrade = POPUP_CUT_NOT; /*5 切换报警信息*/ if ( s_PopupScheduling.NewPopupID < POPUP_MAX ) { NextPopup = Popup_Select ( s_PopupScheduling.NewPopupID ); if ( NextPopup == POPUPLIB_NULL ) { NextPopup = Popup_Polling_Next ( CurPopup ); } s_PopupScheduling.NewPopupID = POPUP_NONE; s_PopupScheduling.Timer = 0u; } else { NextPopup = Popup_Polling_Next ( CurPopup ); } /*6、更新当前显示的信息*/ if ( NextPopup != POPUPLIB_NULL ) { if ( NextPopup->PopupID != s_PopupScheduling.CurPopupID ) { if ( PopupAttributeTable[NextPopup->PopupID].Class != PopupAttributeTable[s_PopupScheduling.CurPopupID].Class ) { s_PopupScheduling.Timer = 0u; } s_PopupScheduling.CurStatus = NextPopup->Status; s_PopupScheduling.CurPopupID = NextPopup->PopupID; } } else { s_PopupScheduling.CurPopupID = POPUP_NONE; s_PopupScheduling.Timer = 0u; } /*7. 更新上一个报警的状态*/ if ( CurPopup != POPUPLIB_NULL ) { Popup_Update_Status ( CurPopup->PopupID ); } } return; } /********************************************************************************************************** *@Function: Popup_Request *@Description: 信息插入请求,包括全部类型,接口函数 *@Input: uint8_t PopupID -- 弹出信息的ID. *@Output: none. *@Calls: none. *@Return: none. *@Note: none. **********************************************************************************************************/ void Popup_Request ( uint16_t PopupID ) { switch ( PopupAttributeTable[PopupID].Type ) { case POPUP_TYPE_FATAL: Popup_Fatal_Request ( PopupID ); break; case POPUP_TYPE_HINT: Popup_Hint_Request ( PopupID ); break; case POPUP_TYPE_WARNING: Popup_Warning_Request ( PopupID ); break; case POPUP_TYPE_EXCEPTION: Popup_Exception_Request ( PopupID ); break; default: break; } return; } /********************************************************************************************************** *@Function: Popup_Mask_Request *@Description: 屏蔽第三类(报警类)信息,只有显示过的才可以被屏蔽 * ***********屏蔽全部显示过的*************** *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: none. **********************************************************************************************************/ void Popup_Mask_Request ( void ) { struct PopupList *p1 = POPUPLIB_NULL; if ( PopupAttributeTable[s_PopupScheduling.CurPopupID].Type == POPUP_TYPE_WARNING ) { s_PopupScheduling.CurMaskedID = s_PopupScheduling.CurPopupID; p1 = WarningListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->Status == POPUP_STATUS_LOOP ) { p1->Status = POPUP_STATUS_MASKED; } p1 = p1->next; } } return; } uint8_t Popup_WarningRequested ( void ); uint8_t Popup_WarningRequested ( void ) { struct PopupList *p1 = POPUPLIB_NULL; uint8_t retVal = 0u; p1 = FatalListHead; if ( p1 == POPUPLIB_NULL ) { p1 = HintListHead; while ( p1 != POPUPLIB_NULL ) { if ( ( p1->Status == POPUP_STATUS_NEW ) || ( p1->Status == POPUP_STATUS_FIRST ) || ( p1->Status == POPUP_STATUS_LOOP ) ) { retVal = 1u; } p1 = p1->next; } p1 = WarningListHead; while ( p1 != POPUPLIB_NULL ) { if ( ( p1->Status == POPUP_STATUS_NEW ) || ( p1->Status == POPUP_STATUS_FIRST ) || ( p1->Status == POPUP_STATUS_LOOP ) ) { retVal = 1u; } p1 = p1->next; } } else { retVal = 1u; } return retVal; } /********************************************************************************************************** *@Function: Popup_Del_Masked_Request *@Description: 在IGN_OFF时,需要将屏蔽过的报警信息显示出来,但不允许再次显示报警声音 *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: 目前将报警信息的状态切换为循环显示状态. **********************************************************************************************************/ void Popup_Del_Masked_Request ( void ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = WarningListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->Status == POPUP_STATUS_MASKED ) { p1->Status = POPUP_STATUS_LOOP; Popup_Cal_CutGrade ( p1->PopupID ); } p1 = p1->next; } } /********************************************************************************************************** *@Function: Popup_Get_Status *@Description: 获取查询信息的状态 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: none. *@Calls: PopupList_Select *@Return: POPUP_STATUS_OFF -- 此信息不在需要显示 * POPUP_STATUS_FIRST -- 此信息第一次显示 * POPUP_STATUS_LOOP -- 此信息处于轮询显示中 * POPUP_STATUS_MASKED -- 此信息被屏蔽 * POPUP_STATUS_DELETE -- 此信息等待被删除 * POPUP_STATUS_CLEAR -- 此信息马上被删除 *@Note: none. **********************************************************************************************************/ uint8_t Popup_Get_Status ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; uint8_t retStatus = POPUP_STATUS_OFF; switch ( PopupAttributeTable[PopupID].Type ) { case POPUP_TYPE_FATAL: p1 = PopupList_Select ( FatalListHead, &PopupID ); break; case POPUP_TYPE_HINT: p1 = PopupList_Select ( HintListHead, &PopupID ); break; case POPUP_TYPE_WARNING: p1 = PopupList_Select ( WarningListHead, &PopupID ); break; case POPUP_TYPE_EXCEPTION: p1 = PopupList_Select ( ExceptionListHead, &PopupID ); break; default: break; } if ( p1 != POPUPLIB_NULL ) { retStatus = p1->Status; } return retStatus; } /********************************************************************************************************** *@Function: Popup_Get_Current_Message *@Description: 获取当前信息的文字编号 *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: none. **********************************************************************************************************/ uint16_t Popup_Get_Current_Message ( void ) { uint16_t retPopupMsgID = POPUP_MSG_NONE; if ( s_PopupScheduling.CurPopupID < POPUP_MAX ) { retPopupMsgID = PopupAttributeTable[s_PopupScheduling.CurPopupID].Message; } return retPopupMsgID; } /********************************************************************************************************** *@Function: Popup_Get_Current_Sound *@Description: 获取当前信息的声音编号 *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: 声音请求码影响声音的持续性及是否打断 **********************************************************************************************************/ uint8_t Popup_Get_Current_Sound ( void ) { uint8_t retSndID = SND_NONE; if ( s_PopupScheduling.CurPopupID < POPUP_MAX ) { retSndID = PopupAttributeTable[s_PopupScheduling.CurPopupID].Snd; } return retSndID; } /********************************************************************************************************** *@Function: Popup_Get_Current_Sound_Req_Code *@Description: 获取当前信息的声音请求码 *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: 声音请求码影响声音的持续性及是否打断 **********************************************************************************************************/ uint8_t Popup_Get_Current_Sound_Req_Code ( void ) { struct PopupList *p1 = POPUPLIB_NULL; uint8_t retReqCode = 0u; if ( s_PopupScheduling.CurPopupID < POPUP_MAX ) { if ( PopupAttributeTable[s_PopupScheduling.CurPopupID].SndMode == POPUP_MODE_MULTI ) { if ( s_PopupScheduling.SndReqCode == 0xFFu ) { s_PopupScheduling.SndReqCode = 0x01u; } else { s_PopupScheduling.SndReqCode++; } retReqCode = s_PopupScheduling.SndReqCode; } else { p1 = Popup_Select ( s_PopupScheduling.CurPopupID ); if ( p1 != POPUPLIB_NULL ) { if ( p1->Status == POPUP_STATUS_FIRST ) { retReqCode = s_PopupScheduling.SndReqCode; } } } } return retReqCode; } /********************************************************************************************************** *@Function: Popup_Delete *@Description: 清除当前显示信息,如果是第一次显示,要等待Tmin(第二类信息(提示类)除外) *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: FatalListHead/HintListHead/WarningListHead/ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Delete *@Return: none. *@Note: none. **********************************************************************************************************/ void Popup_Delete ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = Popup_Select ( PopupID ); if ( p1 != POPUPLIB_NULL ) { if ( p1->PopupID == s_PopupScheduling.CurPopupID ) { p1->Status = POPUP_STATUS_DELETE; if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_HINT ) { s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; } else { s_PopupScheduling.CutGrade = POPUP_CUT_WAIT_TIME_MIN; } } else { Popup_Delete_Request ( PopupID ); } } return; } /********************************************************************************************************** *@Function: Popup_Clear *@Description: 清除当前显示信息,不需要等待Tmin *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: FatalListHead/HintListHead/WarningListHead/ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Delete *@Return: none. *@Note: none. **********************************************************************************************************/ void Popup_Clear ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = Popup_Select ( PopupID ); if ( p1 != POPUPLIB_NULL ) { if ( p1->PopupID == s_PopupScheduling.CurPopupID ) { p1->Status = POPUP_STATUS_CLEAR; s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; } else { Popup_Delete_Request ( PopupID ); } } return; } /********************************************************************************************************** *@Function: Popup_Get_Warning_Status *@Description: 查询是否存在报警类信息/或者是获取显示致命信息下,是否存在报警类信息 *@Input: none *@Output: none *@Calls: none *@Return: TRUE --存在报警类信息 * FALSE -- 不存在报警类信息 *@Note: none. **********************************************************************************************************/ uint8_t Popup_Get_Warning_Status ( void ) { uint8_t retVal = 0u; if ( WarningListHead != POPUPLIB_NULL ) { retVal = 1u; } return retVal; } /********************************************************************************************************** *@Function: Popup_Get_Masked_Warning_Msg *@Description: 获取当前显示的屏蔽信息的文字/图片编号 *@Input: none *@Output: none *@Calls: none *@Return: 文字/图片编号 *@Note: none. **********************************************************************************************************/ uint16_t Popup_Get_Masked_Warning_Msg ( void ) { uint16_t retMaskedID = POPUP_MSG_NONE; if ( s_PopupScheduling.CurMaskedID < POPUP_MAX ) { retMaskedID = s_PopupScheduling.CurMaskedID; } return retMaskedID; } /********************************************************************************************************** *@Function: Popup_Masked_Warning_Polling_Reset *@Description: 复位屏蔽信息当前显示的指针,向前,则指向最后一个;向后,则指向第一个 *@Input: none. *@Output: none. *@Calls: none. *@Return: none. *@Note: none. **********************************************************************************************************/ void Popup_Masked_Warning_Polling_Reset ( uint8_t Mode ) { uint16_t PopupID; if ( Mode == POPUP_POLLING_FORWARD ) { PopupID = Popup_Get_First_Masked_Warning(); } else { PopupID = Popup_Get_Last_Masked_Warning(); } s_PopupScheduling.CurMaskedID = PopupID; return; } /********************************************************************************************************** 函数名:Popup_Masked_Warning_Polling 功 能:查询已屏蔽的报警 每调用一次此函数,已屏蔽报警指针会按指定方向移动一位,当指针已移指定方向 上的最后一个报警信息时,再次向同一方向查询,当前的已屏蔽报警信息会变为 POPUP_NONE 表示报警查询已结束 例如:当前有已屏蔽报警 A、B、C、D,调用Popup_Masked_Warning_Polling_Reset 函数,设定方向为 POPUP_POLLING_FORWARD 时,已屏蔽报警指针会指向报警A,而后, 调用该函数设定方向为 POPUP_POLLING_FORWARD 时已屏蔽报警指针即指向报警B. 重复调用此函数且方向不变至已屏蔽报警指针指向报警D后,再以相同方向调用此函 数则返回 POPUP_NONE,表示查询已结束 通过调用Popup_Get_Masked_Warning可读出当前已屏蔽报警指针指向的报警 参 数:Mode:查询模式 POPUP_POLLING_FORWARD - 正向查找模式 POPUP_POLLING_REVERSE - 逆向查找模式 返回值:无 **********************************************************************************************************/ void Popup_Masked_Warning_Polling ( uint8_t Mode ) { uint16_t PopupEnd; uint16_t PopupID; PopupID = s_PopupScheduling.CurMaskedID; if ( PopupID != POPUP_NONE ) { if ( Mode == POPUP_POLLING_FORWARD ) { PopupEnd = Popup_Get_Last_Masked_Warning(); if ( PopupEnd != POPUP_NONE ) { if ( PopupID == PopupEnd ) { s_PopupScheduling.CurMaskedID = POPUP_NONE; } else { s_PopupScheduling.CurMaskedID = Popup_Get_Next_Masked_Warning ( PopupID ); } } } else { PopupEnd = Popup_Get_First_Masked_Warning(); if ( PopupEnd != POPUP_NONE ) { if ( PopupID == PopupEnd ) { s_PopupScheduling.CurMaskedID = POPUP_NONE; } else { s_PopupScheduling.CurMaskedID = Popup_Get_Previous_Masked_Warning ( PopupID ); } } } } return; } /********************************************************************************************************** *@Function: Popup_Update_Status *@Description: 更新指定弹出信息的状态 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: none *@Calls: PopupList_Select / PopupList_Delete *@Return: none. *@Note: none. **********************************************************************************************************/ static void Popup_Update_Status ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; /*1、根据类型,查找ID位置*/ p1 = Popup_Select ( PopupID ); if ( p1 != POPUPLIB_NULL ) { if ( ( p1->Status == POPUP_STATUS_CLEAR ) || ( p1->Status == POPUP_STATUS_DELETE ) ) { ; Popup_Delete_Request ( p1->PopupID ); } else if ( p1->Status != POPUP_STATUS_MASKED ) { if ( PopupAttributeTable[p1->PopupID].DispMode == POPUP_MODE_SINGLE ) { p1->Status = POPUP_STATUS_OFF; } else { p1->Status = POPUP_STATUS_LOOP; } } else { } } } /********************************************************************************************************** *@Function: Popup_Polling_Next *@Description: 切换轮询的下个显示 *@Input: none *@Output: none *@Calls: PopupList_Select / PopupList_Malloc / PopupList_Insert / Popup_Cal_CutGrade *@Return: none. *@Note: none. **********************************************************************************************************/ static struct PopupList *Popup_Polling_Next ( struct PopupList *CurPopup ) { struct PopupList *NextPopup = POPUPLIB_NULL; if ( CurPopup != POPUPLIB_NULL ) { NextPopup = CurPopup->next; #if POPUP_DEFINE_FIRST_DISPLAY while ( NextPopup != POPUPLIB_NULL ) { if ( NextPopup->Status == POPUP_STATUS_FIRST ) { break; } NextPopup = NextPopup->next; } #endif while ( NextPopup != POPUPLIB_NULL ) { if ( ( NextPopup->Status == POPUP_STATUS_LOOP ) || ( NextPopup->Status == POPUP_STATUS_FIRST ) ) { break; } NextPopup = NextPopup->next; } } if ( NextPopup == POPUPLIB_NULL ) { if ( FatalListHead != POPUPLIB_NULL ) { NextPopup = FatalListHead; while ( NextPopup != POPUPLIB_NULL ) { if ( ( NextPopup->Status == POPUP_STATUS_FIRST ) || ( NextPopup->Status == POPUP_STATUS_LOOP ) ) { break; } NextPopup = NextPopup->next; } } if ( ( HintListHead != POPUPLIB_NULL ) && ( NextPopup == POPUPLIB_NULL ) ) { NextPopup = HintListHead; while ( NextPopup != POPUPLIB_NULL ) { if ( ( NextPopup->Status == POPUP_STATUS_FIRST ) || ( NextPopup->Status == POPUP_STATUS_LOOP ) ) { break; } NextPopup = NextPopup->next; } } if ( ( WarningListHead != POPUPLIB_NULL ) && ( NextPopup == POPUPLIB_NULL ) ) { #if POPUP_CUT_RECOVER if ( s_PopupScheduling.PollPopupID < POPUP_MAX ) { NextPopup = PopupList_Select ( WarningListHead, &s_PopupScheduling.PollPopupID ); s_PopupScheduling.PollPopupID = POPUP_NONE; } #endif if ( NextPopup == POPUPLIB_NULL ) { NextPopup = WarningListHead; while ( NextPopup != POPUPLIB_NULL ) { if ( ( NextPopup->Status == POPUP_STATUS_FIRST ) || ( NextPopup->Status == POPUP_STATUS_LOOP ) ) { break; } NextPopup = NextPopup->next; } } } if ( ( ExceptionListHead != POPUPLIB_NULL ) && ( NextPopup == POPUPLIB_NULL ) ) { NextPopup = HintListHead; while ( NextPopup != POPUPLIB_NULL ) { if ( ( NextPopup->Status == POPUP_STATUS_FIRST ) || ( NextPopup->Status == POPUP_STATUS_LOOP ) ) { break; } NextPopup = NextPopup->next; } } } return NextPopup; } /********************************************************************************************************** *@Function: Popup_Fatal_Request *@Description: 插入第一类信息,并确定其切换等级 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Malloc / PopupList_Insert / Popup_Cal_CutGrade *@Return: none. *@Note: none. **********************************************************************************************************/ static void Popup_Fatal_Request ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = PopupList_Select ( FatalListHead, &PopupID ); #if 1 //VC66 组1 组内插入 上位优先. struct PopupList *pwby = FatalListHead ; while(pwby != POPUPLIB_NULL) { if(pwby->PopupID < PopupID) { Popup_Delete(PopupID); return ; } pwby = pwby->next ; } #endif if ( p1 == POPUPLIB_NULL) { p1 = HintListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->Status != POPUP_STATUS_OFF ) { p1->Status = POPUP_STATUS_OFF; } p1 = p1->next; } p1 = PopupList_Malloc(); if ( p1 != POPUPLIB_NULL ) { p1->PopupID = PopupID; p1->Status = POPUP_STATUS_FIRST; p1->next = POPUPLIB_NULL; FatalListHead = PopupList_Insert ( FatalListHead, p1 ); Popup_Cal_CutGrade ( PopupID ); } } else { if ((p1->Status == POPUP_STATUS_DELETE) || (p1->Status == POPUP_STATUS_CLEAR)) { p1->Status = POPUP_STATUS_FIRST; } } return; } /********************************************************************************************************** *@Function: Popup_Hint_Request *@Description: 插入第二类信息,并确定其切换等级 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Malloc / PopupList_Insert / Popup_Cal_CutGrade *@Return: none. *@Note: none. **********************************************************************************************************/ static void Popup_Hint_Request ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = PopupList_Select ( HintListHead, &PopupID ); if ( p1 == POPUPLIB_NULL ) { p1 = PopupList_Malloc(); if ( p1 != POPUPLIB_NULL ) { p1->PopupID = PopupID; if ( FatalListHead == POPUPLIB_NULL ) { p1->Status = POPUP_STATUS_FIRST; s_PopupScheduling.NewPopupID = PopupID; #if POPUP_HINT_CUT_HINT_IMMEDIATELY s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; /*提示信息可以打断提示类、报警类,所以如果不是特殊类信息,提示类都可以立即打断 */ #else s_PopupScheduling.CutGrade = POPUP_CUT_WAIT_TIME_MIN; /*提示信息可以打断提示类、报警类,所以如果不是特殊类信息,提示类都可以立即打断 */ #endif s_PopupScheduling.PollPopupID = s_PopupScheduling.CurPopupID; } else { p1->Status = POPUP_STATUS_OFF; } p1->next = POPUPLIB_NULL; HintListHead = PopupList_Insert ( HintListHead, p1 ); } } return; } /********************************************************************************************************** *@Function: Popup_Warning_Request *@Description: 插入第三类信息,并确定其切换等级 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Malloc / PopupList_Insert / Popup_Cal_CutGrade *@Return: none. *@Note: none. **********************************************************************************************************/ static void Popup_Warning_Request ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = PopupList_Select ( WarningListHead, &PopupID ); if ( p1 == POPUPLIB_NULL ) { /*普通报警可以打断提示类信息,且未显示的提示类信息,不再进行显示,等同于特殊报警*/ #if POPUP_WARNING_CUT_HINT_MIN p1 = HintListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->Status != POPUP_STATUS_OFF ) { p1->Status = POPUP_STATUS_OFF; } p1 = p1->next; } #endif p1 = PopupList_Malloc(); if ( p1 != POPUPLIB_NULL ) { p1->PopupID = PopupID; p1->Status = POPUP_STATUS_FIRST; p1->next = POPUPLIB_NULL; WarningListHead = PopupList_Insert ( WarningListHead, p1 ); /*如果存在特殊报警,不更新新信息*/ if ( FatalListHead == POPUPLIB_NULL ) { #if POPUP_WARNING_CUT_HINT_MIN /*如果存在提示类信息,等待最小时间后,打断*/ if ( PopupAttributeTable[s_PopupScheduling.CurPopupID].Type == POPUP_TYPE_HINT ) { s_PopupScheduling.NewPopupID = PopupID; s_PopupScheduling.CutGrade = POPUP_CUT_WAIT_TIME_MIN; } else { Popup_Cal_CutGrade ( PopupID ); } #else Popup_Cal_CutGrade ( PopupID ); #endif } } } return; } /********************************************************************************************************** *@Function: Popup_Exception_Request *@Description: 插入第四类信息,并确定其切换等级 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: ExceptionListHead -- 新链表 *@Calls: PopupList_Select / PopupList_Malloc / PopupList_Insert / Popup_Cal_CutGrade *@Return: none. *@Note: none. **********************************************************************************************************/ static void Popup_Exception_Request ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; p1 = PopupList_Select ( ExceptionListHead, &PopupID ); if ( p1 == POPUPLIB_NULL ) { p1 = PopupList_Malloc(); if ( p1 != POPUPLIB_NULL ) { p1->PopupID = PopupID; p1->Status = POPUP_STATUS_FIRST; p1->next = POPUPLIB_NULL; ExceptionListHead = PopupList_Insert ( ExceptionListHead, p1 ); if ( FatalListHead == POPUPLIB_NULL ) { Popup_Cal_CutGrade ( PopupID ); } } } return; } /********************************************************************************************************** *@Function: Popup_Select *@Description: 在全部链表中查找指定ID的位置 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: struct PopupList *head -- 链表头 * struct PopupList *p -- 指定ID所在的位置 *@Calls: PopupList_Select *@Return: struct PopupList *p -- 指定ID所在的位置 *@Note: none **********************************************************************************************************/ static struct PopupList *Popup_Select ( uint16_t PopupID ) { struct PopupList *head = POPUPLIB_NULL; struct PopupList *p1 = POPUPLIB_NULL; /*1、根据类型,获取链表头*/ if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_FATAL ) { head = FatalListHead; } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_HINT ) { head = HintListHead; } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_WARNING ) { head = WarningListHead; } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_EXCEPTION ) { head = ExceptionListHead; } else { } /*2、查找ID位置*/ if ( head != POPUPLIB_NULL ) { p1 = PopupList_Select ( head, &PopupID ); } return p1; } /********************************************************************************************************** *@Function: Popup_Delete_Request *@Description: 在全部链表中查找指定ID的位置 *@Input: uint8_t PopupID -- 弹出信息的ID *@Output: struct PopupList *head -- 链表头 * struct PopupList *p -- 指定ID所在的位置 *@Calls: PopupList_Select *@Return: struct PopupList *p -- 指定ID所在的位置 *@Note: none **********************************************************************************************************/ static void Popup_Delete_Request ( uint16_t PopupID ) { /*1、根据类型,获取链表头*/ if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_FATAL ) { FatalListHead = PopupList_Delete ( FatalListHead, PopupID ); } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_HINT ) { HintListHead = PopupList_Delete ( HintListHead, PopupID ); } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_WARNING ) { WarningListHead = PopupList_Delete ( WarningListHead, PopupID ); } else if ( PopupAttributeTable[PopupID].Type == POPUP_TYPE_EXCEPTION ) { ExceptionListHead = PopupList_Delete ( ExceptionListHead, PopupID ); } else { } return; } /********************************************************************************************************** *@Function: Popup_Cal_CutGrade *@Description: 计算新信息的切换等级 *@Input: uint8_t NewPopupID -- 新的弹出信息ID *@Output: none. *@Calls: Popup_Compare_Priority *@Return: Grade0 -- 无切换请求 * Grade1 -- 低切换等级,当前显示信息,如果是第一次需要满足Tnormal(4s);否则,立即打断. * Grade2 -- 中切换等级,当前显示信息,如果是第一次需要满足Tmin(2s);否则,立即打断. * Grade3 -- 高切换等级,立即打断当前显示信息. *@Note: none **********************************************************************************************************/ static void Popup_Cal_CutGrade ( uint16_t NewPopupID ) { uint8_t ret = 0u; /*已经存在切换等级,如果新信息的优先级低于未显示的信息,则切换等级维持不变*/ if ( s_PopupScheduling.NewPopupID < POPUP_MAX ) { ret = Popup_Compare_Priority ( NewPopupID, s_PopupScheduling.NewPopupID ); if ( ret != 0u ) { s_PopupScheduling.NewPopupID = NewPopupID; Popup_Cal_CutGrade_loc(NewPopupID); } } else { s_PopupScheduling.NewPopupID = NewPopupID; Popup_Cal_CutGrade_loc(NewPopupID); } return; } static void Popup_Cal_CutGrade_loc ( uint16_t NewPopupID ) { uint8_t ret = 0u; if ( s_PopupScheduling.CurPopupID < POPUP_MAX ) { ret = Popup_Compare_Priority ( NewPopupID, s_PopupScheduling.CurPopupID ); switch ( ret ) { case 0u: /*新信息优先级低于/等于当前显示类型*/ if ( PopupAttributeTable[NewPopupID].Class == PopupAttributeTable[s_PopupScheduling.CurPopupID].Class ) { #if POPUP_SAME_CLASS_CUT_IMMEDIATELY s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; /*类型相同,立即打断当前*/ Popup_Update_Status ( s_PopupScheduling.CurPopupID ); s_PopupScheduling.SndReqCode++; #endif } else { if(PopupAttributeTable[NewPopupID].Type != POPUP_TYPE_FATAL) { //wangboyu -add -begin -2021年8月20日09:27:10 //针对VC66 组1 - 上位优先 s_PopupScheduling.CutGrade = POPUP_CUT_WAIT_TIME_NORMAL; } } break; #if POPUP_HIGH_CUT_LOW_TYPE_IMMEDIATELY case 1u: /*新信息的类型高*/ s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; s_PopupScheduling.PollPopupID = s_PopupScheduling.CurPopupID; break; #endif case 2u: case 3u: /*新信息的优先级高(包括主、副优先级)*/ s_PopupScheduling.CutGrade = POPUP_CUT_WAIT_TIME_MIN; break; default: s_PopupScheduling.CutGrade = POPUP_CUT_NOT; break; } } else { s_PopupScheduling.CutGrade = POPUP_CUT_IMMEDIATELY; } } /********************************************************************************************************** *@Function: Popup_Compare_Priority *@Description: 比较两种弹出消息的优先级 *@Input: uint8_t PopupID1 -- 弹出信息1 * uint8_t PopupID2 -- 弹出信息2 *@Output: none. *@Calls: PopupAttributeTable -- 属性表 *@Return: 0 -- 两种优先级相同或PopupID1的优先级低 * 1 -- PopupID1的类型高于PopupID2的类型 * 2 -- PopupID1的主优先级高于PopupID2的主优先级 * 3 -- PopupID1的副优先级高于PopupID2的副优先级 *@Note: none **********************************************************************************************************/ static uint8_t Popup_Compare_Priority ( uint16_t PopupID1, uint16_t PopupID2 ) { uint8_t ret = 0u; /*比较类型*/ if ( PopupAttributeTable[PopupID1].Type < PopupAttributeTable[PopupID2].Type ) { ret = 1u; } else if ( PopupAttributeTable[PopupID1].Type == PopupAttributeTable[PopupID2].Type ) { /*类型相同,比较主优先级*/ if ( PopupAttributeTable[PopupID1].Priority < PopupAttributeTable[PopupID2].Priority ) { ret = 2u; } else if ( PopupAttributeTable[PopupID1].Priority == PopupAttributeTable[PopupID2].Priority ) { /*类型相同,主优先级相同,比较副优先级*/ if ( PopupAttributeTable[PopupID1].SubPriority < PopupAttributeTable[PopupID2].SubPriority ) { ret = 3u; } } else { } } else { } return ret; } /********************************************************************************************************** *@Function: Popup_Get_First_Masked_Warning *@Description: 获取第一个屏蔽信息 *@Input: none. *@Output: none. *@Calls: none. *@Return: 第一个屏蔽信息的ID,如果没有屏蔽信息,返回POPUP_NONE *@Note: none **********************************************************************************************************/ uint16_t Popup_Get_First_Masked_Warning ( void ) { struct PopupList *p = POPUPLIB_NULL; uint16_t retVal = POPUP_NONE; p = WarningListHead; while ( p != POPUPLIB_NULL ) { if ( p->Status == POPUP_STATUS_MASKED ) { break; } p = p->next; } if ( p != POPUPLIB_NULL ) { retVal = p->PopupID; } return retVal; } /********************************************************************************************************** *@Function: Popup_Get_Last_Masked_Warning *@Description: 获取最后一个屏蔽信息 *@Input: none. *@Output: none. *@Calls: none. *@Return: 最后一个屏蔽信息的ID,如果没有屏蔽信息,返回POPUP_NONE *@Note: none **********************************************************************************************************/ static uint16_t Popup_Get_Last_Masked_Warning ( void ) { struct PopupList *p1 = POPUPLIB_NULL; struct PopupList *p2 = POPUPLIB_NULL; uint16_t retVal = POPUP_NONE; p1 = WarningListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->Status == POPUP_STATUS_MASKED ) { p2 = p1; } p1 = p1->next; } if ( p2 != POPUPLIB_NULL ) { retVal = p2->PopupID; } return retVal; } /********************************************************************************************************** *@Function: Popup_Get_Previous_Masked_Warning *@Description: 获取当前显示的屏蔽信息的上一个屏蔽信息 *@Input: none. *@Output: none. *@Calls: none. *@Return: 上一个屏蔽信息的ID,如果上一个信息为空,返回POPUP_NONE *@Note: none **********************************************************************************************************/ static uint16_t Popup_Get_Previous_Masked_Warning ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; struct PopupList *p2 = POPUPLIB_NULL; uint16_t retVal = POPUP_NONE; p1 = WarningListHead; while ( p1 != POPUPLIB_NULL ) { if ( p1->PopupID == PopupID ) { break; } if ( ( p1->Status == POPUP_STATUS_MASKED ) && ( PopupAttributeTable[PopupID].Class != PopupAttributeTable[p1->PopupID].Class ) ) { p2 = p1; } p1 = p1->next; } if ( p2 != POPUPLIB_NULL ) { retVal = p2->PopupID; } return retVal; } /********************************************************************************************************** *@Function: Popup_Get_Previous_Masked_Warning *@Description: 获取当前显示的屏蔽信息的下一个屏蔽信息 *@Input: none. *@Output: none. *@Calls: none. *@Return: 下一个屏蔽信息的ID,如果下一个信息为空,返回POPUP_NONE *@Note: none **********************************************************************************************************/ static uint16_t Popup_Get_Next_Masked_Warning ( uint16_t PopupID ) { struct PopupList *p1 = POPUPLIB_NULL; uint16_t retVal = POPUP_NONE; p1 = PopupList_Select ( WarningListHead, &PopupID ); p1 = p1->next; while ( p1 != POPUPLIB_NULL ) { if ( ( p1->Status == POPUP_STATUS_MASKED ) && ( PopupAttributeTable[PopupID].Class != PopupAttributeTable[p1->PopupID].Class ) ) { break; } p1 = p1->next; } if ( p1 != POPUPLIB_NULL ) { retVal = p1->PopupID; } return retVal; } static void Popup_IRQ_Enable(void) { //IRQ_ENABLE(); enable_interrupt(); } static void Popup_IRQ_Disable(void) { //IRQ_DISABLE(); disable_interrupt(); } /****************************************************************************** 函数名:Popup_Mask_Request 功 能:请求屏蔽报警信息 可以在任意时刻发出屏蔽请求,只有满足屏蔽条件时,报警信息才会被屏蔽 参 数:无 返回值:无 ******************************************************************************/ void Popup_Hint_Mask_Request ( uint16_t PopupID ) { } /********************************************************************************************************** **********************************************************************************************************/