Ejemplo n.º 1
0
/*********************************************************************************************************
** 函数名称: API_CacheDmaMalloc
** 功能描述: 开辟一块非缓冲的内存
** 输 入  : 
**           stBytes                       长度
** 输 出  : 开辟的空间首地址
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API  
PVOID    API_CacheDmaMalloc (size_t   stBytes)
{
    return  ((_G_cacheopLib.CACHEOP_pfuncDmaMalloc == LW_NULL) ?
             (__KHEAP_ALLOC(stBytes)) : 
             (_G_cacheopLib.CACHEOP_pfuncDmaMalloc(stBytes)));
}
Ejemplo n.º 2
0
/*********************************************************************************************************
** 函数名称: _JobQueueCreate
** 功能描述: 创建一个工作队列
** 输 入  : uiQueueSize       队列大小
**           bNonBlock         执行函数是否为非阻塞方式
** 输 出  : 工作队列控制块
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
PLW_JOB_QUEUE  _jobQueueCreate (UINT uiQueueSize, BOOL bNonBlock)
{
    PLW_JOB_QUEUE pjobq;
    
    pjobq = (PLW_JOB_QUEUE)__KHEAP_ALLOC((size_t)(sizeof(LW_JOB_QUEUE) + 
                                         (uiQueueSize * sizeof(LW_JOB_MSG))));
    if (pjobq == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");
        _ErrorHandle(ERROR_KERNEL_LOW_MEMORY);
        return  (LW_NULL);
    }
    
    pjobq->JOBQ_pjobmsgQueue = (PLW_JOB_MSG)(pjobq + 1);
    pjobq->JOBQ_uiIn         = 0;
    pjobq->JOBQ_uiOut        = 0;
    pjobq->JOBQ_uiCnt        = 0;
    pjobq->JOBQ_uiSize       = uiQueueSize;
    pjobq->JOBQ_stLost       = 0;
    
    if (bNonBlock == LW_FALSE) {
        pjobq->JOBQ_ulSync = API_SemaphoreBCreate("job_sync", LW_FALSE, LW_OPTION_OBJECT_GLOBAL, LW_NULL);
        if (pjobq->JOBQ_ulSync == LW_OBJECT_HANDLE_INVALID) {
            __KHEAP_FREE(pjobq);
            return  (LW_NULL);
        }
    }
    
    LW_SPIN_INIT(&pjobq->JOBQ_slLock);
    
    return  (pjobq);
}
Ejemplo n.º 3
0
/*********************************************************************************************************
** 函数名称: vprocStackAlloc
** 功能描述: 分配 stack
** 输 入  : ptcbNew       新建任务
**           ulOption      任务创建选项
**           stSize        堆栈大小
** 输 出  : 堆栈
** 全局变量: 
** 调用模块: 
*********************************************************************************************************/
PVOID  vprocStackAlloc (PLW_CLASS_TCB  ptcbNew, ULONG  ulOption, size_t  stSize)
{
    PVOID           pvRet;

#if (LW_CFG_VMM_EN > 0) && !defined(LW_CFG_CPU_ARCH_PPC)
    PLW_CLASS_TCB   ptcbCur;
    LW_LD_VPROC    *pvproc;
    
    LW_TCB_GET_CUR_SAFE(ptcbCur);
    
    if (ptcbNew->TCB_iStkLocation == LW_TCB_STK_NONE) {                 /*  还没有确定堆栈的位置        */
        pvproc = __LW_VP_GET_TCB_PROC(ptcbCur);
        if ((pvproc && !(ulOption & LW_OPTION_OBJECT_GLOBAL)) ||
            (ulOption & LW_OPTION_THREAD_STK_MAIN)) {
            ptcbNew->TCB_iStkLocation = LW_TCB_STK_VMM;                 /*  使用 VMM 堆栈               */

        } else {
            ptcbNew->TCB_iStkLocation = LW_TCB_STK_HEAP;                /*  使用系统堆栈                */
        }
    }

    if (ptcbNew->TCB_iStkLocation == LW_TCB_STK_VMM) {
        pvRet = API_VmmMalloc(stSize);

    } else
#endif                                                                  /*  LW_CFG_VMM_EN > 0           */
    {
        ptcbNew->TCB_iStkLocation = LW_TCB_STK_HEAP;
        pvRet = __KHEAP_ALLOC(stSize);
    }
    
    return  (pvRet);
}
Ejemplo n.º 4
0
/*********************************************************************************************************
** 函数名称: _StackAllocate
** 功能描述: 分配栈内存
** 输 入  : ptcb      任务
**           ulOption  线程创建选项
**           stSize    需要的栈大小
** 输 出  : 栈内存
** 全局变量:
** 调用模块:
*********************************************************************************************************/
PLW_STACK  _StackAllocate (PLW_CLASS_TCB  ptcb, ULONG  ulOption, size_t  stSize)
{
#if LW_CFG_MODULELOADER_EN > 0
    return  ((PLW_STACK)vprocStackAlloc(ptcb, ulOption, stSize));
#else
    return  ((PLW_STACK)__KHEAP_ALLOC(stSize));
#endif                                                                  /*  LW_CFG_MODULELOADER_EN > 0  */
}
Ejemplo n.º 5
0
/*********************************************************************************************************
** 函数名称: __areaSpaceInit
** 功能描述: 初始化地址空间管理块
** 输 入  : pvmarea       地址空间管理块
**           ulAddr        起始地址
**           stSize        大小
** 输 出  : ERROR CODE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static ULONG  __areaSpaceInit (PLW_VMM_AREA  pvmarea, addr_t  ulAddr, size_t  stSize)
{
    INT    i;
    REGISTER ULONG  ulHashSize;

    for (i = 0; ; i++) {
        if (_G_ulVmmAreaHashSizeTbl[i][0] == 0) {
            ulHashSize = _G_ulVmmAreaHashSizeTbl[i][1];                 /*  最大表大小                  */
            break;

        } else {
            if (stSize >= _G_ulVmmAreaHashSizeTbl[i][0]) {
                continue;

            } else {
                ulHashSize = _G_ulVmmAreaHashSizeTbl[i][1];             /*  确定                        */
                break;
            }
        }
    }

    pvmarea->AREA_ulAreaAddr = ulAddr;
    pvmarea->AREA_stAreaSize = stSize;
    pvmarea->AREA_ulHashSize = ulHashSize;

    pvmarea->AREA_ptrbrHash =
        (PLW_TREE_RB_ROOT)__KHEAP_ALLOC(sizeof(PLW_TREE_RB_ROOT) * (size_t)ulHashSize);
    if (pvmarea->AREA_ptrbrHash == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");
        _ErrorHandle(ERROR_KERNEL_LOW_MEMORY);                          /*  缺少内核内存                */
        return  (ERROR_KERNEL_LOW_MEMORY);
    }
    lib_bzero(pvmarea->AREA_ptrbrHash,
              (size_t)(sizeof(PLW_TREE_RB_ROOT) * ulHashSize));         /*  清空 hash 表                */

    return  (ERROR_NONE);
}
Ejemplo n.º 6
0
/*********************************************************************************************************
** 函数名称: API_InterVectorConnectEx
** 功能描述: 设置系统指定向量中断服务
** 输 入  : ulVector                      中断向量号
**           pfuncIsr                      服务函数
**           pfuncClear                    附加中断清除函数(可为 NULL)
**           pvArg                         服务函数参数
**           pcName                        中断服务名称
** 输 出  : ERROR CODE
** 全局变量: 
** 调用模块: 
                                           API 函数
*********************************************************************************************************/
LW_API
ULONG  API_InterVectorConnectEx (ULONG              ulVector,
                                 PINT_SVR_ROUTINE   pfuncIsr,
                                 VOIDFUNCPTR        pfuncClear,
                                 PVOID              pvArg,
                                 CPCHAR             pcName)
{
    INTREG              iregInterLevel;
    BOOL                bNeedFree;
    
    PLW_LIST_LINE       plineTemp;
    PLW_CLASS_INTACT    piactionOld;
    PLW_CLASS_INTACT    piaction;
    PLW_CLASS_INTDESC   pidesc;
    
    if (LW_CPU_GET_CUR_NESTING()) {                                     /*  不能在中断中调用            */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "called from ISR.\r\n");
        _ErrorHandle(ERROR_KERNEL_IN_ISR);
        return  (ERROR_KERNEL_IN_ISR);
    }
    
    INTER_SHOWLOCK_CREATE();

    if (_Object_Name_Invalid(pcName)) {                                 /*  检查名字有效性              */
        _DebugHandle(__ERRORMESSAGE_LEVEL, "name too long.\r\n");
        _ErrorHandle(ERROR_KERNEL_PNAME_TOO_LONG);
        return  (ERROR_KERNEL_PNAME_TOO_LONG);
    }
    
    if (_Inter_Vector_Invalid(ulVector)) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    if (pfuncIsr == LW_NULL) {
        _ErrorHandle(ERROR_KERNEL_VECTOR_NULL);
        return  (ERROR_KERNEL_VECTOR_NULL);
    }
    
    piaction = (PLW_CLASS_INTACT)__KHEAP_ALLOC(sizeof(LW_CLASS_INTACT));
    if (piaction == LW_NULL) {
        _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");
        _ErrorHandle(ERROR_KERNEL_LOW_MEMORY);
        return  (ERROR_KERNEL_LOW_MEMORY);
    }
    lib_bzero(piaction, sizeof(LW_CLASS_INTACT));
    
    piaction->IACT_pfuncIsr   = pfuncIsr;
    piaction->IACT_pfuncClear = pfuncClear;
    piaction->IACT_pvArg      = pvArg;
    if (pcName) {
        lib_strcpy(piaction->IACT_cInterName, pcName);
    } else {
        piaction->IACT_cInterName[0] = PX_EOS;
    }
    
    pidesc = LW_IVEC_GET_IDESC(ulVector);
    
    LW_SPIN_LOCK_QUICK(&pidesc->IDESC_slLock, &iregInterLevel);         /*  关闭中断同时锁住 spinlock   */

    if (LW_IVEC_GET_FLAG(ulVector) & LW_IRQ_FLAG_QUEUE) {               /*  队列服务类型向量            */
        for (plineTemp  = pidesc->IDESC_plineAction;
             plineTemp != LW_NULL;
             plineTemp  = _list_line_get_next(plineTemp)) {
             
            piactionOld = _LIST_ENTRY(plineTemp, LW_CLASS_INTACT, IACT_plineManage);
            if ((piactionOld->IACT_pfuncIsr == pfuncIsr) &&
                (piactionOld->IACT_pvArg    == pvArg)) {                /*  中断处理函数是否被重复安装  */
                break;
            }
        }
        
        if (plineTemp) {                                                /*  此中断被重复安装            */
            bNeedFree = LW_TRUE;
        
        } else {
            _List_Line_Add_Ahead(&piaction->IACT_plineManage,
                                 &pidesc->IDESC_plineAction);
            bNeedFree = LW_FALSE;
        }
    } else {                                                            /*  非队列服务式中断向量        */
        if (pidesc->IDESC_plineAction) {
            piactionOld = _LIST_ENTRY(pidesc->IDESC_plineAction, 
                                      LW_CLASS_INTACT, 
                                      IACT_plineManage);
            piactionOld->IACT_pfuncIsr   = piaction->IACT_pfuncIsr;
            piactionOld->IACT_pfuncClear = piaction->IACT_pfuncClear;
            piactionOld->IACT_pvArg      = piaction->IACT_pvArg;
            lib_strcpy(piactionOld->IACT_cInterName, piaction->IACT_cInterName);
            bNeedFree = LW_TRUE;
        
        } else {
            _List_Line_Add_Ahead(&piaction->IACT_plineManage,
                                 &pidesc->IDESC_plineAction);
            bNeedFree = LW_FALSE;
        }
    }
    
    LW_SPIN_UNLOCK_QUICK(&pidesc->IDESC_slLock, iregInterLevel);        /*  打开中断, 同时打开 spinlock */
    
    if (bNeedFree) {
        __KHEAP_FREE(piaction);
    }
    
    _DebugFormat(__LOGMESSAGE_LEVEL, "IRQ %d : %s connect : 0x%p\r\n",
                 (INT)ulVector, (pcName ? pcName : ""), (PVOID)pfuncIsr);

    return  (ERROR_NONE);
}