/* * JTAG Core library * Copyright (c) 2008 - 2024 Viveris Technologies * * JTAG Core library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * JTAG Core library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with JTAG Core library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** * @file os_interface.c * @brief Basic/generic OS functions wrapper. * @author Jean-Fran�ois DEL NERO */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "os_interface.h" typedef struct _EVENT_HANDLE{ pthread_cond_t eCondVar; pthread_mutex_t eMutex; int iVar; } EVENT_HANDLE; EVENT_HANDLE * eventtab[256]; pthread_mutex_t criticalsectiontab[256]; #if 0 void * ThreadProc( void *lpParameter) { threadinit *threadinitptr; THREADFUNCTION thread; jtag_core* jtag_ctx; void * hw_context; threadinitptr=(threadinit*)lpParameter; if( threadinitptr ) { thread=threadinitptr->thread; jtag_ctx = threadinitptr->jtag_ctx; hw_context=threadinitptr->hwcontext; thread(jtag_ctx,hw_context); free(threadinitptr); } return 0; } #endif int genos_setevent(unsigned char id) { pthread_mutex_lock(&eventtab[id]->eMutex); pthread_cond_signal(&eventtab[id]->eCondVar); pthread_mutex_unlock(&eventtab[id]->eMutex); return 0; } uintptr_t genos_createevent(unsigned char id) { eventtab[id]=(EVENT_HANDLE*)malloc(sizeof(EVENT_HANDLE)); pthread_mutex_init(&eventtab[id]->eMutex, NULL); pthread_cond_init(&eventtab[id]->eCondVar, NULL); return (uintptr_t)eventtab[id]; } int genos_waitevent(int id,int timeout) { struct timeval now; struct timespec timeoutstr; int retcode; pthread_mutex_lock(&eventtab[id]->eMutex); gettimeofday(&now,0); timeoutstr.tv_sec = now.tv_sec + (timeout/1000); timeoutstr.tv_nsec = (now.tv_usec * 1000) ;//+(timeout*1000000); retcode = 0; retcode = pthread_cond_timedwait(&eventtab[id]->eCondVar, &eventtab[id]->eMutex, &timeoutstr); if (retcode == ETIMEDOUT) { pthread_mutex_unlock(&eventtab[id]->eMutex); return 1; } else { pthread_mutex_unlock(&eventtab[id]->eMutex); return 0; } } uintptr_t genos_createcriticalsection(unsigned char id) { //create mutex attribute variable pthread_mutexattr_t mAttr; pthread_mutexattr_init(&mAttr); #if defined(__APPLE__) // setup recursive mutex for mutex attribute pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE); #else pthread_mutexattr_settype(&mAttr, PTHREAD_MUTEX_RECURSIVE_NP); #endif // Use the mutex attribute to create the mutex pthread_mutex_init(&criticalsectiontab[id], &mAttr); // Mutex attribute can be destroy after initializing the mutex variable pthread_mutexattr_destroy(&mAttr); return (uintptr_t)&criticalsectiontab[id]; } void genos_entercriticalsection(unsigned char id) { #ifdef WIN32 EnterCriticalSection( &criticalsectiontab[id] ); #else pthread_mutex_lock( &criticalsectiontab[id] ); #endif } void genos_leavecriticalsection(unsigned char id) { #ifdef WIN32 LeaveCriticalSection( &criticalsectiontab[id] ); #else pthread_mutex_unlock( &criticalsectiontab[id] ); #endif } void genos_destroycriticalsection(unsigned char id) { #ifdef WIN32 DeleteCriticalSection(&criticalsectiontab[id]); #else pthread_mutex_destroy (&criticalsectiontab[id]); #endif } void genos_msleep (unsigned int ms) { int microsecs; struct timeval tv; microsecs = ms * 1000; tv.tv_sec = microsecs / 1000000; tv.tv_usec = microsecs % 1000000; select (0, NULL, NULL, NULL, &tv); } void genos_pause(int ms) { genos_msleep(ms); } #if 0 int genos_createthread(void* hwcontext,THREADFUNCTION thread,int priority) { unsigned long sit; int ret; pthread_t threadid; pthread_attr_t threadattrib; threadinit *threadinitptr; struct sched_param param; JTAGCORE_PRINT_FUNC print_callback; sit = 0; pthread_attr_init(&threadattrib); pthread_attr_setinheritsched(&threadattrib, PTHREAD_EXPLICIT_SCHED); if(priority) { pthread_attr_setschedpolicy(&threadattrib,SCHED_FIFO); param.sched_priority = sched_get_priority_max(SCHED_FIFO); } else { pthread_attr_setschedpolicy(&threadattrib,SCHED_OTHER); param.sched_priority = sched_get_priority_max(SCHED_OTHER); } /* set the new scheduling param */ pthread_attr_setschedparam (&threadattrib, ¶m); print_callback = jtag_ctx->jtagcore_print_callback; threadinitptr = (threadinit *)malloc(sizeof(threadinit)); if( threadinitptr ) { threadinitptr->thread = thread; threadinitptr->jtag_ctx = jtag_ctx; //threadinitptr->hwcontext=hwcontext; ret = pthread_create(&threadid, &threadattrib,ThreadProc, threadinitptr); if(ret) { print_callback(jtag_ctx,"genos_createthread : pthread_create failed !"); free( threadinitptr ); } } else { print_callback(jtag_ctx,"genos_createthread : memory allocation failed !"); } return sit; } #endif char * genos_strupper(char * str) { int i; i=0; while(str[i]) { if(str[i]>='a' && str[i]<='z') { str[i]=str[i]+('A'-'a'); } i++; } return str; } char * genos_strlower(char * str) { int i; i=0; while(str[i]) { if(str[i]>='A' && str[i]<='Z') { str[i]=str[i]+('a'-'A'); } i++; } return str; } char * genos_getfilenamebase(char * fullpath,char * filenamebase, int type) { int len,i; char separator; if(fullpath) { len=strlen(fullpath); separator = DIR_SEPARATOR_CHAR; // system type by default switch(type) { case SYS_PATH_TYPE: // System based separator = DIR_SEPARATOR_CHAR; break; case UNIX_PATH_TYPE: // Unix style separator = '/'; break; case WINDOWS_PATH_TYPE: // Windows style separator = '\\'; break; } i=0; if(len) { i=len-1; while(i && ( fullpath[i] != separator && fullpath[i]!=':') ) { i--; } if( fullpath[i] == separator || fullpath[i]==':' ) { i++; } if(i>len) { i=len; } } if(filenamebase) { strcpy(filenamebase,&fullpath[i]); } return &fullpath[i]; } return 0; } char * genos_getfilenameext(char * fullpath,char * filenameext, int type ) { char * filename; int len,i; filename = genos_getfilenamebase(fullpath,0,type); if(filename) { len=strlen(filename); i=0; if(len) { i=len-1; while(i && ( filename[i] != '.' ) ) { i--; } if( filename[i] == '.' ) { i++; } else { i=len; } if(i>len) { i=len; } } if(filenameext) { strcpy(filenameext,&filename[i]); } return &filename[i]; } return 0; } int genos_getfilenamewext(char * fullpath,char * filenamewext, int type) { char * filename; char * ext; int len; len = 0; if(fullpath) { filename = genos_getfilenamebase(fullpath,0,type); ext = genos_getfilenameext(fullpath,0,type); len = ext-filename; if(len && filename[len-1]=='.') { len--; } if(filenamewext) { memcpy(filenamewext,filename,len); filenamewext[len]=0; } } return len; } int genos_getpathfolder(char * fullpath,char * folder,int type) { int len; char * filenameptr; len = 0; if(fullpath) { filenameptr = genos_getfilenamebase(fullpath,0,type); len = filenameptr-fullpath; if(folder) { memcpy(folder,fullpath,len); folder[len]=0; } } return len; } int genos_checkfileext(char * path,char *ext,int type) { char pathext[16]; char srcext[16]; char * ptr; if(path && ext) { pathext[0] = '\0'; srcext[0] = ' '; srcext[1] = '\0'; ptr = genos_getfilenameext(path,0,type); if(!ptr) return 0; if( ( strlen(ptr) < 16 ) && ( strlen(ext) < 16 )) { genos_getfilenameext(path,(char*)&pathext,type); genos_strlower(pathext); strcpy((char*)srcext,ext); genos_strlower(srcext); if(!strcmp(pathext,srcext)) { return 1; } } } return 0; } int genos_getfilesize(char * path) { int filesize; FILE * f; filesize=-1; if(path) { f=genos_fopen(path,"rb"); if(f) { fseek (f , 0 , SEEK_END); filesize=ftell(f); fclose(f); } } return filesize; } char * genos_strndstcat( char *dest, const char *src, size_t maxdestsize ) { int i,j; i = 0; while( ( i < maxdestsize ) && dest[i] ) { i++; } if( !dest[i] ) { j = 0; while( ( i < maxdestsize ) && src[j] ) { dest[i] = src[j]; i++; j++; } if( i < maxdestsize ) { dest[i] = '\0'; } } return dest; }