/********************************************************************************************************* ** 函数名称: 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))); }
/********************************************************************************************************* ** 函数名称: _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); }
/********************************************************************************************************* ** 函数名称: 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); }
/********************************************************************************************************* ** 函数名称: _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 */ }
/********************************************************************************************************* ** 函数名称: __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); }
/********************************************************************************************************* ** 函数名称: 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); }