韦东山-电子量产工具项目:输入单元

所有代码都已通过测试跑通,其中代码结构如下:

 一、include文件夹

 1.1 input_manager.h

#ifndef _INPUT_MANAGER_H //防止头文件重复包含,只要右边的出现过,就不会再往下编译
#define _INPUT_MANAGER_H
#include <sys/time.h>

#define INPUT_TYPE_TOUCH 1
#define INPUT_TYPE_NET 2
/* 上报的数据格式 */
typedef struct InputEvent
{
    struct timeval tTime; //加入时间管理
 
    int iType;      //网络事件或者触摸事件类型
    int iX;         //触摸事件x坐标
    int iY;         //触摸事件y坐标
    int iPressure;  //触摸事件压力
    char str[1024]; //网络事件字符串
} InputEvent, *PInputEvent;


/* 不同的输入设备,应该模块化,使用下面的结构体表示输入设备 */
typedef struct InputDevice
{
    char *name;                                     //设备名称
    int (*GetInputEvent)(PInputEvent ptInputEvent); //获得数据
    int (*DeviceInit)(void);
    int (*DeviceExit)(void);
    struct InputDevice *ptNext; //加入链表,将多个输入设备链接到一起
} InputDevice, *PInputDevice;



#endif

 1.2 tslib.h(注意:该文件由tslib-1.21.tar.bz2通过交叉编译得来,如何交叉编译及移植到开发板上将在文章最后介绍,也可参考韦东山老师的视频)

#ifndef _TSLIB_H_
#define _TSLIB_H_
/*
 *  tslib/src/tslib.h
 *
 *  Copyright (C) 2016 Martin Kepplinger <martink@posteo.de>
 *  Copyright (C) 2001 Russell King.
 *
 *  This 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.
 *
 *  This 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 this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 *
 * SPDX-License-Identifier: LGPL-2.1
 *
 *
 * Touch screen library interface definitions.
 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <stdarg.h>
#include <sys/time.h>

#ifdef WIN32
  #define TSIMPORT __declspec(dllimport)
  #define TSEXPORT __declspec(dllexport)
  #define TSLOCAL
#else
  #define TSIMPORT
  #ifdef GCC_HASCLASSVISIBILITY
    #define TSEXPORT __attribute__ ((visibility("default")))
    #define TSLOCAL __attribute__ ((visibility("hidden")))
  #else
    #define TSEXPORT
    #define TSLOCAL
  #endif
#endif

#ifdef TSLIB_INTERNAL
  #define TSAPI TSEXPORT
#else
  #define TSAPI TSIMPORT
#endif /* TSLIB_INTERNAL */

struct tsdev;

struct ts_sample {
	int		x;
	int		y;
	unsigned int	pressure;
	struct timeval	tv;
};

struct ts_sample_mt {
	/* ABS_MT_* event codes. linux/include/uapi/linux/input-event-codes.h
	 * has the definitions.
	 */
	int		x;
	int		y;
	unsigned int	pressure;
	int		slot;
	int		tracking_id;

	int		tool_type;
	int		tool_x;
	int		tool_y;
	unsigned int	touch_major;
	unsigned int	width_major;
	unsigned int	touch_minor;
	unsigned int	width_minor;
	int		orientation;
	int		distance;
	int		blob_id;

	struct timeval	tv;

	/* BTN_TOUCH state */
	short		pen_down;

	/* valid is set != 0 if this sample
	 * contains new data; see below for the
	 * bits that get set.
	 * valid is set to 0 otherwise
	 */
	short		valid;
};

#define TSLIB_MT_VALID			(1 << 0)	/* any new data */
#define TSLIB_MT_VALID_TOOL		(1 << 1)	/* new tool_x or tool_y data */

struct ts_lib_version_data {
	const char	*package_version;
	int		version_num;
	unsigned int	features; /* bitmask, see below */
};

#define TSLIB_VERSION_MT		(1 << 0)	/* multitouch support */
#define TSLIB_VERSION_OPEN_RESTRICTED	(1 << 1)	/* ts_open_restricted() */
#define TSLIB_VERSION_EVENTPATH		(1 << 2)	/* ts_get_eventpath() */
#define TSLIB_VERSION_VERSION		(1 << 3)	/* tslib_version() */

