下面是一个示例,将设备上运行的应用中的printf输出到telnet登录中;
1.common function
debug.h
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#define NONE "\033[m"
#define RED "\033[0;32;31m"
#define LIGHT_RED "\033[1;31m"
#define GREEN "\033[0;32;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;32;34m"
#define LIGHT_BLUE "\033[1;34m"
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define BROWN "\033[0;33m"
#define YELLOW "\033[1;33m"
#define LIGHT_GRAY "\033[0;37m"
#define WHITE "\033[1;37m"
#define SIZE (1024)
typedef struct
{
long int type;
char buffer[SIZE];
}Message;
int debug_print(const char* format, ...);
int debug_recv(Message* recv);
char* debug_time_str();
#define DBG(fmt, ...) do\
{\
debug_print(GREEN"%s %d debug %s: %d: "NONE""fmt"", debug_time_str(), getpid(), __FUNCTION__, __LINE__, ##__VA_ARGS__);\
}while(0)
#define ERR(fmt, ...) do\
{\
debug_print(RED"%s %d error %s: %d: "NONE""fmt"", debug_time_str(), getpid(), __FUNCTION__, __LINE__, ##__VA_ARGS__);\
}while(0)
#define INFO(fmt, ...) do\
{\
debug_print(YELLOW"%s %d info %s: %d: "NONE""fmt"", debug_time_str(), getpid(), __FUNCTION__, __LINE__, ##__VA_ARGS__);\
}while(0)
#define CHECK(exp, ret, fmt...) do\
{\
if (!(exp))\
{\
ERR(fmt);\
return ret;\
}\
}while(0)
debug.c
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "debug.h"
#define KEY (0x23581321)
#define TYPE (1)
#define MAXSENDSIZE (sizeof(Message)-sizeof(long int))
typedef struct
{
int inited;
int msgid;
long int type;
pthread_mutex_t mutex;
}msg_s;
static msg_s msg;
char* debug_time_str()
{
static char time[32] = "";
struct timeval tv = {0, 0};
gettimeofday(&tv, NULL);
strftime(time, sizeof(time), "%F %H:%M:%S", localtime(&tv.tv_sec));
return time;
}
static int debug_init()
{
memset(&msg, 0, sizeof(msg));
msg.type = TYPE;
pthread_mutex_init(&msg.mutex, NULL);
msg.msgid = msgget(KEY, 0666|IPC_CREAT);
if (msg.msgid == -1)
{
perror("create_msg failed!\n");
return -1;
}
msg.inited = 1;
return 0;
}
int debug_print(const char* format, ...)
{
if (!msg.inited)
{
debug_init();
}
pthread_mutex_lock(&msg.mutex);
static Message send_buf;
memset(&send_buf, 0, sizeof(send_buf));
send_buf.type = msg.type;
va_list ap;
va_start(ap, format);
vsnprintf(send_buf.buffer, sizeof(send_buf.buffer), format, ap);
va_end(ap);
fprintf(stdout, "%s", send_buf.buffer);
msgsnd(msg.msgid, &send_buf, MAXSENDSIZE, IPC_NOWAIT);
pthread_mutex_unlock(&msg.mutex);
return 0;
}
int debug_recv(Message* recv)
{
if (!msg.inited)
{
debug_init();
}
pthread_mutex_lock(&msg.mutex);
memset(recv, 0, sizeof(*recv));
msgrcv(msg.msgid, recv, MAXSENDSIZE, msg.type, 0);
pthread_mutex_unlock(&msg.mutex);
return 0;
}
2.client sample,这是一个device上运行的app示例,该示例会循环打印;
client.c
#include "../debug.h"
#include <pthread.h>
void* proc(void* arg)
{
int count = 1000;
while(1)
{
INFO("test count: %d\n", count++);
usleep(1000*1000);
}
return NULL;
}
int main()
{
int count = 0;
pthread_t pid = 0;
pthread_create(&pid, NULL, proc, NULL);
while(1)
{
DBG("test count: %d\n", count++);
ERR("test count: %d\n", count++);
//INFO("test count: %d\n", count++);
usleep(1000*1000);
}
return 0;
}
3.telnet app,telnet登录后运行该app,该app会获取client app中printf发送的字串,将其在telnet中输出;
telnetp.c
#include "../debug.h"
int main(int argc, char** argv)
{
if (argc > 2)
{
printf("invalid args.argc=%d\n", argc);
return 0;
}
Message recv;
while(1)
{
debug_recv(&recv);
if (argc == 2)
{
if (strstr(recv.buffer, argv[1]))
{
//fprintf/printf both work
//fprintf(stdout, "%s", recv.buffer);
printf("%s", recv.buffer);
}
}
else
{
//fprintf/printf both work
//fprintf(stdout, "%s", recv.buffer);
printf("%s", recv.buffer);
}
}
return 0;
}
4.makefile sample,提供一个简单的makefile示例:
code tree
debug.h
debug.c
client
->client.c makefile
telnetp
->telnetp.c makefile
makefile
SDK_DIR = /szsa031/usrhome/ben.du/newglee3528/source/buildroot
SYS_FS_DIR= $(SDK_DIR)/output/target
TOOLCHAIN_DIR = $(SDK_DIR)/output/host/opt/ext-toolchain/2017.10-05/bin/
LD = $(TOOLCHAIN_DIR)mips-mti-linux-gnu-ld
AR = $(TOOLCHAIN_DIR)mips-mti-linux-gnu-ar
CC = $(TOOLCHAIN_DIR)mips-mti-linux-gnu-gcc
CXX = $(TOOLCHAIN_DIR)mips-mti-linux-gnu-g++
CFLAGS = -DHW_SECURE_ENABLE -DAUI -DSDKVERSION_6_6_2_6 -DOLD_SNR2dB_TABLE -EL -mips32r2 -Wall -g -funwind-tables -DRELEASE_SVN_VERSION="\"$(RELEASE_SVN_VERSION)\"" -DRELEASE_DATE="\"$(RELEASE_DATE)\"" -DRELEASE_OWNER="\"$(RELEASE_OWNER)\"" -DRELEASE_CODE_INFO="\"$(RELEASE_CODE_INFO)\"" -DUSM_HAL_SUPPORTED_FLASH_MTD -DUSM_HAL_SUPPORTED_FS_STD -DJZ_SYS_MEM_SIZE=256 \
-I./include -I./hal/common/fs -I./hal/common/flash \
-I./include/jzapi -I./include/utils -I./hal/common/panel \
-I./include/osal -I./osal/include -I./include/hal \
-I./hal/ttx/common -I./hal/ttx/datamanager -I./hal/ttx/filter -I./hal/ttx/local -I./hal/ttx/parser \
-I./hal/flash -I./hal/common/flash/mtd -I./hal/common/frontend -I./hal/common/image\
-I./hal/fs \
$(INC_DIR)
objects = ../debug.o client.o
appname = client
all:$(objects)
$(CXX)$(objects) -EL -mips32r2 -g -lpthread -L. -Wl,--start-group -laui \
-Wl,--end-group -Wl,-rpath-link=$(SYS_FS_DIR)/usr/lib -Wl,--start-group\
-Wl,--end-group -L$(SYS_FS_DIR)/usr/lib -Wl,--start-group -lc -lm -lrt -ldl\
-Wl,--end-group -lz -o $(appname) -Wl,-Map=$(appname).map
## -cp $(appname).out $(SYS_FS_DIR)/root
cp $(appname) $(SYS_FS_DIR)/usr/bin/
cp $(appname) /szsa031/usrhome/username/usb_cp
copfiles:
cp ./ourlib/* ./ -R
%.o:%.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.out *.map *.o *.a ../*.o