//----设定中断同步------------------------------------------------------------- //功能: 阻塞正在处理的事件的线程,直到指定的中断线的中断发生、响应并返回,然后才 // 激活线程。调用前确保该中断线被禁止,调用本函数将导致中断线被使能(是直接 // 使能,不是调用int_save_asyn_line),并在返回后恢复禁止状态。 //参数: ufl_line,等待的目标中断线 //返回: false = 该中断已经被其他线程等待,直接返回。 // true = 成功同步,并在该中断发生后返回。 //备注: 1.中断是一种临界资源,不宜在中断函数中太多的事情,故中断同步的功能比较简 // 单,每条中断线同一时刻只能有一个线程等待,也不允许设置超时等待 // 2.秉承djyos一贯风格,中断同步函数只能把自己置入等待状态,而不能控制别的 // 线程,故函数原型不能是 bool_t int_sync(ufast_t line,uint16_t event_id) // 3.实时中断设置等待无效,调用本函数时,如果line已经被设置为实时中断,则 // 直接返回false,如果调用本函数后,line不能被设置为实时中断。 // 4.为正确实现功能,须在调用前确保该中断线是被禁止的。 //----------------------------------------------------------------------------- bool_t Int_AsynSignalSync(ufast_t ufl_line) { if( (ufl_line > CN_INT_LINE_LAST) || (tg_pIntLineTable[ufl_line] == NULL) ) return false; if( !Djy_QuerySch()) { //禁止调度,不能进入异步信号同步状态。 Djy_SaveLastError(EN_KNL_CANT_SCHED); return false; } Int_SaveAsynSignal(); //在操作就绪队列期间不能发生中断 //实时中断不能设置同步,一个中断只接受一个同步事件 if((tg_pIntLineTable[ufl_line]->int_type == CN_REAL) || (tg_pIntLineTable[ufl_line]->sync_event != NULL)) { Int_RestoreAsynSignal(); return false; //实时中断或已经有同步事件 }else { if(Int_QueryLine(ufl_line) == true) //中断已经发生,同步条件达到 { Int_ClearLine(ufl_line); Int_RestoreAsynSignal(); return true; } //以下三行从就绪链表中取出running事件 __Djy_CutReadyEvent(g_ptEventRunning); g_ptEventRunning->next = NULL; g_ptEventRunning->previous = NULL; g_ptEventRunning->event_status = CN_STS_WAIT_ASYN_SIGNAL; tg_pIntLineTable[ufl_line]->sync_event = g_ptEventRunning; } Int_EnableAsynLine(ufl_line); Int_RestoreAsynSignal(); //调用本函数将引发线程切换,正在处理的事件被 //挂起。 Int_DisableAsynLine(ufl_line); g_ptEventRunning->wakeup_from = CN_STS_WAIT_ASYN_SIGNAL; g_ptEventRunning->event_status = CN_STS_EVENT_READY; return true; }
// ============================================================================= // 函数功能:Exp_Throw // 处理所有异常的入口 // 输入参数:throwpara,抛出的异常信息参数 // 输出参数:dealresult,该异常的最终处理结果 // 返回值 :true,成功, false,失败(参数或者存储等未知原因) // 说明 :异常抛出的唯一入口;如果要重启,则该函数不返回 // ============================================================================= bool_t Exp_Throw(struct tagExpThrowPara *throwpara, u32 *dealresult) { bool_t result; u32 result_hook; u32 result_throw; u32 result_deal; ptu32_t infoaddr; u32 infolen; struct tagExpHeadInfo headinfo; struct tagExpRecordPara recordpara; if(s_bExpMoDuleInitState == false) //组件未初始化,证明很多系统调用都不能使用 { return false; } Int_SaveAsynSignal(); if((NULL != throwpara) &&( true == throwpara->validflag))//抛出有效 { //抛出信息处理 if(NULL != throwpara->name) { strncpy(&headinfo.decodername[0], throwpara->name, CN_EXP_NAMELEN_LIMIT); } else { headinfo.decodername[0] = '\0'; } headinfo.throwinfolen = throwpara->para_len; headinfo.throwresult = throwpara->dealresult; headinfo.throwinfovalid = CN_EXP_PARTIALINFO_VALID; result_throw = throwpara->dealresult; recordpara.throwinfoaddr = (ptu32_t)(throwpara->para); recordpara.throwinfolen = throwpara->para_len; recordpara.headinfoaddr = (ptu32_t)(&(headinfo)); recordpara.headinfolen = (u32)(sizeof(headinfo)); //HOOK信息的搜集(如果搜集不成功,并且抛出者无意记录,则直接返回) result = Exp_HookDealer(throwpara, &infoaddr, &infolen, &result_hook); if(false == result) { result_hook = EN_EXP_DEAL_DEFAULT; headinfo.hookvalid = ~CN_EXP_PARTIALINFO_VALID; infoaddr = 0; infolen = 0; } else { headinfo.hookvalid = CN_EXP_PARTIALINFO_VALID; } result_deal = __Exp_ResultMerge(result_throw, result_hook); if(result_deal < EN_EXP_DEAL_RECORD) { //连记录都无需的话,那么就直接返回吧,简直开玩笑 result = true; *dealresult = EN_EXP_DEALT_IGNORE; goto throw_logic_exit; } headinfo.dealresult = result_deal; headinfo.hookinfolen = infolen; headinfo.hookresult = result_hook; recordpara.hookinfoaddr = infoaddr; recordpara.hookinfolen = infolen; //OSSTATE信息的搜集(如果搜集不成功,无关大局) result = Exp_OsStateInfoGather(throwpara, &infoaddr, &infolen); if(false == result) { infoaddr = 0; infolen = 0; headinfo.osstatevalid = ~CN_EXP_PARTIALINFO_VALID; } else { headinfo.osstatevalid = CN_EXP_PARTIALINFO_VALID; } headinfo.osstateinfolen = infolen; headinfo.recordendian = CN_CFG_BYTE_ORDER; headinfo.magicnumber = CN_EXP_HEADINFO_MAGICNUMBER; recordpara.osstateinfoaddr = infoaddr; recordpara.osstateinfolen = infolen; //该搜集的信息都搜集完毕,那么就处理吧 *dealresult = __Exp_ResultDeal(result_deal, &recordpara); result = true; } else { *dealresult = EN_EXP_DEALT_PARAERR; result = true; } throw_logic_exit: Int_RestoreAsynSignal(); return result; }