enum ts_param {
	TS_SCREEN_RES = 0,		/* 2 integer args, x and y */
	TS_SCREEN_ROT			/* 1 integer arg, 1 = rotate */
};

struct ts_module_conf {
	char *name;
	char *params;
	int raw;
	int nr;

	struct ts_module_conf *next;
	struct ts_module_conf *prev;
};

/*
 * Close the touchscreen device, free all resources.
 */
TSAPI int ts_close(struct tsdev *);

/*
 * Reloads all modules - useful to reload calibration data.
 */
TSAPI int ts_reconfig(struct tsdev *);

/*
 * Configure the touchscreen device.
 */
TSAPI int ts_config(struct tsdev *);

/*
 * Changes a setting.
 */
TSAPI int ts_option(struct tsdev *, enum ts_param, ...);

/*
 * Change this hook to point to your custom error handling function.
 */
extern TSAPI int (*ts_error_fn)(const char *fmt, va_list ap);

/*
 * Implement this to override open() for the input device and return the fd.
 */
extern TSAPI int (*ts_open_restricted)(const char *path, int flags, void *user_data);

/*
 * Implement this to override close().
 */
extern TSAPI void (*ts_close_restricted)(int fd, void *user_data);

/*
 * Returns the file descriptor in use for the touchscreen device.
 */
TSAPI int ts_fd(struct tsdev *);

/*
 * Load a filter/scaling module
 */
TSAPI int ts_load_module(struct tsdev *, const char *mod, const char *params);

/*
 * Open the touchscreen device.
 */
TSAPI struct tsdev *ts_open(const char *dev_name, int nonblock);

/*
 * Find, open and configure the touchscreen device.
 */
TSAPI struct tsdev *ts_setup(const char *dev_name, int nonblock);

/*
 * Return a scaled touchscreen sample.
 */
TSAPI int ts_read(struct tsdev *, struct ts_sample *, int);

/*
 * Returns a raw, unscaled sample from the touchscreen.
 */
TSAPI int ts_read_raw(struct tsdev *, struct ts_sample *, int);

/*
 * Return a scaled touchscreen multitouch sample.
 */
TSAPI int ts_read_mt(struct tsdev *, struct ts_sample_mt **, int slots, int nr);

/*
 * Return a raw, unscaled touchscreen multitouch sample.
 */
TSAPI int ts_read_raw_mt(struct tsdev *, struct ts_sample_mt **, int slots, int nr);

/*
 * This function returns a pointer to a static copy of the version info struct.
 */
TSAPI struct ts_lib_version_data *ts_libversion(void);

/*
 * Get the list of (commented-in) ts.conf module lines (as structs)
 */
TSAPI struct ts_module_conf *ts_conf_get(struct tsdev *ts);

/*
 * Write the list of modules to ts.conf
 */
TSAPI int ts_conf_set(struct ts_module_conf *conf);

/*
 * This function returns the path to the opened touchscreen input device file.
 */
TSAPI char *ts_get_eventpath(struct tsdev *tsdev);

/*
 * This simply returns tslib's version string
 */
TSAPI char *tslib_version(void);

/*
 * This prints tslib's logo to stdout, with pos preceding spaces
 */
TSAPI void ts_print_ascii_logo(unsigned int pos);

#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _TSLIB_H_ */

二、input文件夹

2.1 input_manager.c

#include "input_manager.h"
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
static pthread_mutex_t g_tMutex  = PTHREAD_MUTEX_INITIALIZER; 
static pthread_cond_t  g_tConVar = PTHREAD_COND_INITIALIZER;
static PInputDevice g_InputDevs = NULL;


/************环形缓冲区开******************/
#define BUFFER_LEN 20         /*环形缓冲区长度*/
static int g_iRead  = 0;      /*读指针*/
static int g_iWrite = 0;       /*写指针*/
static InputEvent g_atInputEvents[BUFFER_LEN];   /*环形缓冲区*/
/*判断环形缓冲区是否为满*/
static int isInputBufferFull(void)
{
	return (g_iRead == ((g_iWrite + 1) % BUFFER_LEN));
}
/*判断环形缓冲区是否为空*/
static int isInputBufferEmpty(void)
{
	return (g_iRead == g_iWrite);
}
/************环形缓冲区关******************/

