⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcommx.c~

📁 linux 内核版本2.6.18下的pmac运动控制卡驱动源程序
💻 C~
字号:
#include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <linux/pmacisa.h>#include <linux/errno.h>#include <pthread.h>#include "pcommx.h"////////////////////////////defines////////////////////////////////////////#define ISDEVICEOPEN(device)(pmac[device].count)////////////////////////////global variales///////////////////////////////struct Pmac_Comm_Device pmac[PMAC_NO];int devices_found = 0;////////////////////////////functions Implementation//////////////////////int find_pmac_devices(){	int device, result;	char pmac_isa_node[14]="/dev/pmacisa0\0";	char pmac_pci_node[14]="/dev/pmacpci0\0";	for(device = 0; device < PMAC_NO; device++){		pmac_isa_node[12] = devnos[device];		if((result=open(pmac_isa_node, O_RDWR)) >= 0){			strncpy(pmac[devices_found].dev_node, pmac_isa_node, 14);	//store the /dev entry of device found			devices_found++;	//found a device			close(result);		}	}	for(device = 0; device < PMAC_NO; device++){		pmac_pci_node[12] = devnos[device];		if(devices_found >= PMAC_NO)			break;		if((result=open(pmac_pci_node, O_RDWR)) >= 0){			strncpy(pmac[devices_found].dev_node, pmac_pci_node, 14);	//store the /dev entry of device found			devices_found++;	//found a device			close(result);		}	}	return devices_found;}	/*open_pmac_device() tries to open a device if its present in	  slot and is not in watch dog state. This requires device as	  integer, provided by calling application and returns 0 for	  successful operation, else returns a -ve status number.	  This function opens the device in BUS mode. Along with the	  close_pmac_device, this function keeps book keeping of the	  opened devices.	 */int open_pmac_device(int device){	int result;	if(!devices_found)		find_pmac_devices();	if(device>PMAC_NO)		return -ENODEV;	if(pmac[device].count==0){		if((result=open(pmac[device].dev_node, O_RDWR)) < 0)			return result;		else{			pmac[device].node = result;			pmac[device].progress = 0;			pmac[device].ascii_mode = BUS;   /**default mode is BUS */		}	}	pmac[device].count++;	return 0;}	/*close_pmac_device() closes any opened device previously opened by	 open_pmac_device(). If this device is opened by more than one applications	 the device will be close only after the last application requests for	 closing the device.On successful closure the function returns a 0.	 */int close_pmac_device(int device){	if(pmac[device].count==0)		close(pmac[device].node);	pmac[device].count--;	return 0;}int pmac_download_progress(int device){	return pmac[device].progress;}//////////////////////////////////////////////port functions//////////////////////////////////////	/*pmac_bus_get_line() communicates with device through the port. It requires device	 number as interger and a buffer to store the data sent by the device. On successful	 operation it returns the number of charcters sent by the device. On any error it	 returns the -ve number identifying the error.	 */int pmac_bus_get_line(int device, char *buf){	int result, len=0;	if(!ISDEVICEOPEN(device))		return -ENODEV;	while(pmac[device].ext.status!=COMM_EOT){		if(pmac[device].ext.status==COMM_ERROR){			pmac[device].read_error = COMM_ERROR;			break;		}		if(pmac[device].ext.status==COMM_TIMEOUT){			pmac_bus_send_line(device, "I3=2 I6=1 I63=1 I64=1");			pmac[device].read_error = COMM_TIMEOUT;			break;		}		result=ioctl(pmac[device].node, IOCTL_MOTION_READLN_PORT, &pmac[device].ext);		strncpy(buf+len, pmac[device].ext.buffer, result);		len+=result;	}	buf[len] = NULL_CHR;	pmac[device].ext.status = COMM_OK;	return len;}	/*pmac_bus_send_line() communicates with device through the port. It requires device	 number as interger and buffered data to be sent to the device. On successful operation	 it returns 0. On any error it returns the -ve number identifying the error.	 */int pmac_bus_send_line(int device, char *buf){	if(!ISDEVICEOPEN(device))		return -ENODEV;	strncpy(pmac[device].ext.buffer, buf, 256);	ioctl(pmac[device].node, IOCTL_MOTION_WRITELN_PORT, &pmac[device].ext);	return 0;}//////////////////////////////////////////dpram functions//////////////////////////////////////	/*pmac_dpr_get_line() communicates with device through the dpr. It requires device	 number as interger and a buffer to store the data sent by the pmac. On successful	 operation it returns the number of charcters sent by the device. On any error it	 returns the -ve number identifying the error.	 */int pmac_dpr_get_line(int device, char *buf){	int result, len=0;	if(!ISDEVICEOPEN(device))		return -ENODEV;	while(pmac[device].ext.status!=COMM_EOT){		if(pmac[device].ext.status==COMM_ERROR){			pmac[device].read_error = COMM_ERROR;			break;		}		if(pmac[device].ext.status==COMM_TIMEOUT){			pmac[device].read_error = COMM_TIMEOUT;			break;		}		result=ioctl(pmac[device].node, IOCTL_MOTION_READLN_MEM, &pmac[device].ext);		strncpy(buf+len, pmac[device].ext.buffer, result);		len+=result;	}	buf[len] = NULL_CHR;	pmac[device].ext.status = COMM_OK;	return len;}	/*pmac_dpr_send_line() communicates with device through the dpr. It requires device	 number as interger and buffered data to be sent to the device. On successful operation	 it returns 0. On any error it returns the -ve number identifying the error.	 */int pmac_dpr_send_line(int device, char *buf){	if(!ISDEVICEOPEN(device))		return -ENODEV;	strncpy(pmac[device].ext.buffer, buf, 256);	ioctl(pmac[device].node, IOCTL_MOTION_WRITELN_MEM, &pmac[device].ext);	return 0;}//////////////////////////////////////generic functions////////////////////////////////////////	/*pmac_read_ready() checks whether a particular device is ready to be read. It requires	 device number as integer of a previously opened device. On successful operation it	 returns a 0, else a -ve number identifing the error.	 */int pmac_read_ready(int device){	if(!ISDEVICEOPEN(device))		return -ENODEV;	switch(pmac[device].ascii_mode){		case BUS:			return ioctl(pmac[device].node, IOCTL_MOTION_PORT_READREADY);			break;		case DPR:			return ioctl(pmac[device].node, IOCTL_MOTION_MEM_READREADY);			break;	}	return 0;}	/*pmac_get_line() is the generic function to capture data from the device. It requires	 the device number as integer and a buffer space to hold the data sent by the device.	 Based on the previously set mode it either communicates through port or dpr. On	 successful operation it returns the number of characters read else a -ve number identifing	 the error.	 */int pmac_get_line(int device, char *buf){	int result;	if(!ISDEVICEOPEN(device))		return -ENODEV;	switch(pmac[device].ascii_mode){		case BUS:			result = pmac_bus_get_line(device, buf);			break;		case DPR:			result = pmac_dpr_get_line(device, buf);			break;	}	return result;}	/*pmac_send_line() is the generic function to send data to the device. It requires	 the device number as integer and buffered data to be sent to the device. Based on the	 previously set mode it either communicates through port or dpr. On successful operation	 it returns the number of characters read else a -ve number identifing the error.	*/int pmac_send_line(int device, char *buf){	int result;	if(!ISDEVICEOPEN(device))		return -ENODEV;	switch(pmac[device].ascii_mode){		case BUS:			result = pmac_bus_send_line(device, buf);			break;		case DPR:			result = pmac_dpr_send_line(device, buf);			break;	}	return result;}	/*pmac_get_response() is the generic function to commnicate with the device. It requires	 the device number as integer and a buffered data to be sent to the device. It saves the	 captured data sent by device in the same buffer. Based on the previously set mode it either	 communicates through port or dpr. On successful operation it returns the number of	 characters read else a -ve number identifing the error.	*/int pmac_get_response(int device, char *buf){	if(!ISDEVICEOPEN(device))		return -ENODEV;	pmac[device].ext.status = COMM_OK;	ioctl(pmac[device].node, IOCTL_MOTION_FLUSH_PORT);	ioctl(pmac[device].node, IOCTL_MOTION_FLUSH_MEM);	pmac_send_line(device, buf);	return pmac_get_line(device, buf);}	/*pmac_get_control_response() is the generic function to obtain the the device response of the	 control characters. It requires the device number as integer and buffered control character(s)	 to be sent to the device. It saves the captured response by device in the same buffer. Based	 on the previously set mode it either communicates through port or dpr. On successful operation	 it returns the number of characters read else a -ve number identifing the error.	*/int pmac_get_control_response(int device, char *buf){	int result;	if(!ISDEVICEOPEN(device))		return -ENODEV;	strncpy(pmac[device].ext.buffer, buf, 256);	switch(pmac[device].ascii_mode){		case BUS:			result = ioctl(pmac[device].node, IOCTL_MOTION_CTRLRESP_PORT, &pmac[device].ext);			break;		case DPR:			result = ioctl(pmac[device].node, IOCTL_MOTION_CTRLRESP_MEM, &pmac[device].ext);			break;	}	if(pmac[device].ext.status!=COMM_EOT)			result = pmac_get_line(device, buf);  //multiline response e.g ^I and ^E	else{		strncpy(buf, pmac[device].ext.buffer, result);		buf[result] = NULL_CHR;		pmac[device].ext.status = COMM_OK;	}	return result;}	/*pmac_set_ascii_comm() sets the mode of communication of a previously opened device. It	 requires the device number as integer and mode as ASCII_MODE. The legal values for ASCII_MODE	 as defined in pcommx.h are BUS and DPR. On successful operation it returns a 0 else a -ve	 number identifing the error.	 */int pmac_set_ascii_comm(int device, ASCII_MODE mode){	int i;	if(!ISDEVICEOPEN(device))		return -ENODEV;	if(mode==DPR){		i = ioctl(pmac[device].node, IOCTL_MOTION_DPRAM);		if(i){			pmac_send_line(device, "I58=1");			pmac[device].ascii_mode = DPR;		}else{			close_pmac_device(device);			return -ENODEV;		}	}else		pmac[device].ascii_mode = BUS;	return 0;}	/*pmac_download_file() downloads *.pmc file, a text file containing the configuration	 and motion programs, to the device. It requires device number as integer and a pointer	 to the file. This function may take time and while executing the application may not	 respond(A multithreaded version is underprogress). On successful operation it returns	 ACK else a -ve number identifing he error.	 */int pmac_download_file(int device, const char *fname){	FILE *fsrc;	int nc, lsent=0, result=0, line=0;	char instr[256], outstr[256], buf[MAX_COMM_BUFFER + 4];  // +4 to protect stack in case of dpr	long flen, fpos;	struct stat sbuf;	if(!ISDEVICEOPEN(device))		return -ENODEV;	if((fsrc = fopen(fname, "rt")) < 0 )		return -ENOENT;	if((fstat(fileno(fsrc), &sbuf)) < 0)		return;	flen = sbuf.st_size;	pmac[device].read_error = 0;	pmac_send_line(device, "close");	fseek(fsrc, 0, SEEK_SET);	while(!feof(fsrc)){		if(lsent){			result = pmac_get_line(device, buf);			if(pmac[device].read_error < 0)				return;			lsent = 0;		}else{			fgets(instr, 255, fsrc);			nc = 0;			while(nc < 256){				if(instr[nc] == '\0' || instr[nc] == ';' || instr[nc] == '\r'|| instr[nc] == '\n')					break;				else if(CTRL_A <= instr[nc] && instr[nc] <= CTRL_Z)					nc++;				else					outstr[nc] = instr[nc++];			}			outstr[nc] = '\0';			if(outstr[0] != '\0'){				pmac_send_line(device, outstr);				lsent = 1;			}			line++;			if(line % 5 == 0){				fpos = ftell(fsrc);				pmac[device].progress = (int) ((fpos* 100) /  flen) ;			}		}	}	fclose(fsrc);	return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -