Linux下,接收opos数据的例程

本例程设计知识点:

  • 读取hidraw1设备数据
  • 子线程应用
  • 动态库的制作,及动态加载
  • 回调函数的注册和使用

opos.c文件源码:

#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h> // for close
#include <string.h>
	
#include <stdlib.h>
#include <pthread.h>
#include "opos.h"


#define OposDisplayTest			1
#define ReadOposDisplayTest		1

typedef void (*P_ShowBarcode)(char *str) ;//定义函数指针类型
P_ShowBarcode m_ShowBarcode = NULL;//定义一个函数指针 m_ShowBarcode

int fd=0, CloseFlag=0;
pthread_t id;//定义线程ID

/*******************************************************************************
* Function Name  : reg_opos
* Description    : opos注册函数,用于注册回调显示条码的函数
* Input          : fun:回调显示的函数指针
* Output         : None
* Return         : None
*******************************************************************************/
void reg_opos(void * fun)
{
	m_ShowBarcode = (P_ShowBarcode)fun;
}

/*******************************************************************************
* Function Name  : open_opos
* Description    : 打开opos函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void open_opos(void)
{
	void *arg = NULL;//定义一个空指针
	int ret;
	
	fd = open("/dev/hidraw1", O_RDWR);

#ifdef	OposDisplayTest
	printf("fd = %d \n", fd);
#endif

	if(fd<0)
	{
#ifdef	OposDisplayTest
		printf("Open error2\n");
#endif
	}
	else
	{
#ifdef	OposDisplayTest
		printf("Open ok\n");
#endif
		ret=pthread_create(&id,NULL,(void *) ReadOposData,(void*)(&arg));
	
		if(ret!=0)
		{
#ifdef	OposDisplayTest
			printf ("Create pthread error!\n");
#endif
			exit (1);
		}
	}
}

/*******************************************************************************
* Function Name  : close_opos
* Description    : 关闭opos函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void close_opos(void)
{
	CloseFlag=1;//关闭标志置1
	
	pthread_join(id,NULL);

#ifdef	OposDisplayTest
	printf("close\n");
#endif
	close(fd);
}

/*******************************************************************************
* Function Name  : ReadOposData
* Description    : 读取opos数据的函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void ReadOposData(void *arg)
{
	char barcode[2048];
	int count=64, read_num=0;
	int remain_len=0, save_len=0, code_len=0;
	unsigned char buffer[64];

	CloseFlag=0;//清空关闭标志

	while(CloseFlag==0)
	{
#ifdef	ReadOposDisplayTest
		printf("read...\n");
#endif
		memset(barcode, 0, sizeof(barcode));//清零
		code_len = 0;
		remain_len = 0;
		save_len = 0;
		

		read_num = read(fd,buffer,count);//读取opos数据包
		if (read_num<0)
		{
#ifdef	ReadOposDisplayTest
			printf("read fail\n");
#endif
		}
		else
		{
			code_len = buffer[0] + (buffer[1]<<8);//获取整个数据包的长度
			remain_len = code_len+2;//包头的长度不包含最后两个字节的校验码

#ifdef	ReadOposDisplayTest
			printf("remain_len = %d\n", remain_len);
#endif

			if(remain_len <= read_num)//一个opos包接收完所有数据
			{
				memmove(barcode, buffer+4, remain_len-4);//解析出条码数据
				save_len += remain_len-4;
				remain_len = 0;
			}
			else
			{
				memmove(barcode, buffer+4, read_num-4);//解析出条码数据
				save_len += read_num-4;
				remain_len -= read_num;
				
				while(remain_len)
				{
					memset(buffer, 0, sizeof(buffer));//清零
					
					read_num = read(fd,buffer,count);//读取opos数据包
					if (read_num<0)
					{
#ifdef	ReadOposDisplayTest
						printf("read fail\n");
#endif
					}
					
					if(remain_len>=read_num)//数据包中不包含最后两个字节的校验符。
					{
						memmove(barcode+save_len, buffer, read_num);//解析出条码数据
						save_len += read_num;
						remain_len -= read_num;
					}
					else
					{
						memmove(barcode+save_len, buffer, remain_len);//解析出条码数据
						save_len += remain_len;
						remain_len = 0;
					}
				}
			}

#ifdef	ReadOposDisplayTest
			printf("save_len = %d\n", remain_len);
#endif

			barcode[save_len-2] = '\0';//设置字符串换行符

			m_ShowBarcode(barcode);//回调main函数中的函数,用于显示条码
		}
	}
}
//说明:此函数涉及到从设备的打包格式中提出数据。



opos.h文件源码:

#ifndef OPOS_H
#define OPOS_H


void reg_opos(void * fun);
void open_opos(void);
void close_opos(void);

void ReadOposData(void *arg);


#endif

 

main.c文件源码:

#include <stdio.h>  
#include <stdlib.h>  
#include <dlfcn.h>  
#include <signal.h>  
#include <errno.h> 
#include "opos.h"

int listnum =0;


/*******************************************************************************
* Function Name  : error_quit
* Description    : 输出错误信息并退出 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void error_quit(const char *str)        
{        
    fprintf(stderr, "%s\n", str);     
    exit(1);        
}   

/*******************************************************************************
* Function Name  : ShowBarcode
* Description    : 显示条码的函数
* Input          : str需要显示的条码字符串的指针
* Output         : None
* Return         : None
*******************************************************************************/
void ShowBarcode(char *str)        
{        
	listnum ++;
	printf("%d: %s\n", listnum,str);            
}