//缓冲区事件存储函数
static void PutInputEventToBuffer(PInputEvent ptInputEvent)
{
	if (!isInputBufferFull())
	{
		g_atInputEvents[g_iWrite] = *ptInputEvent;
		g_iWrite = (g_iWrite + 1) % BUFFER_LEN;
	}
}
//缓冲区事件获取函数
static int GetInputEventFromBuffer(PInputEvent ptInputEvent)
{
	if (!isInputBufferEmpty())
	{
		*ptInputEvent = g_atInputEvents[g_iRead];
		g_iRead = (g_iRead + 1) % BUFFER_LEN;
		return 1;
	}
	else
	{
		return 0;
	}
}
// 事件获取函数
int GetInputEvent(PInputEvent ptInputEvent)
{
	InputEvent tEvent;
	int ret;
	/* 无数据则休眠 */
	pthread_mutex_lock(&g_tMutex);  /*互斥锁*/
	if (GetInputEventFromBuffer(&tEvent))
	{
		*ptInputEvent = tEvent;
		pthread_mutex_unlock(&g_tMutex);/*释放互斥锁*/
		return 0;
	}
	else
	{
		/* 休眠等待 */
		pthread_cond_wait(&g_tConVar, &g_tMutex);	
		if (GetInputEventFromBuffer(&tEvent))
		{
			*ptInputEvent = tEvent;
			ret = 0;
		}
		else
		{
			ret = -1;
		}
		pthread_mutex_unlock(&g_tMutex);  /*释放互斥锁*/		
	}
	return ret;
}
//线程函数
static void *input_recv_thread_func (void *data)
{
	PInputDevice ptInputDev = (PInputDevice)data;
	InputEvent tEvent;
	int ret;	
	while (1)
	{
		/* 读数据 */
		ret = ptInputDev->GetInputEvent(&tEvent);
		if (!ret)
		{	
			/* 保存数据 */
			pthread_mutex_lock(&g_tMutex);
			PutInputEventToBuffer(&tEvent);
			/* 唤醒等待数据的线程 */
			pthread_cond_signal(&g_tConVar); /* 通知接收线程 */
			pthread_mutex_unlock(&g_tMutex);
		}
	}
	return NULL;
}


 
void RegisterInputDevice(PInputDevice ptInputDev)
{
    ptInputDev->ptNext = g_InputDevs;//指向链表头
    g_InputDevs = ptInputDev;
}
  
 
void InputInit(void)
{
    /* 注册按键输入 */
    extern void TouchscreenRegister(void);
    TouchscreenRegister();//在touchscreen.c中
 
    /* 注册网络输入 */
    extern void NetInputRegister(void);
    NetInputRegister();//在netinput.c中
}
 

void InputDeviceInit(void)
{
    int ret;
    pthread_t tid;
    /* for each device ,init,pthread_create */
    PInputDevice ptTmp = g_InputDevs;
    while (ptTmp)
    {
        ret = ptTmp->DeviceInit();
        if (!ret)
        {
 
            ret = pthread_create(&tid, NULL, input_recv_thread_func, ptTmp);
        }
 
        ptTmp = ptTmp->ptNext;
    }
}
 

2.2 netinput.c 

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "input_manager.h"
 
#define SERVER_PORT 8888
 
static int g_iSocketServer;
 
