#include "stdio.h" #include "stdarg.h" #include "debug.h" #include "string.h" #include #include #include #include "errno.h" #define CONSOLEBUF_SIZE 1024 #ifdef LINUX union semun{ int val; /* Value for SETVAL */ struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ unsigned short *array; /* Array for GETALL, SETALL */ struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */ }; void _sem_take(int semid)//得到钥匙 { struct sembuf sop; sop.sem_num = 0;//控制第一个信号量 sop.sem_op = -1;//钥匙数量减一6 sop.sem_flg = SEM_UNDO; semop(semid,&sop,1); } void _sem_relase(int semid)//放回钥匙 { struct sembuf sop; sop.sem_num = 0; sop.sem_op = 1; sop.sem_flg = SEM_UNDO; semop(semid,&sop,1); } int _sem_init(){ key_t key; int mutex; key = ftok(".",5345); // printf("sem init, key=%llu\n",key); mutex = semget(key,1,IPC_CREAT);//创建信号量 // printf("sem init, mutex=%d\n",mutex); if(mutex<=0){ // printf("%d\n",errno); } union semun set; set.val = 1;//钥匙数量为0 semctl(mutex,0,SETVAL,set); return mutex; } #endif #ifdef RT_THREAD #include "rtthread.h" #endif typedef struct{ int inited; int print_context; #ifdef RT_THREAD struct rt_mutex mutex; #endif #ifdef LINUX int mutex; #endif dbg_dev *dev; }self_def; static self_def g_data; static int dev_init(){ return 0; } static int dev_write(const uint8_t *data,size_t len){ size_t rb; rb=fwrite(data,sizeof(uint8_t),len,stdout); return (int)rb; } static dbg_dev g_dev_default={ .init=dev_init, .write=dev_write, }; int debug_init(dbg_dev *dev) { self_def *self=&g_data; if(dev==NULL){ dev=&g_dev_default; } if(self->inited==0) { #ifdef RT_THREAD rt_mutex_init(&self->mutex,"debug_mutex",RT_IPC_FLAG_FIFO); #endif #ifdef LINUX self->mutex=_sem_init(); #endif self->dev=dev; self->dev->init(); self->dev->write((const uint8_t *)"\r\n",2); self->inited = 1; debug_print_context(1); DBG_LOG("debug inited.\r\n"); } return 0; } void debug_print_context(int enable) { g_data.print_context = enable; } void debug_log(const char *file,const char *fun,int line,int level,const char *fmt, ...) { self_def *self=&g_data; if(self->inited==0) return; va_list args; size_t length; static char log_buf[CONSOLEBUF_SIZE]; static const char *level_str[]={"[info] ","[log] ","[warn] ","[err] "}; static int level_str_len[]={7,6,7,6}; if(levelDBG_LEVEL_ERR) return; #ifdef RT_THREAD rt_mutex_take(&self->mutex,RT_WAITING_FOREVER); #endif #ifdef LINUX _sem_take(self->mutex); #endif memcpy(log_buf,level_str[level],level_str_len[level]); length = level_str_len[level]; if (self->print_context) { length += sprintf(log_buf + length, "%s:%d|%s| ", file, line, fun); } va_start(args, fmt); length += vsnprintf(log_buf + length, CONSOLEBUF_SIZE - length - 3, fmt, args); va_end(args); if (length > CONSOLEBUF_SIZE - 3) length = CONSOLEBUF_SIZE - 3; if(log_buf[length-1]!='\n'){ memcpy(&log_buf[length],"\n",1); length+=1; } log_buf[length]=0; self->dev->write((const uint8_t *)log_buf,length); #ifdef RT_THREAD rt_mutex_release(&self->mutex); #endif #ifdef LINUX _sem_relase(self->mutex); #endif }