171 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
#include "stdio.h"
 | 
						|
#include "stdarg.h"
 | 
						|
#include "debug.h"
 | 
						|
#include "string.h"
 | 
						|
#include <sys/ipc.h>
 | 
						|
#include <sys/sem.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#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(level<DBG_LEVEL_INFO||level>DBG_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
 | 
						|
}
 | 
						|
 | 
						|
 |