コード例 #1
0
ファイル: int.c プロジェクト: djyos/djyos
//----设定中断同步-------------------------------------------------------------
//功能: 阻塞正在处理的事件的线程,直到指定的中断线的中断发生、响应并返回,然后才
//      激活线程。调用前确保该中断线被禁止,调用本函数将导致中断线被使能(是直接
//      使能,不是调用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;
}
コード例 #2
0
ファイル: exp.c プロジェクト: jiankangshiye/DJYOS
// =============================================================================
// 函数功能: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;
}