static int NetinputGetInputEvent(PInputEvent ptInputEvent)
{
    char ucRecvBuf[1000];
    int iRecvLen;
    struct sockaddr_in tSocketClientAddr;
 
    unsigned int iAddrLen = sizeof(struct sockaddr);
    /* 接收客户端数据报文,返回的为接收到的字节数 */
    iRecvLen = recvfrom(g_iSocketServer, ucRecvBuf, sizeof(ucRecvBuf), 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
    if (iRecvLen > 0)
    {
 
        ucRecvBuf[iRecvLen] = '\0';
        //printf("Get Msg from %s : %s\n", inet_ntoa(socket_client_addr.sin_addr), buf);
        ptInputEvent->iType = INPUT_TYPE_NET;
        gettimeofday(&ptInputEvent->tTime, NULL);
        strncpy(ptInputEvent->str, ucRecvBuf, 1000);
        ptInputEvent->str[999] = '\0';
        return 0;
    }
    else
        return -1;
}
 
static int NetinputDeviceInit(void)
{
    struct sockaddr_in tSocketServerAddr;
    int iRet;
 
    /*创建数据报套接字*/
    g_iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
    if (g_iSocketServer == -1)
    {
        printf("socket error");
        return -1;
    }
 
    /* 服务器端填充 sockaddr_in结构 */
    tSocketServerAddr.sin_family = AF_INET;
    tSocketServerAddr.sin_port = htons(SERVER_PORT);
    tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
    memset(tSocketServerAddr.sin_zero, 0, 8);
 
    /*绑定套接字*/
    iRet = bind(g_iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
    if (iRet == -1)
    {
        printf("bind error!\n");
        return -1;
    }
    return 0;
}
 
static int NetinputDeviceExit(void)
{
    close(g_iSocketServer);
    return 0;
}
 
static InputDevice g_tNetinputDev = {
 
    .name = "netinput",
    .GetInputEvent = NetinputGetInputEvent,
    .DeviceInit = NetinputDeviceInit,
    .DeviceExit = NetinputDeviceExit,
 
};
void NetInputRegister(void)
{
	RegisterInputDevice(&g_tNetinputDev);
}
#if 0
 
int main(int argc, char **argv)
{
    InputEvent event;
    int ret;
    g_tNetinputDev.DeviceInit();
    while (1)
    {
        ret = g_tNetinputDev.GetInputEvent(&event);
        if (ret)
        {
            printf("GetInputEvent err\r\n");
            return -1;
        }
        else
        {
            printf("iType       =%d\r\n", event.iType);
            printf("str         =%s\r\n", event.str);
        }
    }
    return 0;
}
 
#endif

2.3 touchscreen.c

#include "input_manager.h"
#include <tslib.h>
#include <stdio.h>

struct tsdev *g_ts;
//获取触摸事件
static int TouchscreenGetInputEvent(PInputEvent ptInputEvent)
{
    struct ts_sample samp;
    int ret;
 
    ret = ts_read(g_ts, &samp, 1);
 
    if (ret != 1)
        return -1;
 
    ptInputEvent->iType = INPUT_TYPE_TOUCH;
    ptInputEvent->iX = samp.x;
    ptInputEvent->iY = samp.y;
    ptInputEvent->iPressure = samp.pressure;
    ptInputEvent->tTime = samp.tv;
    return 0;
}
//触摸屏设备初始化
static int TouchscreenDeviceInit(void)
{
    /* 打开并配置触摸屏设备 */
    g_ts = ts_setup(NULL, 0);
    if (!g_ts)
    {
        printf("ts_setup err\n");
        return -1;
    }
    return 0;
}
//触摸设备退出
static int TouchscreenDeviceExit(void)
{
    ts_close(g_ts);
    return 0;
}
//设备结构体 
static InputDevice g_tTouchscreenDev = {
 
    .name = "touchscreen",
    .GetInputEvent = TouchscreenGetInputEvent,
    .DeviceInit = TouchscreenDeviceInit,
    .DeviceExit = TouchscreenDeviceExit,
 
};

void TouchscreenRegister(void)
{
	RegisterInputDevice(&g_tTouchscreenDev);
}

#if 0
 
int main(int argc, char **argv)
{
    InputEvent event;
    int ret;
    g_tTouchscreenDev.DeviceInit();
    while (1)
    {
        ret = g_tTouchscreenDev.GetInputEvent(&event);
        if (ret)
        {
            printf("GetInputEvent err\r\n");
            return -1;
        }
        else
        {
            printf("iType       =%d\r\n", event.iType);
            printf("iX          =%d\r\n", event.iX);
            printf("iY          =%d\r\n", event.iY);
            printf("iPressure   =%d\r\n", event.iPressure);
        }
    }
    return 0;
}
 
#endif

2.4 Makefile

EXTRA_CFLAGS  :=
CFLAGS_file.o :=
obj-y +=netinput.o  
obj-y +=touchscreen.o
obj-y +=input_manager.o

三、uiontest文件夹

3.1 test.c

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <input_manager.h>

int main(int argc, char **argv)
{
	int ret;
	InputEvent event;
	
	InputInit();
	InputDeviceInit();

	while (1)
	{
		printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
		ret = GetInputEvent(&event);

		printf("%s %s %d, ret = %d\n", __FILE__, __FUNCTION__, __LINE__, ret);
		if (ret) {
			printf("GetInputEvent err!\n");
			return -1;
		}
		else
		{
			printf("%s %s %d, event.iType = %d\n", __FILE__, __FUNCTION__, __LINE__, event.iType );
			if (event.iType == INPUT_TYPE_TOUCH)
			{
				printf("Type      : %d\n", event.iType);
				printf("iX        : %d\n", event.iX);
				printf("iY        : %d\n", event.iY);
				printf("iPressure : %d\n", event.iPressure);
			}
			else if (event.iType == INPUT_TYPE_NET)
			{
				printf("Type      : %d\n", event.iType);
				printf("str       : %s\n", event.str);
			}
		}
	}
	return 0;	
}

3.2 client.c

        注意:该代码不通过makefile编译,而是直接通过arm-linux-gnueabihf-gcc client.c -o all_client命令编译

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
 
#define SERVER_PORT 8888
 
int main(int argc, char **argv)
{
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr;
 
	int iRet;
	int iSendLen;
	int iAddrLen;
 
	if (argc != 3)
	{
		printf("Usage:\n");
		printf("%s <server_ip> <str>\n", argv[0]);
		return -1;
	}
 
	iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
 
	tSocketServerAddr.sin_family = AF_INET;
	tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
	//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
	if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))
	{
		printf("invalid server_ip\n");
		return -1;
	}
	memset(tSocketServerAddr.sin_zero, 0, 8);
 
#if 0
	iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));	
	if (-1 == iRet)
	{
		printf("connect error!\n");
		return -1;
	}
