HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) { // a thread handle would actually contain an event // the event would mark if the thread is running or not. it will be used in the Wait functions. HANDLE h = CreateEvent(NULL, TRUE, FALSE, NULL); h->ChangeType(CXHandle::HND_THREAD); #ifdef __APPLE__ h->m_machThreadPort = MACH_PORT_NULL; #endif pthread_attr_t attr; pthread_attr_init(&attr); if (dwStackSize > PTHREAD_STACK_MIN) pthread_attr_setstacksize(&attr, dwStackSize); if (pthread_create(&(h->m_hThread), &attr, (void*(*)(void*))lpStartAddress, lpParameter) == 0) h->m_threadValid = true; else { CloseHandle(h); h = NULL; } pthread_attr_destroy(&attr); if (h && lpThreadId) // WARNING: This can truncate thread IDs on x86_64. *lpThreadId = (DWORD)h->m_hThread; return h; }
HANDLE WINAPI CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) { // a thread handle would actually contain an event // the event would mark if the thread is running or not. it will be used in the Wait functions. // DO NOT use SDL_WaitThread for waiting. it will delete the thread object. HANDLE h = CreateEvent(NULL, TRUE, FALSE, NULL); h->ChangeType(CXHandle::HND_THREAD); InternalThreadParam *pParam = new InternalThreadParam; pParam->threadFunc = lpStartAddress; pParam->data = lpParameter; pParam->handle = h; h->m_nRefCount++; h->m_hThread = SDL_CreateThread(InternalThreadFunc, (void*)pParam); if (lpThreadId) *lpThreadId = SDL_GetThreadID(h->m_hThread); return h; }
void HandleMgr<DATA, HANDLE>::Release(HANDLE handle) { unsigned int index = handle.GetIndex(); if(magicNumbers[index] == handle.GetMagic() && index < data.size()) { magicNumbers[index] = 0; freeSlots.push_back(index); } }
/** * Sets the current device configuration */ void usb_svc_setaddress(HANDLE hnd, unsigned int adr) { /* Sends a zero-length packet and then set the device address */ if(hnd->tsk_write(NULL, 0, USB_SETUP_WRITE_TOUT)==RES_OK) { // note: Stall will be performed for the last endpoint used by this handle!! hnd->dst.as_voidptr = (void*)usb_svc_setaddress_hook; hnd->src.as_int = adr; hnd->hcontrol(DCR_HANDLE); } }
static bool ConfigureDacDma(HANDLE dma_hnd, const DMA_DRIVER_MODE* dma_mode) { if(dma_mode->dma_index < INALID_DRV_INDX) { if(dma_hnd->res < RES_CLOSED) { dma_hnd->hcontrol(DCR_CANCEL); dma_hnd->close(); } return dma_hnd->drv_open(dma_mode->dma_index, dma_mode); } return true; }
void CHandleMgr <DATA, HANDLE> :: releaseHandle( HANDLE handle ) { // okresl ktory uchwyt ma byc zwolniony unsigned int index = handle.getIndex(); // sprawdz, czy na pewno jest prawidlowy assert( index < m_UserData_.size() ); assert( m_MagicNumbers_[ index ] == handle.getMagic() ); // jesli wszystko sie powiodlo, ustaw magiczna liczbe na 0, co oznacza, ze uchwyt jest pusty m_MagicNumbers_[ index ] = 0; // dodaj dany uchwyt do listy wolnych uchwytow m_FreeSlots_.push_back( index ); }
//*---------------------------------------------------------------------------- //* Helper functions //*---------------------------------------------------------------------------- HANDLE tsk_open_new_hnd(DRIVER_INDEX index, const void * mode ) { HANDLE hnd; if( (hnd = new CHandle()) ) { if(!hnd->tsk_open(index, mode)) { delete hnd; hnd = NULL; } } return (hnd); }
PathString GetDefaultLogFile() { // 和exe在同一目录下. wchar_t module_name[MAX_PATH]; GetModuleFileNameW(NULL, module_name, MAX_PATH); PathString log_file = module_name; PathString::size_type last_backslash = log_file.rfind('\\', log_file.size()); if(last_backslash != PathString::npos) { log_file.erase(last_backslash+1); } log_file += L"debug.log"; return log_file; }
/** * Sets the current device configuration */ void usb_svc_configendpoint(HANDLE hnd, const USBGenericDescriptor* ds) { // note: Stall will be performed for the last endpoint used by this handle!! hnd->dst.as_voidptr = (void*)usb_svc_configendpoints_hook; hnd->src.as_cvoidptr = ds; hnd->hcontrol(DCR_HANDLE); }
/** * Sets the current device configuration */ void usb_svc_setconfiguration(HANDLE hnd, unsigned int cfg) { // note: Stall will be performed for the last endpoint used by this handle!! hnd->dst.as_voidptr = (void*)usb_svc_setconfiguration_hook; hnd->src.as_int = cfg; hnd->hcontrol(DCR_HANDLE); }
/** * Sets the current device configuration */ void usb_svc_unhalt(HANDLE hnd, unsigned int eptnum) { // note: Stall will be performed for the last endpoint used by this handle!! hnd->dst.as_voidptr = (void*)usb_svc_unhalt_hook; hnd->src.as_int = eptnum; hnd->hcontrol(DCR_HANDLE); }
void usb_cdc_acm_interface::RequestHandler(const void* drv, const USBGenericRequest *pRequest, HANDLE hnd) { /* Check request code */ switch (pRequest->bRequest) { case CDCRequest_SET_LINE_CODING: TRACE1_USB(" sLineCoding"); if (hnd->tsk_read(&lineCoding, sizeof(lineCoding), USB_SETUP_READ_TOUT)==RES_OK) { //read OK TRACE_USB(" rate=%d", lineCoding.dwDTERate); set_line_coding(drv); usb_svc_send_control_status(hnd); } break; case CDCRequest_GET_LINE_CODING: TRACE1_USB(" gLineCoding"); hnd->tsk_write(&lineCoding, sizeof(lineCoding), USB_SETUP_WRITE_TOUT); break; case CDCRequest_SET_CONTROL_LINE_STATE: { TRACE_USB("sControlLineState(%02x) ", pRequest->wValue); bControlLineState = (uint8_t)pRequest->wValue; set_control_line_state(drv); usb_svc_send_control_status(hnd); break; } default: TRACE_USB(" Unknown cdc acm request(%d)", pRequest->bRequest); usb_svc_stall(hnd); break; } }
QString ProcessHandle::command() const { #ifdef Q_OS_WIN HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, id()); if(!process) { throwError("OpenProcessError", tr("Unable to open the process")); return QString(); } TCHAR buffer[256]; if(!GetModuleFileNameEx(process, NULL, buffer, 256)) { throwError("GetModuleFilenameError", tr("Unable to retrieve the executable filename")); return QString(); } CloseHandle(process); return QString::fromWCharArray(buffer); #else QProcess process; process.start(QString("ps h -p %1 -ocommand").arg(id()), QIODevice::ReadOnly); if(!process.waitForStarted(2000) || !process.waitForReadyRead(2000) || !process.waitForFinished(2000) || process.exitCode() != 0) { throwError("GetProcessError", tr("Failed to get the process command")); return QString(); } return process.readAll().trimmed(); #endif }
//*---------------------------------------------------------------------------- //* DCR function //*---------------------------------------------------------------------------- void CAN_DCR(CAN_INFO drv_info, unsigned int reason, HANDLE param) { CAN_DRIVER_DATA* drv_data; drv_data = drv_info->drv_data; switch(reason) { case DCR_RESET: //Initialize the driver here Task* task; task = usr_task_create_dynamic("CANT", (TASK_FUNCTION) can_thread, 90, CAN_TASK_STACK_SIZE); if (task) { svc_task_schedule(task); task->sp->r0.as_cvoidptr = drv_info; } break; case DCR_OPEN: param->res = RES_OK; break; case DCR_CANCEL: if(param->mode.as_int) { param->svc_list_cancel(drv_data->waiting); } else { param->svc_list_cancel(drv_data->helper); } break; } }
BOOL FindNextFile(HANDLE hHandle, LPWIN32_FIND_DATA lpFindData) { if (lpFindData == NULL || hHandle == NULL || hHandle->GetType() != CXHandle::HND_FIND_FILE) return FALSE; if ((unsigned int) hHandle->m_nFindFileIterator >= hHandle->m_FindFileResults.size()) return FALSE; CStdString strFileName = hHandle->m_FindFileResults[hHandle->m_nFindFileIterator++]; CStdString strFileNameTest = hHandle->m_FindFileDir + strFileName; if (IsAliasShortcut(strFileNameTest)) TranslateAliasShortcut(strFileNameTest); struct stat64 fileStat; memset(&fileStat, 0, sizeof(fileStat)); if (stat64(strFileNameTest, &fileStat) == -1) return FALSE; bool bIsDir = false; if (S_ISDIR(fileStat.st_mode)) { bIsDir = true; } memset(lpFindData,0,sizeof(WIN32_FIND_DATA)); lpFindData->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; strcpy(lpFindData->cFileName, strFileName.c_str()); if (bIsDir) lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; if (strFileName[0] == '.') lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN; if (access(strFileName, R_OK) == 0 && access(strFileName, W_OK) != 0) lpFindData->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; TimeTToFileTime(fileStat.st_ctime, &lpFindData->ftCreationTime); TimeTToFileTime(fileStat.st_atime, &lpFindData->ftLastAccessTime); TimeTToFileTime(fileStat.st_mtime, &lpFindData->ftLastWriteTime); lpFindData->nFileSizeHigh = (DWORD)(fileStat.st_size >> 32); lpFindData->nFileSizeLow = (DWORD)fileStat.st_size; return TRUE; }
/** DACC Driver DCR routine * * @param drv_info * @param reason * @param param */ void DACC_DCR(DACC_INFO drv_info, unsigned int reason, HANDLE param) { DACC_DRIVER_DATA drv_data = drv_info->drv_data; Dacc* pDacc = drv_info->hw_base; switch(reason) { case DCR_RESET: DACC_off(drv_info); break; case DCR_OPEN: { DRV_DACC_MODE pMode = (DRV_DACC_MODE)(param->mode.as_voidptr); if(drv_data->cnt) { if(pMode->DACC_MR != pDacc->DACC_MR) return; } else { DACC_on(drv_info, pMode); } pDacc->DACC_CHER = pMode->DACC_CHER; drv_data->cnt++; param->res = RES_OK; break; } case DCR_CLOSE: if(!--drv_data->cnt) DACC_off(drv_info); break; case DCR_CANCEL: if (drv_data->pending == param) { pDacc->DACC_PTCR = DACC_PTCR_TXTDIS; drv_data->pending = param->next; if(drv_data->pending) START_TX_HND(pDacc, drv_data->pending); svc_HND_SET_STATUS(param, RES_SIG_IDLE); } else param->svc_list_cancel(drv_data->pending); break; } }
DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ) { if (hHandle == NULL || hHandle == (HANDLE)-1) return WAIT_FAILED; DWORD dwRet = WAIT_FAILED; switch (hHandle->GetType()) { case CXHandle::HND_EVENT: case CXHandle::HND_THREAD: SDL_mutexP(hHandle->m_hMutex); // Perform the wait. dwRet = WaitForEvent(hHandle, dwMilliseconds); SDL_mutexV(hHandle->m_hMutex); break; case CXHandle::HND_MUTEX: SDL_mutexP(hHandle->m_hMutex); if (hHandle->OwningThread == pthread_self() && hHandle->RecursionCount > 0) { hHandle->RecursionCount++; dwRet = WAIT_OBJECT_0; SDL_mutexV(hHandle->m_hMutex); break; } // Perform the wait. dwRet = WaitForEvent(hHandle, dwMilliseconds); if (dwRet == WAIT_OBJECT_0) { hHandle->OwningThread = pthread_self(); hHandle->RecursionCount = 1; } SDL_mutexV(hHandle->m_hMutex); break; default: XXLog(ERROR, "cant wait for this type of object"); } return dwRet; }
bool InitializeRecursiveMutex(HANDLE hMutex, BOOL bInitialOwner) { if (!hMutex) return false; // we use semaphores instead of the mutex because in SDL we CANT wait for a mutex // to lock with timeout. hMutex->m_pSem = new CSemaphore(bInitialOwner?0:1); hMutex->m_hMutex = SDL_CreateMutex(); hMutex->ChangeType(CXHandle::HND_MUTEX); if (bInitialOwner) { hMutex->OwningThread = pthread_self(); hMutex->RecursionCount = 1; } return true; }
//*---------------------------------------------------------------------------- //* DCR function //*---------------------------------------------------------------------------- void KEY2_DCR(KEY2_DRIVER_INFO* drv_info, unsigned int reason, HANDLE param) { KEY2_DRIVER_DATA* drv_data; drv_data = drv_info->drv_data; switch(reason) { case DCR_RESET: drv_data->key_in = 0; drv_data->key_out = 0; usr_task_init_static(&keyboard_task_desc, true); keyboard_task.sp->r0.as_cvoidptr = drv_info; break; case DCR_OPEN: param->res = RES_OK; break; case DCR_CANCEL: param->svc_list_cancel(drv_data->waiting); break; case DCR_PARAMS: //keycode sent from thread { HANDLE hnd = drv_data->waiting; if( hnd ) { // send the code to the waiting *hnd->dst.as_byteptr++ = (unsigned int)param; drv_data->waiting = hnd->next; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { // store the code in the key_buf drv_data->key_buf[drv_data->key_in] = (unsigned int)param; drv_data->key_in = (drv_data->key_in+1) & DRV_KEYBUF_SIZE; } } break; } }
/** DACC Driver DSR routine * * @param drv_info * @param hnd */ void DACC_DSR(DACC_INFO drv_info, HANDLE hnd) { DACC_DRIVER_DATA drv_data = drv_info->drv_data; if(hnd->len) { if(drv_data->pending) { hnd->list_add(drv_data->pending); } else { hnd->next = NULL; drv_data->pending = hnd; START_TX_HND(drv_info->hw_base, hnd); } }else svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
//*---------------------------------------------------------------------------- //* DSR function //*---------------------------------------------------------------------------- void CAN_DSR(CAN_INFO drv_info, HANDLE hnd) { CAN_DRIVER_DATA* drv_data = drv_info->drv_data; HANDLE tmp; if(hnd->mode.as_int) { // this is a CAN handle... hnd->next = NULL; if( (tmp=drv_data->helper) ) { //the helper task is waiting for object... hnd->res = RES_BUSY; drv_data->helper = NULL; tmp->dst.as_voidptr = hnd; svc_HND_SET_STATUS(tmp, RES_SIG_OK); } else { //queue the client handle while the helper task is busy hnd->list_add(drv_data->waiting); } } else { // this must be the helper if( (tmp=drv_data->waiting) ) { drv_data->waiting = tmp->next; hnd->dst.as_voidptr = tmp; svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else { hnd->res = RES_BUSY; drv_data->helper = hnd; } } }
bool StLangMap::open(const StString& theLngFilePath) { myLngFile = theLngFilePath; #ifdef _WIN32 // it is possible to use std::ifstream, but only for ANSI filenames HANDLE inFile = CreateFileW(myLngFile.toUtfWide().toCString(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(inFile == INVALID_HANDLE_VALUE) { ST_DEBUG_LOG("StLangMap, Failed to open language file \"" + myLngFile + '\"'); return false; } #else std::ifstream inFile; inFile.open(myLngFile.toCString()); if(inFile.fail()) { ST_DEBUG_LOG("StLangMap, Failed to open language file \"" + myLngFile + '\"'); return false; } #endif char bufferOrig[READ_BUFFER_SIZE]; bufferOrig[0] = '\0'; char* bufferLineOrig = new char[1]; bufferLineOrig[0] = '\0'; size_t aLineSize = 0; StString bufferLineUTF; bool isCont = false; size_t oldLen = 0; #ifdef _WIN32 DWORD aBytesRead = 0; while(ReadFile(inFile, bufferOrig, READ_BUFFER_SIZE, &aBytesRead, NULL)) { if(aBytesRead < 1) { break; } #else while(!inFile.eof()) { inFile.read(bufferOrig, READ_BUFFER_SIZE); const size_t aBytesRead = inFile.gcount(); if(aBytesRead < 1) { break; } #endif size_t lineStart = 0; for(size_t c = 0; c < (size_t )aBytesRead; ++c) { if(bufferOrig[c] == '\n') { if(isCont) { char* aCopy = new char[oldLen + c - lineStart + 1]; stMemCpy(&aCopy[0], bufferLineOrig, oldLen); stMemCpy(&aCopy[oldLen], &bufferOrig[lineStart], (c - lineStart)); aLineSize = oldLen + c - lineStart; delete[] bufferLineOrig; bufferLineOrig = aCopy; } else { delete[] bufferLineOrig; bufferLineOrig = new char[c - lineStart + 1]; stMemCpy(bufferLineOrig, &bufferOrig[lineStart], (c - lineStart)); aLineSize = c - lineStart; } // remove CR symbol if needed if(aLineSize > 0 && bufferLineOrig[aLineSize - 1] == stUtf8_t(13)) { --aLineSize; } bufferLineOrig[aLineSize] = '\0'; bufferLineUTF = StString(bufferLineOrig); parseLine(bufferLineUTF); lineStart = c + 1; oldLen = 0; isCont = false; } else if(c == (READ_BUFFER_SIZE - 1)) { char* aCopy = new char[oldLen + READ_BUFFER_SIZE - lineStart]; if(oldLen > 0) { stMemCpy(aCopy, bufferLineOrig, oldLen); } stMemCpy(&aCopy[oldLen], &bufferOrig[lineStart], (READ_BUFFER_SIZE - lineStart)); delete[] bufferLineOrig; bufferLineOrig = aCopy; oldLen += (READ_BUFFER_SIZE - lineStart); isCont = true; } if(!isCont) { delete[] bufferLineOrig; bufferLineOrig = new char[1]; bufferLineOrig[0] = '\0'; } } } delete[] bufferLineOrig; #ifdef _WIN32 CloseHandle(inFile); #else inFile.close(); #endif ST_DEBUG_LOG("StLangMap, Loaded language file \"" + myLngFile + '\"'); return true; } StString& StLangMap::changeValue(const size_t theId) { return myMap[theId]; } const StString& StLangMap::getValue(const size_t theId) const { const std::map<size_t, StString>::const_iterator anIter = myMap.find(theId); return (anIter != myMap.end()) ? anIter->second : myEmptyStr; } StString& StLangMap::changeValueId(const size_t theId, const char* theDefaultValue) { StString& aValue = myMap[theId]; if(aValue.isEmpty()) { if(myToShowId) { aValue = StString('[') + theId + ']' + theDefaultValue; } else { aValue = theDefaultValue; } } return aValue; }
/** USART DCR * * @param drv_info * @param reason * @param param */ void USART_DCR(USART_INFO drv_info, unsigned int reason, HANDLE param) { UART_DRIVER_DATA drv_data = drv_info->drv_data; unsigned int temp; switch(reason) { case DCR_RESET: drv_data->buf_size = drv_info->buf_size; USART_OFF(drv_info); break; case DCR_OPEN: { DRV_UART_MODE pMode = (DRV_UART_MODE)(param->mode.as_voidptr); if(pMode) { if(drv_data->cnt) { if( (pMode->mode != drv_data->mode) || (pMode->baudrate != drv_data->baudrate)) return; } else { drv_data->mode = pMode->mode; drv_data->baudrate =pMode->baudrate; USART_CFG(drv_info, pMode); START_RX_BUF(drv_info->hw_base, drv_data); } drv_data->cnt++; param->res = RES_OK; } break; } case DCR_CLOSE: if(drv_data->cnt) if(!--drv_data->cnt) USART_OFF(drv_info); break; case DCR_CANCEL: { if (param->cmd & FLAG_READ) { if(param == drv_data->hnd_rcv) { STOP_RX(drv_info->hw_base); temp = drv_info->hw_base->US_RCR; if(param->len > temp) { param->len = temp; param->dst.as_int = drv_info->hw_base->US_RPR; temp = RES_OK; } else temp = RES_SIG_IDLE; drv_data->hnd_rcv = param->next; if( drv_data->hnd_rcv ) START_RX_HND(drv_info->hw_base, drv_data, drv_data->hnd_rcv); else START_RX_BUF(drv_info->hw_base, drv_data); svc_HND_SET_STATUS(param, temp); } else param->svc_list_cancel(drv_data->hnd_rcv); } else { if(param == drv_data->hnd_snd) { STOP_TX(drv_info->hw_base); temp = drv_info->hw_base->US_TCR; if(param->len > temp) { param->len = temp; param->src.as_int = drv_info->hw_base->US_TPR; temp = RES_OK; } else temp = RES_SIG_IDLE; drv_data->hnd_snd = param->next; if( drv_data->hnd_snd ) START_TX_HND(drv_info->hw_base, drv_data->hnd_snd); svc_HND_SET_STATUS(param, temp); } else param->svc_list_cancel(drv_data->hnd_snd); } break; } case DCR_CLOCK: if(drv_data->cnt) drv_info->hw_base->US_BRGR = AT91_GetDiv(drv_data->baudrate); break; } }
/** * USART DSR * @param drv_info * @param hnd */ void USART_DSR(USART_INFO drv_info, HANDLE hnd) { UART_DRIVER_DATA drv_data = drv_info->drv_data; unsigned char *ptr; signed int size; if(hnd->len) { hnd->next = NULL; if (hnd->cmd & FLAG_READ) { if(drv_data->hnd_rcv) { hnd->list_add(drv_data->hnd_rcv); return; } STOP_RX(drv_info->hw_base); //try to read from buffer ptr = (unsigned char*) (drv_info->hw_base->US_RPR); if (ptr != drv_data->rx_ptr) { if (ptr < drv_data->rx_ptr) { size = min(hnd->len, drv_info->buf_size - (drv_data->rx_ptr - drv_data->rx_buf)); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; if(drv_data->rx_ptr == &drv_data->rx_buf[drv_info->buf_size]) drv_data->rx_ptr = drv_data->rx_buf; } if (hnd->len && (ptr > drv_data->rx_ptr)) { size =min(hnd->len, ptr - drv_data->rx_ptr); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; } } if (hnd->len ) { //receive directly drv_data->hnd_rcv = hnd; START_RX_HND(drv_info->hw_base, drv_data, hnd); } else { RESUME_RX(drv_info->hw_base); svc_HND_SET_STATUS(hnd, RES_SIG_OK); } } else { if (hnd->cmd & FLAG_WRITE) { if(drv_data->hnd_snd) { hnd->list_add(drv_data->hnd_snd); } else { drv_data->hnd_snd = hnd; START_TX_HND(drv_info->hw_base, hnd); } } else { svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); } } } else { svc_HND_SET_STATUS(hnd, RES_SIG_IDLE); } }
/** * Causes the given endpoint to acknowledge the next packet it receives * with a STALL handshake */ void usb_svc_stall(HANDLE hnd) { // note: Stall will be performed for the last endpoint used by this handle!! hnd->dst.as_voidptr = (void*)usb_svc_stall_hook; hnd->hcontrol(DCR_HANDLE); }
void EXTI_DCR(EXTI_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd) { EXTI_DRIVER_DATA * drv_data = drv_info->drv_data ; const PIN_DESC* pin; unsigned int lines; switch( reason ) { case DCR_ISR: { lines = (unsigned int)hnd; //lines with edge // loop waiting handles for(hnd = drv_data->waiting; hnd; hnd = hnd->next) { // loop pin description list in the handle for(pin = (PIN_DESC*)hnd->mode.as_voidptr; *pin; pin++) { if(lines & *pin) { if(hnd->mode0 == PIOHND_WAITING) { hnd->mode0 = PIOHND_IDLE; read_handle(hnd); svc_HND_SET_STATUS(hnd, RES_SIG_OK); } else hnd->mode0 = PIOHND_INTPENDING; break; //done with this handle } } } } break; case DCR_OPEN: { //Enable AFIO/SYSCFG... RCCPeripheralEnable(drv_info->info.peripheral_indx); pin = (PIN_DESC *)hnd->mode.as_voidptr; hnd->list_add(drv_data->waiting); hnd->mode0 = PIOHND_IDLE; while(*pin) { unsigned int pin_pattern, pos; PIO_Cfg(*pin); if(PD_MODE_Get(*pin) == PD_MODE_INPUT) { if(PD_INT_Get(*pin)) { pin_pattern = PD_PINS_Get(*pin); while(pin_pattern) { pos = 31 - __CLZ(pin_pattern); lines = 1 << pos; pin_pattern ^= lines; pos = stm_get_drv_indx(pos); // Handles can be open with any EXTI driver, so check // here if the actual driver is installed int adr = (int)DRV_TABLE[pos]; adr &= ~3; const EXTI_DRIVER_INFO* info; info = (const EXTI_DRIVER_INFO*)adr; if(info->info.isr == (DRV_ISR)EXTI_ISR) { drv_enable_isr(&info->info); /* Clear Rising Falling edge configuration */ info->hw_base->EXTI_RTSR &= ~lines; info->hw_base->EXTI_FTSR &= ~lines; exti_set_line_source(31 - __CLZ(lines), PD_PORT_Get(*pin)); /* Select the trigger for the selected external interrupts */ if(*pin & PD_INT_FE) // falling edge info->hw_base->EXTI_FTSR |= lines; if(*pin & PD_INT_RE) // rising edge info->hw_base->EXTI_RTSR |= lines; /* Enable line interrupt */ info->hw_base->EXTI_IMR |= lines; } } } } pin++; } hnd->res = RES_OK; } break; case DCR_CLOSE: { PIO_Cfg_List((PIN_DESC*)hnd->mode.as_voidptr); hnd->list_remove(drv_data->waiting); } break; case DCR_CANCEL: if (hnd->res & FLG_BUSY) { read_handle(hnd); svc_HND_SET_STATUS(hnd, RES_SIG_CANCEL); } break; case DCR_RESET: NVIC_DisableIRQ(drv_info->info.drv_index); RCCPeripheralReset(drv_info->info.peripheral_indx); RCCPeripheralDisable(drv_info->info.peripheral_indx); // turn off break; default: break; } }
namespace base { bool g_enable_dcheck = false; VlogInfo* g_vlog_info = NULL; const char* const log_severity_names[LOG_NUM_SEVERITIES] = { "INFO", "WARNING", "ERROR", "ERROR_REPORT", "FATAL" }; int min_log_level = 0; // logging_destination的缺省值在未调用InitLogging初始化时有效. // 缺省是日志写文件. LoggingDestination logging_destination = LOG_ONLY_TO_FILE; // 对于LOG_ERROR以及以上等级, 会打印到终端. const int kAlwaysPrintErrorLevel = LOG_ERROR; // 通过BaseInitLoggingImpl初始化日志文件名, 否则会在第一次 // 写日志的时候初始化默认值. typedef std::wstring PathString; PathString* log_file_name = NULL; // 日志文件句柄 HANDLE log_file = NULL; // 日志消息前缀显示内容项开关. bool log_process_id = false; bool log_thread_id = false; bool log_timestamp = true; bool log_tickcount = false; // 是否弹出fatal错误消息对话框? bool show_error_dialogs = false; LogAssertHandlerFunction log_assert_handler = NULL; LogReportHandlerFunction log_report_handler = NULL; LogMessageHandlerFunction log_message_handler = NULL; // 辅助函数 int32 CurrentProcessId() { return GetCurrentProcessId(); } int32 CurrentThreadId() { return GetCurrentThreadId(); } uint64 TickCount() { return GetTickCount(); } void CloseFile(HANDLE log) { CloseHandle(log); } void DeleteFilePath(const PathString& log_name) { DeleteFileW(log_name.c_str()); } PathString GetDefaultLogFile() { // 和exe在同一目录下. wchar_t module_name[MAX_PATH]; GetModuleFileNameW(NULL, module_name, MAX_PATH); PathString log_file = module_name; PathString::size_type last_backslash = log_file.rfind('\\', log_file.size()); if(last_backslash != PathString::npos) { log_file.erase(last_backslash+1); } log_file += L"debug.log"; return log_file; } // 日志文件锁封装类. 日志操作前在main线程中调用LoggingLock::Init(), 写日志时 // 在局部栈上实例一个变量, 可以确保出局部作用域时自动解锁. // LoggingLocks不能嵌套. class LoggingLock { public: LoggingLock() { LockLogging(); } ~LoggingLock() { UnlockLogging(); } static void Init(LogLockingState lock_log, const PathChar* new_log_file) { if(initialized) { return; } lock_log_file = lock_log; if(lock_log_file == LOCK_LOG_FILE) { if(!log_mutex) { std::wstring safe_name; if(new_log_file) { safe_name = new_log_file; } else { safe_name = GetDefaultLogFile(); } // \不是合法的mutex名字符, 替换成/ std::replace(safe_name.begin(), safe_name.end(), '\\', '/'); std::wstring t(L"Global\\"); t.append(safe_name); log_mutex = ::CreateMutex(NULL, FALSE, t.c_str()); if(log_mutex == NULL) { #if DEBUG // 保存错误码以便调试 int error = GetLastError(); DebugUtil::BreakDebugger(); #endif // 直接返回 return; } } } else { log_lock = new LockImpl(); } initialized = true; } private: static void LockLogging() { if(lock_log_file == LOCK_LOG_FILE) { ::WaitForSingleObject(log_mutex, INFINITE); } else { log_lock->Lock(); } } static void UnlockLogging() { if(lock_log_file == LOCK_LOG_FILE) { ReleaseMutex(log_mutex); } else { log_lock->Unlock(); } } // LogLockingState为DONT_LOCK_LOG_FILE时使用该锁解决多线程写日志 // 冲突. 使用LockImpl而不是Lock, 因为Lock中调用了写日志操作. static LockImpl* log_lock; // 当不使用锁的时候, 使用全局mutex保证进程间同步. static HANDLE log_mutex; static bool initialized; static LogLockingState lock_log_file; }; // static bool LoggingLock::initialized = false; // static LockImpl* LoggingLock::log_lock = NULL; // static LogLockingState LoggingLock::lock_log_file = LOCK_LOG_FILE; // static HANDLE LoggingLock::log_mutex = NULL; // InitializeLogFileHandle在日志函数中调用, 初始化日志文件以便写日志. // 初始化失败返回false, log_file==NULL. bool InitializeLogFileHandle() { if(log_file) { return true; } if(!log_file_name) { // 如果没有调用过InitLogging指定日志文件名, 初始化缺省文件名. // 日志文件跟exe在相同目录. log_file_name = new PathString(GetDefaultLogFile()); } if(logging_destination==LOG_ONLY_TO_FILE || logging_destination==LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { log_file = CreateFileW(log_file_name->c_str(), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(log_file==INVALID_HANDLE_VALUE || log_file==NULL) { // 尝试当前目录. log_file = CreateFileW(L".\\debug.log", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(log_file==INVALID_HANDLE_VALUE || log_file==NULL) { log_file = NULL; return false; } } SetFilePointer(log_file, 0, 0, FILE_END); } return true; } void BaseInitLoggingImpl(const PathChar* new_log_file, LoggingDestination logging_dest, LogLockingState lock_log, OldFileDeletionState delete_old) { CommandLine* command_line = CommandLine::ForCurrentProcess(); g_enable_dcheck = command_line->HasSwitch(base::kEnableDCHECK); delete g_vlog_info; g_vlog_info = NULL; // 除非有vlog开关, 否则不必要初始化g_vlog_info if(command_line->HasSwitch(base::kV) || command_line->HasSwitch(base::kVModule)) { g_vlog_info = new VlogInfo(command_line->GetSwitchValueASCII(base::kV), command_line->GetSwitchValueASCII(base::kVModule)); } LoggingLock::Init(lock_log, new_log_file); LoggingLock logging_lock; if(log_file) { // calling InitLogging twice or after some log call has already opened the // default log file will re-initialize to the new options CloseFile(log_file); log_file = NULL; } logging_destination = logging_dest; // ignore file options if logging is disabled or only to system if(logging_destination==LOG_NONE || logging_destination==LOG_ONLY_TO_SYSTEM_DEBUG_LOG) { return; } if(!log_file_name) { log_file_name = new PathString(); } *log_file_name = new_log_file; if(delete_old == DELETE_OLD_LOG_FILE) { DeleteFilePath(*log_file_name); } InitializeLogFileHandle(); } void SetMinLogLevel(int level) { min_log_level = level; } int GetMinLogLevel() { return min_log_level; } int GetVlogLevelHelper(const char* file, size_t N) { DCHECK_GT(N, 0U); return g_vlog_info ? g_vlog_info->GetVlogLevel(base::StringPiece(file, N-1)) : VlogInfo::kDefaultVlogLevel; } void SetLogItems(bool enable_process_id, bool enable_thread_id, bool enable_timestamp, bool enable_tickcount) { log_process_id = enable_process_id; log_thread_id = enable_thread_id; log_timestamp = enable_timestamp; log_tickcount = enable_tickcount; } void SetShowErrorDialogs(bool enable_dialogs) { show_error_dialogs = enable_dialogs; } void SetLogAssertHandler(LogAssertHandlerFunction handler) { log_assert_handler = handler; } void SetLogReportHandler(LogReportHandlerFunction handler) { log_report_handler = handler; } void SetLogMessageHandler(LogMessageHandlerFunction handler) { log_message_handler = handler; } // 在致命(fatal)消息时显示错误消息框给用户, 同时关闭应用程序. void DisplayDebugMessageInDialog(const std::string& str) { if(str.empty()) { return; } if(!show_error_dialogs) { return; } // 对于Windows程序显示MessageBox会导致消息循环, 有可能引起更多的严重错误. // 所以首先尝试通过其他进程来显示错误消息. 在相同目录下查找 // "debug_message.exe"程序, 如果存在我们用它来显示错误消息; 否则使用常规 // 方式弹出MessageBox. wchar_t prog_name[MAX_PATH]; GetModuleFileNameW(NULL, prog_name, MAX_PATH); wchar_t* backslash = wcsrchr(prog_name, '\\'); if(backslash) { backslash[1] = 0; } wcscat_s(prog_name, MAX_PATH, L"debug_message.exe"); std::wstring cmdline = UTF8ToWide(str); if(cmdline.empty()) { return; } STARTUPINFO startup_info; memset(&startup_info, 0, sizeof(startup_info)); startup_info.cb = sizeof(startup_info); PROCESS_INFORMATION process_info; if(CreateProcessW(prog_name, &cmdline[0], NULL, NULL, false, 0, NULL, NULL, &startup_info, &process_info)) { WaitForSingleObject(process_info.hProcess, INFINITE); CloseHandle(process_info.hThread); CloseHandle(process_info.hProcess); } else { // debug process broken, let's just do a message box MessageBoxW(NULL, &cmdline[0], L"Fatal error", MB_OK|MB_ICONHAND|MB_TOPMOST); } } LogMessage::SaveLastError::SaveLastError() : last_error_(GetLastError()) { } LogMessage::SaveLastError::~SaveLastError() { SetLastError(last_error_); } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, int ctr) : severity_(severity) { Init(file, line); } LogMessage::LogMessage(const char* file, int line, const CheckOpString& result) : severity_(LOG_FATAL) { Init(file, line); stream_ << "Check failed: " << (*result.str_); } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, const CheckOpString& result) : severity_(severity) { Init(file, line); stream_ << "Check failed: " << (*result.str_); } LogMessage::LogMessage(const char* file, int line) : severity_(LOG_INFO) { Init(file, line); } LogMessage::LogMessage(const char* file, int line, LogSeverity severity) : severity_(severity) { Init(file, line); } // writes the common header info to the stream void LogMessage::Init(const char* file, int line) { // log only the filename const char* last_slash = strrchr(file, '\\'); if(last_slash) { file = last_slash + 1; } stream_ << '['; if(log_process_id) { stream_ << CurrentProcessId() << ':'; } if(log_thread_id) { stream_ << CurrentThreadId() << ':'; } if(log_timestamp) { time_t t = time(NULL); struct tm local_time = { 0 }; localtime_s(&local_time, &t); struct tm* tm_time = &local_time; stream_ << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon << std::setw(2) << tm_time->tm_mday << '/' << std::setw(2) << tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2) << tm_time->tm_sec << ':'; } if(log_tickcount) { stream_ << TickCount() << ':'; } stream_ << log_severity_names[severity_] << ":" << file << "(" << line << ")] "; message_start_ = stream_.tellp(); } LogMessage::~LogMessage() { if(severity_ < min_log_level) { return; } #ifndef NDEBUG if(severity_ == LOG_FATAL) { // fatal时输出堆栈. StackTrace trace; stream_ << std::endl; trace.OutputToStream(&stream_); } #endif stream_ << std::endl; std::string str_newline(stream_.str()); // 所有消息先交由log_message_handler处理 if(log_message_handler && log_message_handler(severity_, str_newline)) { return; } if(logging_destination==LOG_ONLY_TO_SYSTEM_DEBUG_LOG || logging_destination==LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG) { OutputDebugStringA(str_newline.c_str()); fprintf(stderr, "%s", str_newline.c_str()); fflush(stderr); } else if(severity_ >= kAlwaysPrintErrorLevel) { // 在只输出日志到文件情况下, 对于kAlwaysPrintErrorLevel以及以上等级 // 的消息仍然显示到标准错误输出以便单元测试能更方便的检测和诊断问题. fprintf(stderr, "%s", str_newline.c_str()); fflush(stderr); } // 可能多线程或者多进程同时写操作, 所以必须加锁. // 如果客户端应用没有调用BaseInitLoggingImpl, 锁在此时才会创建, 假如同时有 // 2个线程运行此处, 会导致锁创建冲突, 这也是BaseInitLoggingImpl应该在main // 函数运行开始处调用的原因. LoggingLock::Init(LOCK_LOG_FILE, NULL); // 写日志文件 if(logging_destination!=LOG_NONE && logging_destination!=LOG_ONLY_TO_SYSTEM_DEBUG_LOG) { LoggingLock logging_lock; if(InitializeLogFileHandle()) { SetFilePointer(log_file, 0, 0, SEEK_END); DWORD num_written; WriteFile(log_file, static_cast<const void*>(str_newline.c_str()), static_cast<DWORD>(str_newline.length()), &num_written, NULL); } } if(severity_ == LOG_FATAL) { // fatal error: 显示错误消息或者显示在调试器中中断. if(DebugUtil::BeingDebugged()) { DebugUtil::BreakDebugger(); } else { if(log_assert_handler) { // make a copy of the string for the handler out of paranoia log_assert_handler(std::string(stream_.str())); } else { // 把错误消息发送到消息显示进程弹出. // 在release模式下不显示断言信息给用户, 因为这种信息对于最终用户 // 没什么价值而且显示消息框可能会给程序带来其他问题. #ifndef NDEBUG DisplayDebugMessageInDialog(stream_.str()); #endif // Crash the process to generate a dump. DebugUtil::BreakDebugger(); } } } else if(severity_ == LOG_ERROR_REPORT) { // 用户在release模式下通过参数--enable-dcheck启动程序 if(log_report_handler) { log_report_handler(std::string(stream_.str())); } else { DisplayDebugMessageInDialog(stream_.str()); } } } SystemErrorCode GetLastSystemErrorCode() { return GetLastError(); } Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file, int line, LogSeverity severity, SystemErrorCode err, const char* module) : err_(err), module_(module), log_message_(file, line, severity) {} Win32ErrorLogMessage::Win32ErrorLogMessage(const char* file, int line, LogSeverity severity, SystemErrorCode err) : err_(err), module_(NULL), log_message_(file, line, severity) {} Win32ErrorLogMessage::~Win32ErrorLogMessage() { const int error_message_buffer_size = 256; char msgbuf[error_message_buffer_size]; DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS; HMODULE hmod; if(module_) { hmod = GetModuleHandleA(module_); if(hmod) { flags |= FORMAT_MESSAGE_FROM_HMODULE; } else { // 导致Win32ErrorLogMessage嵌套, 由于module_是NULL不会再次进入这里, // 所以不会死循环. DPLOG(WARNING) << "Couldn't open module " << module_ << " for error message query"; } } else { hmod = NULL; } DWORD len = FormatMessageA(flags, hmod, err_, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msgbuf, sizeof(msgbuf)/sizeof(msgbuf[0]), NULL); if(len) { while((len>0) && isspace(static_cast<unsigned char>(msgbuf[len-1]))) { msgbuf[--len] = 0; } stream() << ": " << msgbuf; } else { stream() << ": Error " << GetLastError() << " while retrieving error " << err_; } } void CloseLogFile() { LoggingLock logging_lock; if(!log_file) { return; } CloseFile(log_file); log_file = NULL; } void RawLog(int level, const char* message) { if(level >= min_log_level) { size_t bytes_written = 0; const size_t message_len = strlen(message); int rv; while(bytes_written < message_len) { rv = write(STDERR_FILENO, message+bytes_written, message_len-bytes_written); if(rv < 0) { // Give up, nothing we can do now. break; } bytes_written += rv; } if(message_len>0 && message[message_len-1]!='\n') { do { rv = write(STDERR_FILENO, "\n", 1); if(rv < 0) { // Give up, nothing we can do now. break; } } while(rv != 1); } } if(level == LOG_FATAL) { DebugUtil::BreakDebugger(); } } } //namespace base
void dsr_SerialDriver(UART_DRIVER_INFO* drv_info, HANDLE hnd) { unsigned char *ptr; signed int size; UART_DRIVER_DATA *drv_data = drv_info->drv_data; UART_Type * Uart = drv_info->hw_base; hnd->next = NULL; if (hnd->cmd & FLAG_READ) { hnd->mode0 = 0; // няма нищо прието в хендъла if(drv_data->hnd_rcv) { hnd->list_add(drv_data->hnd_rcv); return; } STOP_RX(Uart); //try to read from buffer ptr = drv_data->rx_wrptr; if( hnd->len && (ptr!= drv_data->rx_ptr) ) { if(ptr < drv_data->rx_ptr) { size =min(hnd->len, (unsigned int)(&drv_data->rx_buf[RX_BUF_SIZE]) - (unsigned int)drv_data->rx_ptr); memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->mode0 = 1; // в хендъла е писано hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; if(drv_data->rx_ptr == &drv_data->rx_buf[RX_BUF_SIZE]) drv_data->rx_ptr = drv_data->rx_buf; } if( hnd->len && (ptr!= drv_data->rx_ptr) ) { size =min(hnd->len, ptr - drv_data->rx_ptr); hnd->mode0 = 1; // в хендъла е писано memcpy(hnd->dst.as_byteptr, drv_data->rx_ptr, size); hnd->len -= size; hnd->dst.as_int += size; drv_data->rx_ptr += size; } } if (hnd->len == 0) { RESUME_RX(Uart); svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } //receive directly hnd->res = RES_BUSY; drv_data->hnd_rcv = hnd; START_RX_HND(Uart, drv_info, hnd); return; } if (hnd->cmd & FLAG_WRITE) { if(hnd->len) { if(drv_data->hnd_snd) { hnd->list_add(drv_data->hnd_snd); return; } hnd->res = RES_BUSY; drv_data->hnd_snd = hnd; START_TX_HND(Uart, hnd); } else svc_HND_SET_STATUS(hnd, RES_SIG_OK); return; } svc_HND_SET_STATUS(hnd, RES_SIG_ERROR); }
void dcr_SerialDriver(UART_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd) { UART_Type * Uart = drv_info->hw_base; UART_DRIVER_DATA *drv_data = drv_info->drv_data; switch(reason) { case DCR_ISR: TX_CTS(drv_data, Uart, (unsigned int)hnd); return; case DCR_RESET: SysCtlPeripheralReset(drv_info->info.peripheral_indx); SysCtlPeripheralDisable(drv_info->info.peripheral_indx); // ??? turn off return; case DCR_OPEN: { UART_DRIVER_MODE *uart_mode = (UART_DRIVER_MODE *)(hnd->mode.as_voidptr); if(uart_mode) { //unsigned long mode, baudrate; if(drv_data->cnt) { if( uart_mode->mode != drv_data->mode.mode || uart_mode->baudrate != drv_data->mode.baudrate || uart_mode->hw_flow != drv_data->mode.hw_flow ) { return; } } else { // Enable AND Reset the UART peripheral SysCtlPeripheralReset(drv_info->info.peripheral_indx); if(drv_data->mode.hw_flow) { PIO_Cfg_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_ALL_PINS]); ConfigureUart(drv_info, drv_data, uart_mode); #ifdef HW_VER_10 if(drv_info->info.drv_index != UART1_IRQn) TX_CTS(drv_data, Uart, PIO_Read(drv_info->uart_pins[CTS_PIN])); #endif } else { PIO_Cfg_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_RX_TX_PINS]); ConfigureUart(drv_info, drv_data, uart_mode); } START_RX_BUF(Uart, drv_info, drv_data); } drv_data->cnt++; hnd->res = RES_OK; } return; } case DCR_CLOSE: if(drv_data->cnt) drv_data->cnt--; case DCR_CANCEL: { if( !(hnd->res & FLG_BUSY)) return; if (hnd->cmd & FLAG_READ) { if(hnd == drv_data->hnd_rcv) { STOP_RX(Uart); if(hnd->len > drv_data->rx_remaining || hnd->mode0 ) { hnd->len = drv_data->rx_remaining; hnd->res = RES_SIG_OK; } else hnd->res = RES_SIG_IDLE; drv_data->hnd_rcv = hnd->next; svc_HND_SET_STATUS(hnd, hnd->res); if( (hnd=drv_data->hnd_rcv) ) START_RX_HND(Uart, drv_info, hnd); else START_RX_BUF(Uart, drv_info, drv_data); } else { // try cnacel hnd->svc_list_cancel(drv_data->hnd_rcv); } } else { if(hnd == drv_data->hnd_snd) { STOP_TX(Uart); drv_data->hnd_snd = hnd->next; svc_HND_SET_STATUS(hnd, RES_SIG_IDLE); if( (hnd=drv_data->hnd_snd) ) START_TX_HND(Uart, hnd); } else { hnd->svc_list_cancel(drv_data->hnd_snd); } } if(!drv_data->cnt) { NVIC->NVIC_DisableIRQ(drv_info->info.drv_index); Uart->UARTDisable(); STOP_RX(Uart); STOP_TX(Uart); SysCtlPeripheralDisable(drv_info->info.peripheral_indx); SYSCTL->SysCtlPeripheralDeepSleepDisable(drv_info->info.peripheral_indx); SYSCTL->SysCtlPeripheralSleepDisable(drv_info->info.peripheral_indx); if(drv_data->mode.hw_flow) PIO_Free_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_ALL_PINS]); else PIO_Free_List((PIN_DESC *)&drv_info->uart_pins[UART_LIST_RX_TX_PINS]); } return; } case DCR_CLOCK: return; } }