/*******************************************************************************
* Function Name  : main
* Description    : 主函数
* Input          : argc:未调用,argv:未调用
* Output         : None
* Return         : 0
*******************************************************************************/
int main(int argc, char * argv [ ])
{
	void *plib; 					//指向so文件的指针  
	typedef void (*FUN_REG_OPOS)(void*);  
	typedef void (*FUN_OPEN_OPOS)(); 
	typedef void (*FUN_CLOSE_OPOS)();  

	FUN_REG_OPOS funRegOpos = NULL;	   //函数指针  
	FUN_OPEN_OPOS funOpenOpos = NULL;	   //函数指针 
	FUN_CLOSE_OPOS funCloseOpos = NULL;	   //函数指针 

	char command_data = '0';

	//打开so文件  
	//为了方便演示,我将库文件和可执行文件放在同一个目录下  
	plib = dlopen("./libopos.so", RTLD_NOW | RTLD_GLOBAL);  
	if( NULL == plib )  
	error_quit("Can't open the libopos.so");  

	funRegOpos = dlsym(plib, "reg_opos");  
	if( NULL == funRegOpos )  
	error_quit("Can't load function 'reg_opos'"); 	

	funOpenOpos = dlsym(plib, "open_opos");  
	if( NULL == funOpenOpos )  
	error_quit("Can't load function 'open_opos'"); 

	funCloseOpos = dlsym(plib, "close_opos");  
	if( NULL == funCloseOpos )  
	error_quit("Can't load function 'close_opos'"); 


	//注册函数
	funRegOpos((void*)ShowBarcode);

	//打开opos
	funOpenOpos();	

	while(1)
	{
		scanf("%c",&command_data);

		if(command_data=='c')
		{
			printf("Close opos!\n");
			break;
		}
	}


	//关闭opos
	funCloseOpos();


	//关闭so文件  
	dlclose(plib);  

	printf("end!\n");

	return 0;
}

 

ubuntu终端运行:

命令1:gcc opos.c -fPIC -shared -o libopos.so -lpthread

作用:生成动态库文件 opos.c。

 

命令2:gcc main.c -o main -ldl

作用:编译main.c文件,调用了动态库,增加“-ldl”。

 

命令3:sudo ./main

作用:使用管理员权限运行main函数。

 

展示效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值