DoVrgEndptDeinit(arg);
//如果之前初始化阶段完成,则释放每条线路的所有媒体连接
if ( initStatus & VRGENDPTINIT_COMPLETED )
for (i = 0; i < vrgEndptGetNumEndpoints(); i++)
for( cnxIndex = 0; cnxIndex < VRG_ENDPT_CFG_MAX_CNX_PER_ENDPT; cnxIndex++ )
endptDeleteConnection( (ENDPT_STATE*)&vrgEndptArchive[i], cnxIndex );
vrgEndptDeinit();
for (i = 0; i < vrgEndptGetNumEndpoints(); i++)
state = &vrgEndpt[i];
state->isLineUsed = VRG_FALSE;
classStmDeinit( &state->classState ); //线路的CAS状态机复位
//关闭DSP之前创建的线路通道
if ( endptConfig.initState & EPEINIT_CNXSTATE )
for ( i = 0; i < vrgEndptGetNumEndpoints(); i++ )
state = &vrgEndpt[i];
if ( state->lineVhdHdl != 0xffff )
hdspVhdClose( state->lineVhdHdl, state->dspNum )
//关闭DSP之前创建的媒体通道
if ( endptConfig.initState & EPEINIT_CNXVHD )
for ( i = 0; i < VRG_ENDPT_CFG_NUM_CNX; i++ )
if ( vrgCnxState[i].vhdhdl )
hdspVhdClose( vrgCnxState[i].vhdhdl, vrgCnxState[i].dspNum )
//让BOS的根任务通知所有创建的子任务进行复位,这里的操作流程如下
//1、释放boszcb.appResetSemId信号量,用于触发根任务流程,让根任务
//开始给所有子任务发送复位
//2、根任务信号量被触发后,调用TaskResetNotifyAll();通知所有子任务开
//始复位,并等待所有子任务ACK,注意这里如果有任何一个子任务出错,
//都会导致卡在这里。这里TaskResetNotifyAll函数更改所有子任务TCB的状态
//为BOS_TASKSTATE_RESET_NTFY,在子任务中调用一些如bosSleep等函数,遇到
//当前任务状态为BOS_TASKSTATE_RESET_NTFY,则返回错误码BOS_STATUS_RESET,
//子任务在收到错误码后,调用bosTaskResetAck函数,来释放boszcb.taskResetSemId
//信号量,并等待BOS_TASKSHUTDOWN_EVENT事件。
//3、根任务等待所有子任务都调用了boszcb.taskResetSemId信号量后,根任务释
//放boszcb.appResetCompletedSemId信号量,以告诉bosAppReset函数所有子任
//务已经退出
//4、bosAppReset在信号量被触发后,整个函数bosAppReset才执行完成。
//注意这里,其它子任务还没有完全退出,卡在等待BOS_TASKSHUTDOWN_EVENT
//事件上,后面不同子任务退出都会调用bosTaskProceedToShutdown来给该子任
//务发会BOS_TASKSHUTDOWN_EVENT事件
bosAppReset();
//复位DSP相关的错误处理任务
if ( endptConfig.initState & EPEINIT_HDSP )
hdspDeinit() != HAPISUCCESS )
if ( endptConfig.initState & EPEINIT_CAS )
//CAS控制任务退出,机制的实现见上面bosAppReset函数相关注释说明
casCtlDeinit()
bosTaskProceedToShutdown( &casState.taskId );
bosTaskWaitForDone( &casState.taskId );
//环形缓冲释放
memCircBufFree(&casCtlCmdQ)
//信号量销毁
bosSemDestroy(&casSynCmdSem);
for ( chan = 0; chan < casState.numChannels; chan++ )
//CAS服务关闭
// casState.service[chan].localmem. status &= ~CAS_ENABLED;
// casState.service[chan].localmem. channelinfo. profilep = NULL;
casCmd( chan, CAS_ENABLE, VRG_FALSE, 0 );
//资源清除
casCmd( chan, CAS_EXIT, 0, 0 );
if ( endptConfig.initState & EPEINIT_VRGDISP )
VrgDispatcherProcessDeinit()
//DISP任务退出,机制的实现见上面bosAppReset函数相关注释说明
bosTaskProceedToShutdown( &vrgDispProcessTaskId );
bosTaskWaitForDone( &vrgDispProcessTaskId );
//消息队列释放
memCircBufFree(&vrgEptCmdQ)
memCircBufFree(&vrgEventQ)
//信号量释放
bosSemDestroy( &vrgDispSem );
//释放这前创建的所有ENDPT相关信号量
vrgDestroyEndptSemaphores();
//DSP低级HAPI模块的释放
if ( endptConfig.initState & EPEINIT_LHAPI )
lhapiDeinit()
//心跳模块的释放
if ( endptConfig.initState & EPEINIT_HEARTBEAT )
hbDeInit();
memCircBufDeinit() //环形缓冲驱动的释放
if ( initStatus & BOARDHAL_INIT_COMPLETED )
boardHalDeinit()
boardCfgModules =
BROADCFG6816_MODULE_TPD|BROADCFG6816_MODULE_HVGRING
boardHalDeinitUni()
boardHalCasDeinit();
casDriverStopHistoryLog(); //停止摘挂机历史记录
for ( endpt = 0; endpt < boardHalGetNumEndpoints(); endpt++ )
casDriverDeinit( &gCasDriver[ endpt ] ) //复位CAS驱动对象
boardHalSlicDeinit();
boardHalSlicDeinitApm()
//中间个别流程跳过,当前6816使用9530型号SLIC
boardHalSlicDeinit9530();
for ( endpt = 0; endpt < BOARD_HAL_6816_NUM_ENDPTS; endpt++ )
// 关闭SLIC,里面函数最终设置SLIC电压,及SLIC状态
//寄存器
pDev = &(gSlicDriver[endpt]);
slic6816L9530Deinit( pDev );
//这里都是针对不同SLIC操作,因为6816的9530 SLIC在上面已经处理
//完,这里是找不到9530的操作的。这段函数没有粘出来。
//调用GPIO复位,该函数涉及到SLIC是否需要复位,及寄电器设置,当
//前6816这两项都不需要处理,这里此函数没太大用。
resetGpios()
//信号量释放
spiSiDeinit();
spiZarInit();
//FXO芯片去除初始化
boardHalDaaDeinit();
voiceParams = boardHalProvGetVoiceParms(); //获取语音板卡参数
for ( deviceId = 0; voiceParams->voiceDevice[deviceId].voiceDeviceType !=
BP_VD_NONE; deviceId++ ) //遍历所有芯片
//查找FXO类型芯片,这里假设ZARLINK 88010
switch ( voiceParams->voiceDevice[deviceId].voiceDeviceType )
case BP_VD_ZARLINK_88010:
daaDriverLe88010index--; //索引递减
//获取当前FXO口驱动对象
pDeviceDriver = &gDaaDriverLe88010[daaDriverLe88010index];
//FXO芯片去除初始化
daaLe88010Deinit( pDeviceDriver );
CloseDaa( pDev ); //空函数
if( mspiInUse )
boardHalMspiDeinit(); //空函数
mspiInUse = 0;
debugCmtInterfaceDeinit(); //DEBUG模块关闭
boardHalDspTaskDeinit(); //DSP定时器任务关闭
boardHalIpcDeinit(0); //关闭IPC主机通信任务
boardHalDspDeinit(); //关闭DSP线程处理任务
dlbStubDestroy( &gHalDlbDrv ); //空函数
exceptionHdlrCmtDeinit(); //关闭异常处理模块
xdrvItpcDeinit( &gHalItpcDrv ); //关闭IPC通讯中断
bosMutexDestroy( &gHalItpcBosMutex );
xdrvSpinLockDestroy( gHalSpinLock );
pcmDeinit(); //关闭PCM模块
boardHalApmDeinit(); //关闭APM模块
isEndptDeinitialized = TRUE;
endptOpened = 0;
initThreadPid = 0;
//BCM OS抽象层中止,和之前ENDPT初始化时类似,只是把一些信号量等做销毁动作
bosSleep(1000);
bosTerm();
//释放之前为PROVISION线路分配的内存空间
endptProvDeinit();
for ( line = 0; line < VRG_ENDPT_CFG_NUM_ENDPT; line++ )
PROV_ENTRY* pTable = provTable;
while ( pTable->provItemId != EPPROV_LastItem )
if ( pTable->provItemValue[line] != NULL )
free( pTable->provItemValue[line] );
pTable->provItemValue[line] = NULL;
pTable++;
totalAlocatedMemory = 0;
//标记板卡参数未完成
boardHalProvDeinit();
voiceParamsObtained = VRG_FALSE;
//注销字符设备
devId = MKDEV(ENDPOINTDRV_MAJOR, 0);
cdev_del(&endpoint_cdev);
unregister_chrdev_region(devId, 1);
ENDPT_410_endpoint_cleanup
最新推荐文章于 2024-06-07 15:48:32 发布