#endif
 
	iAddrLen = sizeof(struct sockaddr);
	iSendLen = sendto(iSocketClient, argv[2], strlen(argv[2]), 0,(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
 
	close(iSocketClient);
 
	return 0;
}

3.3 Makefile

      这里很明显可以看到只编译test.c

EXTRA_CFLAGS  :=
CFLAGS_file.o :=
obj-y +=test.o  

四、顶层Makefile及Makefile.build

4.1 Makefile

注意LDFLAGS 设置链接库,需要线程库和触摸屏库支持,其中-lts要求在指定路径下寻找,我的tslib交叉编译在/home/alexius/Downloads/tslib-1.21/install文件夹下。故LDFLAGS设置如下:

                  LDFLAGS := -L/home/alexius/Downloads/tslib-1.21/install/lib -lts -lpthread

#指定交叉编译工具链
COSS_COMPLE ?=arm-linux-gnueabihf-
AS	= $(COSS_COMPLE)as
LD	= $(COSS_COMPLE)ld
CC	= $(COSS_COMPLE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm



STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump

# export导出的变量是给子目录下的Makefile使用的
export AS LD CC CPP AR NM 
export STRIP OBJCOPY OBJDUMP

# 编译器在编译时的参数设置
CFLAGS := -Wall -O2 -g -DDEBUG
# 添加头文件路径,不添加的话include目录下的头文件编译时找不到
CFLAGS += -I $(shell pwd)/include 

# 链接器的链接参数设置,链接库
LDFLAGS := -L/home/alexius/Downloads/tslib-1.21/install/lib -lts -lpthread#触摸屏库链接

export CFLAGS LDFLAGS

TOPDIR := $(shell pwd)
export TOPDIR

# 定义将来编译生成的可执行程序的名字
TARGET := all_test

# 添加项目中所有用到的源文件,有顶层目录下的.c文件,和子文件夹
# 添加顶层目录下的.c文件
#obj-y += main.o

# 添加顶层目录下的子文件夹(注意目录名后面加一个/)
#obj-y += main.o
obj-y += input/
obj-y += uiontest/



# 第一个目标
all : start_recursive_build $(TARGET)
	@echo $(TARGET) has been built!
    
# 处理第一个依赖,**转到 Makefile.build 执行**
start_recursive_build:
	make -C ./ -f $(TOPDIR)/Makefile.build
    
# 处理最终目标,把前期处理得出的 built-in.o 用上
$(TARGET) : built-in.o
	$(CC) -o $(TARGET) built-in.o $(LDFLAGS)
    
# 清理
clean:
	rm -f $(shell find -name "*.o")
	rm -f $(TARGET)
    
# 彻底清理
distclean:
	rm -f $(shell find -name "*.o")
	rm -f $(shell find -name "*.d")
	rm -f $(TARGET)

4.2 Makefile.build


# 将__build定义为伪目标
PHONY := __build
__build:

# 这里初值为空,下面引入Makefile文件后会被覆盖
obj-y :=
subdir-y :=

# 包含同级目录的Makefile
include Makefile

# 从obj-y变量中,将"/"结尾的字符串提取出来,也就是包含的子文件夹目录
__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y	+= $(__subdir-y)

# 将subdir-y变量中的字符串依次赋值给f变量,形成新的$(f)/built-in.o字符串
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)

# 筛选出obj-y中不以"/"结尾的字符串,也就是普通文件,一般是.o结尾
cur_objs := $(filter-out %/, $(obj-y))

# 为每个.o文件生成.d文件
# 注意.$(f).d是隐藏文件,需要ls -a查看
dep_files := $(foreach f,$(cur_objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

# 如果.d文件不是空,则将.d文件都包含进来
ifneq ($(dep_files),)
  include $(dep_files)
endif


PHONY += $(subdir-y)

# __build是Makefile的目标

__build : $(subdir-y) built-in.o

# 依次跳转到子目录中,执行Makefile.build文件
$(subdir-y):
	make -C $@ -f $(TOPDIR)/Makefile.build

# 生成当前目录的built-in.o,依赖当前目录的.o文件和子目录下的built-in.o文件
built-in.o : $(cur_objs) $(subdir_objs)
	$(LD) -r -o $@ $^

# dep_file变量是用来生成.d文件的
dep_file = .$@.d

# Makefile中的规则,把.c文件编译成.o文件
%.o : %.c
	$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<

# 重新定义 .PHONY的依赖
.PHONY : $(PHONY)

五、编译及运行

  5.1 编译    

此时编译client.c

 5.2 运行

 先查开发板ip

运行测试程序

再运行clien程序

 此时滑动屏幕,显示如下:

六、tslib库移植到开发板上

      6.1 交叉编译步骤 

        采用tslib-1.21.tar.bz2,步骤如下:

#ubuntu 工具安装
sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install libtool
#git下载
git clone https://github.com/libts/tslib
#加入文件夹
cd tslib/
mkdir install
./autogen.sh
./configure --host=arm-linux-gnueabihf --prefix=$(pwd)/install  
make //编译
sudo make install //安装

 交叉编译后的文件如下:

     6.2 移植开发板

       将install文件夹拷贝到IMX6ull开发板上,并重命名为arm-tslib。这里不建议向正点一样直接将lib下文件拷贝到开发板lib下,因为做其他类似移植时,存在使用同一个库但不同版本的问题。如移植wpa_supplicant和mqtt时候存在两个openssl库冲突问题,故移植直接打包过去就好,省时还清晰明了。

      6.3 开发板配置tslib的相关文件

        由于是整个打包到开发板,所以直接在开发板上把包里的库和可执行程序告诉profile环境就行,执行 vi /etc/profile ,添加如下:

#tslib
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_ROOT=/arm-tslib
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal #TSLIB_CALIBFILE指定了触摸屏的校准文件路径
#export LD_PRELOAD=$TSLIB_ROOT/lib/libts.so
export PATH=$PATH:$TSLIB_ROOT/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib

#再次激活环境
source /etc/profile

6.4 移植测试 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值