mirror of
https://github.com/eddyem/BTA_utils.git
synced 2025-12-06 18:55:18 +03:00
Working version
This commit is contained in:
parent
db1c4eb8b6
commit
ce5767775d
211
BTA_modbusmeteo/olddaemon/CAN/can4linux.h
Normal file
211
BTA_modbusmeteo/olddaemon/CAN/can4linux.h
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* can4linux.h - can4linux CAN driver module
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2001 port GmbH Halle/Saale
|
||||||
|
*------------------------------------------------------------------
|
||||||
|
* $Header: /z2/cvsroot/products/0530/software/can4linux/src/can4linux.h,v 1.5 2004/05/14 10:02:54 oe Exp $
|
||||||
|
*
|
||||||
|
*--------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* modification history
|
||||||
|
* --------------------
|
||||||
|
* $Log: can4linux.h,v $
|
||||||
|
* Revision 1.5 2004/05/14 10:02:54 oe
|
||||||
|
* - started supporting CPC-Card
|
||||||
|
* - version number in can4linux.h available
|
||||||
|
* - only one structure type for Config_par_t Command_par_t
|
||||||
|
* - new ioctl command CMD_CLEARBUFFERS
|
||||||
|
*
|
||||||
|
* Revision 1.4 2003/08/27 17:49:04 oe
|
||||||
|
* - New CanStatusPar structure
|
||||||
|
*
|
||||||
|
* Revision 1.3 2002/08/20 05:57:22 oe
|
||||||
|
* - new write() handling, now not ovrwriting buffer content if buffer fill
|
||||||
|
* - ioctl() get status returns buffer information
|
||||||
|
*
|
||||||
|
* Revision 1.2 2002/08/08 17:50:46 oe
|
||||||
|
* - MSG_ERR_MASK extended
|
||||||
|
*
|
||||||
|
* Revision 1.1 2002/01/10 19:13:19 oe
|
||||||
|
* - application header file changed name can.h -> can4linux.h
|
||||||
|
*
|
||||||
|
* Revision 1.2 2001/09/14 14:58:09 oe
|
||||||
|
* first free release
|
||||||
|
*
|
||||||
|
* Revision 1.1.1.1 2001/06/11 18:30:54 oe
|
||||||
|
* minimal version can4linux embedded, compile time Konfigurierbar
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file can.h
|
||||||
|
* \author Heinz-Jürgen Oertel, port GmbH
|
||||||
|
* $Revision: 1.5 $
|
||||||
|
* $Date: 2004/05/14 10:02:54 $
|
||||||
|
*
|
||||||
|
* can4linux interface definitions
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CAN_H
|
||||||
|
#define __CAN_H
|
||||||
|
|
||||||
|
|
||||||
|
#define CAN4LINUXVERSION 0x0301 /*(Version 3.1)*/
|
||||||
|
|
||||||
|
#ifndef __KERNEL__
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
/*---------- the can message structure */
|
||||||
|
|
||||||
|
#define CAN_MSG_LENGTH 8 /**< maximum length of a CAN frame */
|
||||||
|
|
||||||
|
|
||||||
|
#define MSG_RTR (1<<0) /**< RTR Message */
|
||||||
|
#define MSG_OVR (1<<1) /**< CAN controller Msg overflow error */
|
||||||
|
#define MSG_EXT (1<<2) /**< extended message format */
|
||||||
|
#define MSG_PASSIVE (1<<4) /**< controller in error passive */
|
||||||
|
#define MSG_BUSOFF (1<<5) /**< controller Bus Off */
|
||||||
|
#define MSG_ (1<<6) /**< */
|
||||||
|
#define MSG_BOVR (1<<7) /**< receive/transmit buffer overflow */
|
||||||
|
/**
|
||||||
|
* mask used for detecting CAN errors in the canmsg_t flags field
|
||||||
|
*/
|
||||||
|
#define MSG_ERR_MASK (MSG_OVR + MSG_PASSIVE + MSG_BUSOFF + MSG_BOVR)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CAN message structure.
|
||||||
|
* Used for all data transfers between the application and the driver
|
||||||
|
* using read() or write().
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** flags, indicating or controlling special message properties */
|
||||||
|
int flags;
|
||||||
|
int cob; /**< CAN object number, used in Full CAN */
|
||||||
|
unsigned long id; /**< CAN message ID, 4 bytes */
|
||||||
|
struct timeval timestamp; /**< time stamp for received messages */
|
||||||
|
short int length; /**< number of bytes in the CAN message */
|
||||||
|
unsigned char data[CAN_MSG_LENGTH]; /**< data, 0...8 bytes */
|
||||||
|
} canmsg_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
---------- IOCTL requests */
|
||||||
|
|
||||||
|
#define COMMAND 0 /**< IOCTL command request */
|
||||||
|
#define CONFIG 1 /**< IOCTL configuration request */
|
||||||
|
#define SEND 2 /**< IOCTL request */
|
||||||
|
#define RECEIVE 3 /**< IOCTL request */
|
||||||
|
#define CONFIGURERTR 4 /**< IOCTL request */
|
||||||
|
#define STATUS 5 /**< IOCTL status request */
|
||||||
|
|
||||||
|
/*---------- CAN ioctl parameter types */
|
||||||
|
/**
|
||||||
|
IOCTL Command request parameter structure */
|
||||||
|
struct Command_par {
|
||||||
|
int cmd; /**< special driver command */
|
||||||
|
int target; /**< special configuration target */
|
||||||
|
unsigned long val1; /**< 1. parameter for the target */
|
||||||
|
unsigned long val2; /**< 2. parameter for the target */
|
||||||
|
int error; /**< return value */
|
||||||
|
unsigned long retval; /**< return value */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Command_par Command_par_t ;
|
||||||
|
/**
|
||||||
|
PSW made them all the same
|
||||||
|
IOCTL Configuration request parameter structure */
|
||||||
|
typedef struct Command_par Config_par_t ;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
IOCTL generic CAN controller status request parameter structure */
|
||||||
|
typedef struct CanStatusPar {
|
||||||
|
unsigned int baud; /**< actual bit rate */
|
||||||
|
unsigned int status; /**< CAN controller status register */
|
||||||
|
unsigned int error_warning_limit; /**< the error warning limit */
|
||||||
|
unsigned int rx_errors; /**< content of RX error counter */
|
||||||
|
unsigned int tx_errors; /**< content of TX error counter */
|
||||||
|
unsigned int error_code; /**< content of error code register */
|
||||||
|
unsigned int rx_buffer_size; /**< size of rx buffer */
|
||||||
|
unsigned int rx_buffer_used; /**< number of messages */
|
||||||
|
unsigned int tx_buffer_size; /**< size of tx buffer */
|
||||||
|
unsigned int tx_buffer_used; /**< number of messages */
|
||||||
|
unsigned long retval; /**< return value */
|
||||||
|
unsigned int type; /**< CAN controller / driver type */
|
||||||
|
} CanStatusPar_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
IOCTL CanStatusPar.type CAN controller hardware chips */
|
||||||
|
#define CAN_TYPE_UNSPEC 0
|
||||||
|
#define CAN_TYPE_SJA1000 1
|
||||||
|
#define CAN_TYPE_FlexCAN 2
|
||||||
|
#define CAN_TYPE_TouCAN 3
|
||||||
|
#define CAN_TYPE_82527 4
|
||||||
|
#define CAN_TYPE_TwinCAN 5
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
IOCTL Send request parameter structure */
|
||||||
|
typedef struct Send_par {
|
||||||
|
canmsg_t *Tx; /**< CAN message struct */
|
||||||
|
int error; /**< return value for errno */
|
||||||
|
unsigned long retval; /**< return value */
|
||||||
|
} Send_par_t ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
IOCTL Receive request parameter structure */
|
||||||
|
typedef struct Receive_par {
|
||||||
|
canmsg_t *Rx; /**< CAN message struct */
|
||||||
|
int error; /**< return value for errno */
|
||||||
|
unsigned long retval; /**< return value */
|
||||||
|
} Receive_par_t ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
IOCTL ConfigureRTR request parameter structure */
|
||||||
|
typedef struct ConfigureRTR_par {
|
||||||
|
unsigned message; /**< CAN message ID */
|
||||||
|
canmsg_t *Tx; /**< CAN message struct */
|
||||||
|
int error; /**< return value for errno */
|
||||||
|
unsigned long retval; /**< return value */
|
||||||
|
} ConfigureRTR_par_t ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
---------- IOCTL Command subcommands and there targets */
|
||||||
|
|
||||||
|
# define CMD_START 1
|
||||||
|
# define CMD_STOP 2
|
||||||
|
# define CMD_RESET 3
|
||||||
|
# define CMD_CLEARBUFFERS 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
---------- IOCTL Configure targets */
|
||||||
|
|
||||||
|
# define CONF_ACC 0 /* mask and code */
|
||||||
|
# define CONF_ACCM 1 /* mask only */
|
||||||
|
# define CONF_ACCC 2 /* code only */
|
||||||
|
# define CONF_TIMING 3 /* bit timing */
|
||||||
|
# define CONF_OMODE 4 /* output control register */
|
||||||
|
# define CONF_FILTER 5
|
||||||
|
# define CONF_FENABLE 6
|
||||||
|
# define CONF_FDISABLE 7
|
||||||
|
|
||||||
|
#endif /* __CAN_H */
|
||||||
548
BTA_modbusmeteo/olddaemon/CAN/can_io.c
Normal file
548
BTA_modbusmeteo/olddaemon/CAN/can_io.c
Normal file
@ -0,0 +1,548 @@
|
|||||||
|
/* CAN I/O library (to use as a process)
|
||||||
|
* usage:
|
||||||
|
* first: fork() + start_can_io(NULL) - start CAN Rx-buffering process
|
||||||
|
* then: fork() + Control_1(....) - start process that uses recv/send functions
|
||||||
|
* ...........................
|
||||||
|
* then: fork() + Control_N(....)
|
||||||
|
*
|
||||||
|
* note: use init_can_io() at the begining of every Control process
|
||||||
|
* BUT DON't USE it in main() before Control process start
|
||||||
|
* ^^^^^^^^^^^^^
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/shm.h>
|
||||||
|
|
||||||
|
#include "can4linux.h"
|
||||||
|
#include "can_io.h"
|
||||||
|
|
||||||
|
char can_dev[40] = "/dev/can0";
|
||||||
|
int can_fd=-1;
|
||||||
|
char can_lck[40] = "/tmp/dev_can0.lock";
|
||||||
|
int can_lk=-1;
|
||||||
|
static int server_mode=0;
|
||||||
|
static int my_uid;
|
||||||
|
|
||||||
|
#define CAN_SHM_SIZE ((sizeof(int)*3)+CAN_CTLR_SIZE+(CAN_RX_SIZE*sizeof(canmsg_t)))
|
||||||
|
|
||||||
|
union ShMkey {
|
||||||
|
char name[5];
|
||||||
|
key_t code;
|
||||||
|
} can_shm_key;
|
||||||
|
int can_shm_id=-1;
|
||||||
|
char *can_shm_addr = NULL;
|
||||||
|
#define can_pid (*(((int *)can_shm_addr)+0)) /* PID of CAN I/O process */
|
||||||
|
#define can_open (*(((int *)can_shm_addr)+1)) /* file descr.of CAN-driver */
|
||||||
|
#define rx_buff_pntr (*(((int *)can_shm_addr)+2)) /* from 0 till CAN_RX_SIZE-1 */
|
||||||
|
void *can_ctrl_addr = NULL; /* shm area reserved for control process purpose*/
|
||||||
|
canmsg_t *rx_buff; /* rx ring buffer: CAN_RX_SIZE*sizeof(canmsg_t)*/
|
||||||
|
|
||||||
|
struct CMD_Queue { /* ÏÐÉÓÁÎÉÅ ÏÞÅÒÅÄÉ (ËÁÎÁÌÁ) ËÏÍÁÎÄ */
|
||||||
|
union {
|
||||||
|
char name[5]; /* ËÌÀÞ ÉÄÅÎÔÅÆÉËÁÃÉÉ ÏÞÅÒÅÄÉ */
|
||||||
|
key_t code;
|
||||||
|
} key;
|
||||||
|
int mode; /* ÒÅÖÉÍ ÄÏÓÔÕÐÁ (rwxrwxrwx) */
|
||||||
|
int side; /* ÔÉÐ ÐÏÄÓÏÅÄÉÎÅÎÉÑ: ëÌÉÅÎÔ/óÅÒ×ÅÒ (Sender/Receiver)*/
|
||||||
|
int id; /* ÄÅÓËÒÉÐÔÏÒ ÐÏÄÓÏÅÄÉÎÅÎÉÑ */
|
||||||
|
unsigned int acckey; /* ËÌÀÞ ÄÏÓÔÕÐÁ (ÄÌÑ ÐÅÒÅÄÁÞÉ ëÌÉÅÎÔ->óÅÒ×ÅÒ) */
|
||||||
|
};
|
||||||
|
/* ËÁÎÁÌ ËÏÍÁÎÄ ÉÓÐÏÌØÚÕÅÍ ÄÌÑ ÐÅÒÅÄÁÞÉ CAN-ÆÒÅÊÍÏ× */
|
||||||
|
static struct CMD_Queue canout = {{'C','A','N',0,0},0200,0,-1,0};
|
||||||
|
|
||||||
|
/* ÓÔÒÕËÔÕÒÁ ÓÏÏÂÝÅÎÉÑ */
|
||||||
|
struct my_msgbuf {
|
||||||
|
long mtype; /* type of message */
|
||||||
|
unsigned long acckey; /* ËÌÀÞ ÄÏÓÔÕÐÁ ËÌÉÅÎÔÁ */
|
||||||
|
unsigned long src_pid; /* ÎÏÍÅÒ ÐÒÏÃÅÓÓÁ ÉÓÔÏÞÎÉËÁ */
|
||||||
|
unsigned long src_ip; /* IP-ÁÄÒ. ÉÓÔÏÞÎÉËÁ, =0 - ÌÏËÁÌØÎÁÑ ËÏÍÁÎÄÁ */
|
||||||
|
char mtext[100]; /* message text */
|
||||||
|
};
|
||||||
|
|
||||||
|
static void can_abort(int sig);
|
||||||
|
|
||||||
|
void set_server_mode(int mode) {server_mode=mode;}
|
||||||
|
int can_server() {return(server_mode);}
|
||||||
|
int can_card() {return(can_fd>0);}
|
||||||
|
int can_gate() {return(0);}
|
||||||
|
double can_gate_time_offset() {return(0.0);}
|
||||||
|
|
||||||
|
void setup_can_net(unsigned long ipaddr, int port, unsigned long acckey) {return;}
|
||||||
|
unsigned long get_acckey() {return(0);}
|
||||||
|
|
||||||
|
static int shm_created=0;
|
||||||
|
|
||||||
|
/* to use _AFTER_ process forking */
|
||||||
|
void *init_can_io() { /* returns shared area addr. for client control process*/
|
||||||
|
int i,ret;
|
||||||
|
int new_shm=0;
|
||||||
|
char *p, msg[100];
|
||||||
|
|
||||||
|
my_uid=geteuid();
|
||||||
|
if(can_shm_addr==NULL) {
|
||||||
|
if((p=strrchr(can_dev,'/'))!=NULL) {
|
||||||
|
memcpy(&can_lck[9], p+1, 4);
|
||||||
|
memcpy(can_shm_key.name, p+1, 4);
|
||||||
|
can_shm_key.name[4]='\0';
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"Wrong CAN device name: %s\n", can_dev);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
can_shm_id = shmget(can_shm_key.code, CAN_SHM_SIZE, 0644);
|
||||||
|
if(can_shm_id<0 && errno==EACCES)
|
||||||
|
can_shm_id = shmget(can_shm_key.code, CAN_SHM_SIZE, 0444);
|
||||||
|
if(can_shm_id<0 && errno==ENOENT && server_mode) {
|
||||||
|
can_shm_id = shmget(can_shm_key.code, CAN_SHM_SIZE, IPC_CREAT|IPC_EXCL|0644);
|
||||||
|
new_shm = shm_created = 1;
|
||||||
|
}
|
||||||
|
if(can_shm_id<0) {
|
||||||
|
can_prtime(stderr);
|
||||||
|
if(new_shm)
|
||||||
|
sprintf(msg,"Can't create shm CAN buffer '%s'",can_shm_key.name);
|
||||||
|
else if(server_mode)
|
||||||
|
sprintf(msg,"CAN-I/O: Can't find shm segment for CAN buffer '%s'",can_shm_key.name);
|
||||||
|
else
|
||||||
|
sprintf(msg,"Can't find shm segment for CAN buffer '%s' (maybe no CAN-I/O process?)",can_shm_key.name);
|
||||||
|
perror(msg);
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
can_shm_addr = shmat(can_shm_id, NULL, 0);
|
||||||
|
if ((int)(can_shm_addr) == -1 && errno==EACCES)
|
||||||
|
can_shm_addr = shmat(can_shm_id, NULL, SHM_RDONLY);
|
||||||
|
if ((int)(can_shm_addr) == -1) {
|
||||||
|
sprintf(msg,"Can't attach shm CAN buffer '%s'",can_shm_key.name);
|
||||||
|
perror(msg);
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
can_ctrl_addr = (canmsg_t *)(can_shm_addr+sizeof(int)*3);
|
||||||
|
rx_buff = (canmsg_t *)(can_ctrl_addr+CAN_CTLR_SIZE);
|
||||||
|
|
||||||
|
if(can_fd<0 && canout.id<0) {
|
||||||
|
if(server_mode) {
|
||||||
|
if(( can_fd = open(can_dev, O_RDWR )) < 0 ) {
|
||||||
|
sprintf(msg,"CAN-I/O: Error opening CAN device %s", can_dev);
|
||||||
|
can_prtime(stderr);
|
||||||
|
perror(msg);
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((canout.id = msgget(canout.key.code, canout.mode)) < 0) {
|
||||||
|
sprintf(msg,"Error opening CAN output queue '%s'(maybe no CANqueue server process?) ",canout.key.name);
|
||||||
|
perror(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(can_lk>0) close(can_lk);
|
||||||
|
if(( can_lk = open(can_lck, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH )) < 0 ) {
|
||||||
|
sprintf(msg,"Error opening CAN device lock-file %s", can_lck);
|
||||||
|
perror(msg);
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
close(can_fd);
|
||||||
|
exit(errno);
|
||||||
|
}
|
||||||
|
fchmod(can_lk, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
||||||
|
if(new_shm) {
|
||||||
|
struct timeval tmv;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&tmv,&tz);
|
||||||
|
if(flock(can_lk, LOCK_EX)<0) perror("locking CAN");
|
||||||
|
can_pid = 0;
|
||||||
|
can_open = -1;
|
||||||
|
rx_buff_pntr = 0;
|
||||||
|
for(i=0; i<CAN_RX_SIZE; i++) {
|
||||||
|
rx_buff[i].id = 0;
|
||||||
|
rx_buff[i].timestamp = tmv;
|
||||||
|
}
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
}
|
||||||
|
signal(SIGHUP, can_exit);
|
||||||
|
signal(SIGINT, can_exit);
|
||||||
|
signal(SIGQUIT,can_exit);
|
||||||
|
signal(SIGTERM,can_exit);
|
||||||
|
return(can_ctrl_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CAN "Rx to buff" process */
|
||||||
|
void *start_can_io(void *arg) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
set_server_mode(1);
|
||||||
|
init_can_io();
|
||||||
|
if(can_io_ok()) {
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"CAN I/O process(%d) already running!\n",can_pid);
|
||||||
|
sleep(1);
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"New CAN I/O process(%d) exiting...!\n",getpid());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
if( can_fd < 0 ) {
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"Error opening CAN device %s\n", can_dev);
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
can_pid = getpid();
|
||||||
|
can_open = can_fd;
|
||||||
|
|
||||||
|
signal(SIGHUP, can_abort);
|
||||||
|
signal(SIGINT, can_abort);
|
||||||
|
signal(SIGQUIT,can_abort);
|
||||||
|
signal(SIGFPE, can_abort);
|
||||||
|
signal(SIGPIPE,can_abort);
|
||||||
|
signal(SIGSEGV,can_abort);
|
||||||
|
signal(SIGALRM, SIG_IGN);
|
||||||
|
signal(SIGTERM,can_abort);
|
||||||
|
|
||||||
|
if((shmctl(can_shm_id, SHM_LOCK, NULL) < 0) < 0)
|
||||||
|
perror("CAN I/O: can't prevents swapping of Rx-buffer area");
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
int n;
|
||||||
|
canmsg_t rx;
|
||||||
|
|
||||||
|
if(!can_io_shm_ok()) {can_delay(0.3); continue;}
|
||||||
|
|
||||||
|
n = can_wait(can_fd, 0.3);
|
||||||
|
if(n < 0) sleep(1);
|
||||||
|
if(n <= 0) continue;
|
||||||
|
|
||||||
|
// do {
|
||||||
|
static struct timeval tm = {0,0};
|
||||||
|
n = read(can_fd, &rx, sizeof(canmsg_t));
|
||||||
|
if(n < 0)
|
||||||
|
perror("CAN Rx error");
|
||||||
|
else if(n > 0) {
|
||||||
|
/* work around the timestamp bug in old driver version */
|
||||||
|
while((double)rx.timestamp.tv_sec+(double)rx.timestamp.tv_usec/1e6 < (double)tm.tv_sec+(double)tm.tv_usec/1e6) {
|
||||||
|
rx.timestamp.tv_usec += 10000;
|
||||||
|
if(rx.timestamp.tv_usec > 1000000) {
|
||||||
|
rx.timestamp.tv_sec++;
|
||||||
|
rx.timestamp.tv_usec -= 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(flock(can_lk, LOCK_EX)<0) perror("locking CAN");
|
||||||
|
rx_buff[rx_buff_pntr] = rx;
|
||||||
|
rx_buff_pntr = (rx_buff_pntr + 1) % CAN_RX_SIZE;
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
//fprintf(stderr,"%d read(id=%02x,len=%d)\n",rx_buff_pntr,rx.id,rx.length);fflush(stderr);
|
||||||
|
/*fprintf(stderr,"reading CAN: 1 frame\n");*/
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,"reading CAN: nothing\n");fflush(stderr);
|
||||||
|
}
|
||||||
|
// } while(n>0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* put CAN-frame to recv-buffer */
|
||||||
|
void can_put_buff_frame(double rtime, int id, int length, unsigned char data[]) {
|
||||||
|
int i;
|
||||||
|
canmsg_t rx;
|
||||||
|
int sec = (int)rtime;
|
||||||
|
if(!server_mode) return;
|
||||||
|
if(length<0) length=0;
|
||||||
|
if(length>8) length=8;
|
||||||
|
rx.id=id;
|
||||||
|
rx.length=length;
|
||||||
|
for(i=0; i<length; i++) rx.data[i]=data[i];
|
||||||
|
rx.timestamp.tv_sec = sec;
|
||||||
|
rx.timestamp.tv_usec = (int)((rtime-sec)*1000000.);
|
||||||
|
if(flock(can_lk, LOCK_EX)<0) perror("locking CAN");
|
||||||
|
rx_buff[rx_buff_pntr] = rx;
|
||||||
|
rx_buff_pntr = (rx_buff_pntr + 1) % CAN_RX_SIZE;
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ÷ÓÅ ÎÏÒÍÁÌØÎÏ Ó SHM-ÂÕÆÅÒÏÍ CAN-I/O ÐÒÏÃÅÓÓÁ */
|
||||||
|
int can_io_shm_ok() {
|
||||||
|
return(can_pid>0 && can_open>0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ÷ÓÅ ÎÏÒÍÁÌØÎÏ Ó CAN-I/O ÐÒÏÃÅÓÓÏÍ */
|
||||||
|
/* (ÎÏ ÎÁÄÏ ÂÙÔØ ÓÕÐÅÒ-ÀÚÅÒÏÍ!) */
|
||||||
|
int can_io_ok() {
|
||||||
|
return(can_io_shm_ok() && (my_uid!=0||kill(can_pid, 0)==0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ÷ÏÚÍÏÖÎÁ ÒÁÂÏÔÁ c CAN ÄÌÑ ËÌÉÅÎÔÁ */
|
||||||
|
int can_ok() {
|
||||||
|
return(can_io_shm_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* wait for CAN-frame */
|
||||||
|
int can_wait(int fd, double tout)
|
||||||
|
{
|
||||||
|
int nfd,width;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set readfds;
|
||||||
|
|
||||||
|
if(fd==0 && tout>=0.01) {
|
||||||
|
double dt = can_dsleep(tout);
|
||||||
|
if(dt>0.) can_dsleep(dt);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
if(fd<0) fd=can_fd;
|
||||||
|
if(fd>0) {
|
||||||
|
FD_ZERO(&readfds);
|
||||||
|
FD_SET(fd, &readfds);
|
||||||
|
width = fd+1;
|
||||||
|
} else
|
||||||
|
width = 0;
|
||||||
|
tv.tv_sec = (int)tout;
|
||||||
|
tv.tv_usec = (int)((tout - tv.tv_sec)*1000000.+0.9);
|
||||||
|
slipping:
|
||||||
|
if(fd>0 && can_fd>0)
|
||||||
|
nfd = select(width, &readfds, (fd_set *)NULL, (fd_set *)NULL, &tv);
|
||||||
|
else
|
||||||
|
nfd = select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &tv);
|
||||||
|
if(nfd < 0) {
|
||||||
|
if(errno == EINTR)
|
||||||
|
goto slipping;
|
||||||
|
perror("Error in can_wait(){ select() }");
|
||||||
|
return(-1);
|
||||||
|
} else if(nfd == 0) /* timeout! */
|
||||||
|
return(0);
|
||||||
|
if(fd>0 && FD_ISSET(fd, &readfds)) /* Rx frame! */
|
||||||
|
return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleanup recv-buffer in client process */
|
||||||
|
void can_clean_recv(int *pbuf, double *rtime) {
|
||||||
|
struct timeval tmv;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&tmv,&tz);
|
||||||
|
*pbuf = rx_buff_pntr;
|
||||||
|
*rtime = tmv.tv_sec + (double)tmv.tv_usec/1000000.;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find next rx-frame in recv-buffer for client process */
|
||||||
|
int can_recv_frame(int *pbuf, double *rtime,
|
||||||
|
int *id, int *length, unsigned char data[]) {
|
||||||
|
return(can_get_buff_frame(pbuf, rtime, id, length, data));
|
||||||
|
}
|
||||||
|
int can_get_buff_frame(int *pbuf, double *rtime,
|
||||||
|
int *id, int *length, unsigned char data[]) {
|
||||||
|
while(*pbuf != rx_buff_pntr) {
|
||||||
|
canmsg_t *rx = &rx_buff[*pbuf];
|
||||||
|
struct timeval *tv = &rx->timestamp;
|
||||||
|
double t_rx;
|
||||||
|
|
||||||
|
if(flock(can_lk, LOCK_EX)<0) perror("locking CAN");
|
||||||
|
|
||||||
|
t_rx = tv->tv_sec + (double)tv->tv_usec/1000000.;
|
||||||
|
if(t_rx+1. >= *rtime) {
|
||||||
|
int i;
|
||||||
|
*id = rx->id;
|
||||||
|
*length = rx->length;
|
||||||
|
for(i = 0; i < *length; i++)
|
||||||
|
data[i] = rx->data[i];
|
||||||
|
*rtime = t_rx;
|
||||||
|
*pbuf = (*pbuf + 1) % CAN_RX_SIZE;
|
||||||
|
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
*pbuf = (*pbuf + 1) % CAN_RX_SIZE;
|
||||||
|
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send tx-frame from client process */
|
||||||
|
/* to CAN-driver or to output queue */
|
||||||
|
int can_send_frame(int id, int length, unsigned char data[]) {
|
||||||
|
int i, ret=1;
|
||||||
|
if(can_fd<0 && canout.id<0)
|
||||||
|
return(0);
|
||||||
|
if(length>8) length=8;
|
||||||
|
if(length<0) length=0;
|
||||||
|
if(can_fd>=0) {
|
||||||
|
canmsg_t tx;
|
||||||
|
tx.id=id;
|
||||||
|
tx.cob=0;
|
||||||
|
tx.flags=0;
|
||||||
|
tx.length=length;
|
||||||
|
for(i=0;i<length;i++) tx.data[i]=data[i];
|
||||||
|
if(flock(can_lk, LOCK_EX)<0) perror("locking CAN");
|
||||||
|
ret = write(can_fd, &tx, sizeof(canmsg_t));
|
||||||
|
if(flock(can_lk, LOCK_UN)<0) perror("unlocking CAN");
|
||||||
|
if(server_mode)
|
||||||
|
/* copy tx CAN-frame back to recv-buffer */
|
||||||
|
can_put_buff_frame(can_dtime(), id, length, data);
|
||||||
|
} else if(canout.id>=0) {
|
||||||
|
struct my_msgbuf mbuf;
|
||||||
|
mbuf.src_pid = getpid();
|
||||||
|
mbuf.src_ip = 0;
|
||||||
|
mbuf.acckey = canout.acckey;
|
||||||
|
mbuf.mtype = id;
|
||||||
|
for(i=0;i<length;i++) mbuf.mtext[i]=data[i];
|
||||||
|
msgsnd( canout.id, (struct msgbuf *)&mbuf, length+12, IPC_NOWAIT);
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void can_abort(int sig) {
|
||||||
|
int ret;
|
||||||
|
char ss[10];
|
||||||
|
struct shmid_ds buf;
|
||||||
|
|
||||||
|
if(sig) signal(sig,SIG_IGN);
|
||||||
|
if(!server_mode) can_exit(sig);
|
||||||
|
switch (sig) {
|
||||||
|
case 0 : strcpy(ss," "); break;
|
||||||
|
case SIGHUP : strcpy(ss,"SIGHUP -"); break;
|
||||||
|
case SIGINT : strcpy(ss,"SIGINT -"); break;
|
||||||
|
case SIGQUIT: strcpy(ss,"SIGQUIT -"); break;
|
||||||
|
case SIGFPE : strcpy(ss,"SIGFPE -"); break;
|
||||||
|
case SIGPIPE: strcpy(ss,"SIGPIPE -"); break;
|
||||||
|
case SIGSEGV: strcpy(ss,"SIGSEGV -"); break;
|
||||||
|
case SIGTERM: strcpy(ss,"SIGTERM -"); break;
|
||||||
|
default: sprintf(ss,"SIG_%d -",sig); break;
|
||||||
|
}
|
||||||
|
switch (sig) {
|
||||||
|
default:
|
||||||
|
case SIGHUP :
|
||||||
|
case SIGINT :
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"CAN I/O: %s Ignore .....\n",ss);
|
||||||
|
fflush(stderr);
|
||||||
|
signal(sig, can_abort);
|
||||||
|
return;
|
||||||
|
case SIGPIPE:
|
||||||
|
case SIGQUIT:
|
||||||
|
case SIGFPE :
|
||||||
|
case SIGSEGV:
|
||||||
|
case SIGTERM:
|
||||||
|
signal(SIGALRM, can_abort);
|
||||||
|
alarm(2);
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"CAN I/O: %s process should stop after 2sec delay...\n",ss);
|
||||||
|
fflush(stderr);
|
||||||
|
close(can_fd);
|
||||||
|
can_fd = can_open = -1;
|
||||||
|
return;
|
||||||
|
case SIGALRM:
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"CAN I/O: process stop!\n");
|
||||||
|
fflush(stderr);
|
||||||
|
close(can_lk);
|
||||||
|
can_lk = -1;
|
||||||
|
can_pid = 0;
|
||||||
|
ret=shmdt(can_shm_addr);
|
||||||
|
ret=shmctl(can_shm_id, IPC_STAT, &buf);
|
||||||
|
if(buf.shm_nattch==0) {
|
||||||
|
ret=shmctl(can_shm_id, SHM_UNLOCK, NULL);
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
}
|
||||||
|
exit(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void can_exit(int sig) {
|
||||||
|
int ret;
|
||||||
|
char ss[10];
|
||||||
|
|
||||||
|
struct shmid_ds buf;
|
||||||
|
if(sig) signal(sig,SIG_IGN);
|
||||||
|
if(server_mode) can_abort(sig);
|
||||||
|
switch (sig) {
|
||||||
|
case 0 : strcpy(ss,"Exiting - "); break;
|
||||||
|
case SIGHUP : strcpy(ss,"SIGHUP -"); break;
|
||||||
|
case SIGINT : strcpy(ss,"SIGINT -"); break;
|
||||||
|
case SIGQUIT: strcpy(ss,"SIGQUIT -"); break;
|
||||||
|
case SIGFPE : strcpy(ss,"SIGFPE -"); break;
|
||||||
|
case SIGPIPE: strcpy(ss,"SIGPIPE -"); break;
|
||||||
|
case SIGSEGV: strcpy(ss,"SIGSEGV -"); break;
|
||||||
|
case SIGTERM: strcpy(ss,"SIGTERM -"); break;
|
||||||
|
default: sprintf(ss,"SIG_%d -",sig); break;
|
||||||
|
}
|
||||||
|
switch (sig) {
|
||||||
|
default:
|
||||||
|
case SIGHUP :
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"%s Ignore .....\n",ss);
|
||||||
|
fflush(stderr);
|
||||||
|
signal(sig, can_exit);
|
||||||
|
return;
|
||||||
|
case 0:
|
||||||
|
case SIGINT :
|
||||||
|
case SIGPIPE:
|
||||||
|
case SIGQUIT:
|
||||||
|
case SIGFPE :
|
||||||
|
case SIGSEGV:
|
||||||
|
case SIGTERM:
|
||||||
|
if(can_fd>=0) close(can_fd);
|
||||||
|
can_prtime(stderr);
|
||||||
|
fprintf(stderr,"%s process stop!\n",ss);
|
||||||
|
fflush(stderr);
|
||||||
|
close(can_lk);
|
||||||
|
ret=shmdt(can_shm_addr);
|
||||||
|
ret=shmctl(can_shm_id, IPC_STAT, &buf);
|
||||||
|
if(buf.shm_nattch==0)
|
||||||
|
ret=shmctl(can_shm_id, IPC_RMID, NULL);
|
||||||
|
exit(sig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *time2asc(double t)
|
||||||
|
{
|
||||||
|
static char stmp[10][20];
|
||||||
|
static int itmp=0;
|
||||||
|
char *lin = stmp[itmp];
|
||||||
|
int h, min;
|
||||||
|
double sec;
|
||||||
|
h = (int)(t/3600.);
|
||||||
|
min = (int)((t - (double)h*3600.)/60.);
|
||||||
|
sec = t - (double)h*3600. - (double)min*60.;
|
||||||
|
h %= 24;
|
||||||
|
sprintf(lin, "%02d:%02d:%09.6f", h,min,sec);
|
||||||
|
itmp = (itmp+1)%10;
|
||||||
|
return lin;
|
||||||
|
}
|
||||||
|
|
||||||
|
double can_dsleep(double dt) {
|
||||||
|
struct timespec ts,tsr;
|
||||||
|
ts.tv_sec = (time_t)dt;
|
||||||
|
ts.tv_nsec = (long)((dt-ts.tv_sec)*1e9);
|
||||||
|
nanosleep(&ts,&tsr);
|
||||||
|
return((double)ts.tv_sec + (double)ts.tv_nsec/1e9);
|
||||||
|
}
|
||||||
|
|
||||||
|
double can_dtime() {
|
||||||
|
struct timeval ct;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&ct, &tz);
|
||||||
|
return ((double)ct.tv_sec + (double)ct.tv_usec/1e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *can_atime() {return(time2asc(can_dtime()));}
|
||||||
|
|
||||||
|
void can_prtime(FILE *fd) {
|
||||||
|
static double otime=0.0;
|
||||||
|
double ntime=can_dtime();
|
||||||
|
time_t itime = (int)ntime;
|
||||||
|
if(otime==0.0) tzset();
|
||||||
|
ntime -= (double)timezone;
|
||||||
|
if((((int)ntime)%(24*3600) < ((int)otime)%(24*3600)) || otime==0.0)
|
||||||
|
fprintf(fd,"========================\n%s",ctime(&itime));
|
||||||
|
fprintf(fd,"%s ",time2asc(ntime));
|
||||||
|
otime=ntime;
|
||||||
|
}
|
||||||
30
BTA_modbusmeteo/olddaemon/CAN/can_io.h
Normal file
30
BTA_modbusmeteo/olddaemon/CAN/can_io.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#define CAN_CTLR_SIZE 300 /* size of client process shared area */
|
||||||
|
#define CAN_RX_SIZE 1000 /* max. # frames in Rx-buffer */
|
||||||
|
|
||||||
|
int can_wait(int fd, double tout);
|
||||||
|
#define can_delay(Tout) can_wait(0, Tout)
|
||||||
|
void set_server_mode(int mode);
|
||||||
|
int can_server();
|
||||||
|
int can_card();
|
||||||
|
int can_gate();
|
||||||
|
double can_gate_time_offset();
|
||||||
|
void setup_can_net(unsigned long ipaddr, int port, unsigned long acckey);
|
||||||
|
unsigned long get_acckey();
|
||||||
|
void *init_can_io();
|
||||||
|
void *start_can_io(void *arg);
|
||||||
|
void can_put_buff_frame(double rtime, int id, int length, unsigned char data[]);
|
||||||
|
int can_io_ok();
|
||||||
|
int can_io_shm_ok();
|
||||||
|
int can_ok();
|
||||||
|
void can_clean_recv(int *pbuf, double *rtime);
|
||||||
|
int can_get_buff_frame(int *pbuf, double *rtime,
|
||||||
|
int *id, int *length, unsigned char data[]);
|
||||||
|
int can_recv_frame(int *pbuf, double *rtime,
|
||||||
|
int *id, int *length, unsigned char data[]);
|
||||||
|
int can_send_frame(int id, int length, unsigned char data[]);
|
||||||
|
void can_exit(int sig);
|
||||||
|
char *time2asc(double t);
|
||||||
|
double can_dsleep(double dt);
|
||||||
|
double can_dtime();
|
||||||
|
char *can_atime();
|
||||||
|
void can_prtime(FILE *fd);
|
||||||
7
BTA_modbusmeteo/olddaemon/Makefile
Normal file
7
BTA_modbusmeteo/olddaemon/Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CFLAGS=-g
|
||||||
|
|
||||||
|
bta_meteo_can: bta_meteo_can.c bta_shdata.h CAN/can_io.h CAN/can_io.o
|
||||||
|
cc -g bta_meteo_can.c CAN/can_io.o -lcrypt -o bta_meteo_can
|
||||||
|
# setroot bta_meteo_can
|
||||||
|
|
||||||
|
CAN/can_io.o: CAN/can_io.c CAN/can_io.h CAN/can4linux.h
|
||||||
309
BTA_modbusmeteo/olddaemon/bta_meteo_can.c
Normal file
309
BTA_modbusmeteo/olddaemon/bta_meteo_can.c
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
/* ðÏÌÕÞÅÎÉÅ ÍÅÔÅÏ-ÄÁÎÎÙÈ ÏÔ PEP-ËÏÎÔÒÏÌÌÅÒÏ× ÐÏ CAN-ÛÉÎÅ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <termio.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#include "bta_shdata.h"
|
||||||
|
#include "CAN/can_io.h"
|
||||||
|
|
||||||
|
const double zeroV = 1.0;
|
||||||
|
const double scaleT = 50.0/(5.-1.); /* New: 1:5V -> -20:+30dgr */
|
||||||
|
const double zeroT2 = -19.1; /* -20.0 + 0.9 Tind (16.11.2012)*/
|
||||||
|
|
||||||
|
static int stop_prog = 0;
|
||||||
|
static char *myname;
|
||||||
|
|
||||||
|
static void print_date(FILE *fdout) {
|
||||||
|
static char lastdate[40] = "01.01.2000 00:00:00";
|
||||||
|
const char *formdate = "%d.%m.%Y %H:%M:%S";
|
||||||
|
time_t t;
|
||||||
|
struct tm *tm;
|
||||||
|
char currdate[40];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
time(&t);
|
||||||
|
tm = localtime(&t);
|
||||||
|
len = strftime(currdate,40,formdate,tm);
|
||||||
|
if(strncmp(lastdate,currdate,11)==0)
|
||||||
|
fprintf(fdout,"%s ", &currdate[11]);
|
||||||
|
else
|
||||||
|
fprintf(fdout,"Date: %s ", currdate);
|
||||||
|
|
||||||
|
strncpy(lastdate,currdate,20);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fprtime(FILE *fd) { can_prtime(fd); }
|
||||||
|
|
||||||
|
static double dsleep(double dt) {
|
||||||
|
struct timespec ts,tsr;
|
||||||
|
ts.tv_sec = (time_t)dt;
|
||||||
|
ts.tv_nsec = (long)((dt-ts.tv_sec)*1e9);
|
||||||
|
nanosleep(&ts,&tsr);
|
||||||
|
return((double)ts.tv_sec + (double)ts.tv_nsec/1e9);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double dtime() {
|
||||||
|
struct timeval ct;
|
||||||
|
struct timezone tz;
|
||||||
|
gettimeofday(&ct, &tz);
|
||||||
|
return (ct.tv_sec + ct.tv_usec/1e6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void myabort(int sig) {
|
||||||
|
int ret;
|
||||||
|
char ss[10], tmp[80];
|
||||||
|
signal(sig,SIG_IGN);
|
||||||
|
switch (sig) {
|
||||||
|
case SIGHUP : strcpy(ss,"SIGHUP"); break;
|
||||||
|
case SIGINT : strcpy(ss,"SIGINT"); break;
|
||||||
|
case SIGQUIT: strcpy(ss,"SIGQUIT"); break;
|
||||||
|
case SIGFPE : strcpy(ss,"SIGFPE"); break;
|
||||||
|
case SIGPIPE: strcpy(ss,"SIGPIPE"); break;
|
||||||
|
case SIGSEGV: strcpy(ss,"SIGSEGV"); break;
|
||||||
|
case SIGTERM: strcpy(ss,"SIGTERM"); break;
|
||||||
|
default: sprintf(ss,"SIG_%d",sig); break;
|
||||||
|
}
|
||||||
|
print_date(stderr);
|
||||||
|
switch (sig) {
|
||||||
|
default:
|
||||||
|
|
||||||
|
case SIGHUP :
|
||||||
|
case SIGINT :
|
||||||
|
fprintf(stderr,"%s: %s - Ignore .....\n",myname,ss);
|
||||||
|
fflush(stderr);
|
||||||
|
signal(sig, myabort);
|
||||||
|
return;
|
||||||
|
case SIGPIPE:
|
||||||
|
case SIGQUIT:
|
||||||
|
case SIGFPE :
|
||||||
|
case SIGSEGV:
|
||||||
|
case SIGTERM:
|
||||||
|
signal(SIGALRM, SIG_IGN);
|
||||||
|
fprintf(stderr,"%s: %s - programm stop!\n",myname,ss);
|
||||||
|
fflush(stderr);
|
||||||
|
stop_prog = sig;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rxpnt;
|
||||||
|
static double rxtime;
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
double tcurr, tlast, tok, twndok;
|
||||||
|
char msg[60];
|
||||||
|
double t0=0., t;
|
||||||
|
int i,m,n, idr, idt, dlen, start=0, imsg;
|
||||||
|
unsigned char rdata[8],tdata[8];
|
||||||
|
char tmp[100],tmp1[100], pmsg[48], *pmsgp;
|
||||||
|
|
||||||
|
myname = argv[0];
|
||||||
|
tzset();
|
||||||
|
print_date(stderr);
|
||||||
|
sdat.mode |= 0200;
|
||||||
|
sdat.atflag = 0;
|
||||||
|
get_shm_block( &sdat, ClientSide);
|
||||||
|
get_cmd_queue( &ocmd, ClientSide);
|
||||||
|
|
||||||
|
MeteoMode &= ~SENSOR_T2;
|
||||||
|
|
||||||
|
init_can_io();
|
||||||
|
can_clean_recv(&rxpnt, &rxtime);
|
||||||
|
fprintf(stderr,"\n");
|
||||||
|
|
||||||
|
signal(SIGHUP, myabort);
|
||||||
|
signal(SIGINT, myabort);
|
||||||
|
signal(SIGQUIT,myabort);
|
||||||
|
signal(SIGFPE, myabort);
|
||||||
|
signal(SIGPIPE,myabort);
|
||||||
|
signal(SIGSEGV,myabort);
|
||||||
|
signal(SIGTERM,myabort);
|
||||||
|
|
||||||
|
imsg=0;
|
||||||
|
pmsgp=pmsg;
|
||||||
|
|
||||||
|
t0 = tcurr = tlast = tok = twndok = dtime();
|
||||||
|
tok -= 600.;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
char *pep = "RK";
|
||||||
|
int nch = 0;
|
||||||
|
dsleep(0.2);
|
||||||
|
tcurr = dtime();
|
||||||
|
if(PEP_A_On && PEP_R_On) {
|
||||||
|
if(!stop_prog && !start && tcurr-tok>15.) {
|
||||||
|
idt = 0x447;
|
||||||
|
dlen=6;
|
||||||
|
tdata[0] = 7;
|
||||||
|
tdata[2] = 50; /* 0.5s */
|
||||||
|
tdata[3] = 1;
|
||||||
|
tdata[4] = 0; tdata[5] = 50; /* 0.5s */
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
if(i==2||i==3||i==5||i==6) /* T-ÚÅÒËÁÌÁ, ×ÅÔÅÒ, ×ÌÁÖÎÏÓÔØ, T ÎÁ ÍÅÔÅÏ-ÍÁÞÔÅ */
|
||||||
|
continue; /* ÐÏËÁ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ (ÚÁÍÅÎÅÎÙ) */
|
||||||
|
if(i==4) { /*×ÒÅÍÅÎÎÏ: ÐÏËÁ áãð4 ÉÄÅÔ Ó PEP-A (ÄÁ×ÌÅÎÉÅ)*/
|
||||||
|
pep = "A";
|
||||||
|
idt = 0x40f; /* PEP-A */
|
||||||
|
tdata[1] = nch = 4; /* áãð/4 */
|
||||||
|
} else {
|
||||||
|
pep = "RK";
|
||||||
|
idt = 0x447; /* PEP-RK */
|
||||||
|
tdata[1] = nch = i; /* áãð/i */
|
||||||
|
}
|
||||||
|
print_date(stderr);
|
||||||
|
if(can_send_frame(idt, dlen, tdata)<=0) {
|
||||||
|
fprintf(stderr,"Can't send command \"Start ADC%d\" to PEP-%s!\n",nch,pep);
|
||||||
|
} else if(tcurr-tlast<70.)
|
||||||
|
fprintf(stderr,"Send command \"Start ADC%d\" to PEP-%s.\n",nch,pep);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
start=1;
|
||||||
|
tok = tcurr;
|
||||||
|
}
|
||||||
|
if(stop_prog || (start && tcurr-tok>5.)) {
|
||||||
|
if(!stop_prog) {
|
||||||
|
print_date(stderr);
|
||||||
|
fprintf(stderr,"PEP-RK: ADC(0,1,7) (or PEP-A ADC4) timeout!\n");
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
MeteoMode &= ~SENSOR_T2;
|
||||||
|
idt = 0x447;
|
||||||
|
dlen=6;
|
||||||
|
tdata[0] = 7;
|
||||||
|
tdata[2] = tdata[3] = tdata[4] = tdata[5] = 0;
|
||||||
|
for(i=0; i<8; i++) {
|
||||||
|
if(i==2||i==3||i==5||i==6) /* T-ÚÅÒËÁÌÁ, ×ÅÔÅÒ, ×ÌÁÖÎÏÓÔØ, T ÎÁ ÍÅÔÅÏ-ÍÁÞÔÅ */
|
||||||
|
continue; /* ÐÏËÁ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ (ÚÁÍÅÎÅÎÙ) */
|
||||||
|
if(i==4) { /*×ÒÅÍÅÎÎÏ: ÐÏËÁ áãð4 ÉÄÅÔ Ó PEP-A (ÄÁ×ÌÅÎÉÅ)*/
|
||||||
|
pep = "A";
|
||||||
|
idt = 0x40f; /* PEP-A */
|
||||||
|
tdata[1] = nch = 4; /* áãð/4 */
|
||||||
|
} else {
|
||||||
|
pep = "RK";
|
||||||
|
idt = 0x447; /* PEP-RK */
|
||||||
|
tdata[1] = nch = i; /* áãð/i */
|
||||||
|
}
|
||||||
|
print_date(stderr);
|
||||||
|
if(can_send_frame(idt, dlen, tdata)<=0) {
|
||||||
|
fprintf(stderr,"Can't send command \"Stop ADC%d\" to PEP-%s!\n",nch,pep);
|
||||||
|
} else if(tcurr-tlast<70.)
|
||||||
|
fprintf(stderr,"Send command \"Stop ADC%d\" to PEP-%s.\n",nch,pep);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(stop_prog) can_exit(0);
|
||||||
|
start=0;
|
||||||
|
tok = tcurr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(stop_prog) can_exit(0);
|
||||||
|
else {
|
||||||
|
static int tpr = 0;
|
||||||
|
if(tcurr-tpr>600.) {
|
||||||
|
if(PEP_R_Off) {
|
||||||
|
print_date(stderr);
|
||||||
|
fprintf(stderr,"PEP-RK (ADC0/1/7) turned off!\n");
|
||||||
|
}
|
||||||
|
if(PEP_A_Off) {
|
||||||
|
print_date(stderr);
|
||||||
|
fprintf(stderr,"PEP-A (ADC4) turned off!\n");
|
||||||
|
}
|
||||||
|
tpr=tcurr;
|
||||||
|
}
|
||||||
|
if(PEP_R_Off) {
|
||||||
|
if((MeteoMode & NET_T2)==0)
|
||||||
|
MeteoMode &= ~SENSOR_T2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(can_recv_frame(&rxpnt, &rxtime, &idr, &dlen, rdata)) {
|
||||||
|
int rcode = 0;
|
||||||
|
t = rxtime;
|
||||||
|
if(idr==0x447||idr==0x40f) {
|
||||||
|
pep = (idr==0x40f)? "A" : "RK";
|
||||||
|
if(rdata[0]==7) {
|
||||||
|
if(rdata[2] == 0 && rdata[3] == 0)
|
||||||
|
fprintf(stderr,"%s PEP-%s: Echo command \"Stop ADC%d\"\n", time2asc(rxtime-timezone),pep,rdata[1]);
|
||||||
|
else
|
||||||
|
fprintf(stderr,"%s PEP-%s: Echo command \"Start ADC%d\"\n", time2asc(rxtime-timezone),pep,rdata[1]);
|
||||||
|
} else if(rdata[0]==8) {
|
||||||
|
fprintf(stderr,"%s PEP-%s: Echo command \"Stop all ADC\"\n", time2asc(rxtime-timezone),pep);
|
||||||
|
start=0;
|
||||||
|
}
|
||||||
|
fflush(stderr);
|
||||||
|
} else if(idr==0x20c) { /* ×ÒÅÍÅÎÎÏ: ËÏÄ áãð4 PEP-A - ÄÁ×ÌÅÎÉÅ */
|
||||||
|
if(dlen!=3)
|
||||||
|
goto wrong_frame;
|
||||||
|
idr = 0x224; /* ×ÒÅÍÅÎÎÏ: ÉÍÉÔÁÃÉÑ áãð4 PEP-RK */
|
||||||
|
goto adc_pep_rk;
|
||||||
|
} else if((idr&0xff8)==0x220) { /* ËÏÄ ÏÔ áãð PEP-RK */
|
||||||
|
static double T2 = 0.;
|
||||||
|
static int ctm=0;
|
||||||
|
static int terr=0;
|
||||||
|
int chan, code;
|
||||||
|
double volt,T,b,w,h;
|
||||||
|
adc_pep_rk:
|
||||||
|
if(dlen!=3) {
|
||||||
|
static double last_print = 0.;
|
||||||
|
wrong_frame:
|
||||||
|
if(tcurr-last_print > 60.) {
|
||||||
|
print_date(stderr);
|
||||||
|
fprintf(stderr,"Wrong CAN-frame id=0x%x len=%d < ",idr,dlen);
|
||||||
|
for(i=0; i<dlen; i++) fprintf(stderr,"%02x ",rdata[i]);
|
||||||
|
fprintf(stderr,">\n");
|
||||||
|
fflush(stderr);
|
||||||
|
last_print = tcurr;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
chan = idr&7;
|
||||||
|
code = (unsigned int)rdata[0]<<8|rdata[1];
|
||||||
|
volt = (double)code/4096.*5.; /* ADC 12bit 0-5V */
|
||||||
|
if(chan == 1){ /* áãð1 - T-ÐÏÄËÕÐÏÌØÎÏÇÏ */
|
||||||
|
ctm |= 2; /* áãð1 - T-ÐÏÄËÕÐÏÌØÎÏÇÏ */
|
||||||
|
T = zeroT2 + (volt-zeroV)*scaleT;
|
||||||
|
/*t2=T;*/
|
||||||
|
if(T >= -20. && T <= 30.) {
|
||||||
|
if((MeteoMode & SENSOR_T2) && fabs(T2-T)<5.) {
|
||||||
|
if(fabs(T2-T)>0.1)
|
||||||
|
T2 += (T2>T)? -0.005 : 0.005;
|
||||||
|
else
|
||||||
|
T2 = 0.9*T2 + 0.1*T;
|
||||||
|
} else {
|
||||||
|
T2=T;
|
||||||
|
MeteoMode |= SENSOR_T2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
terr |= 2;
|
||||||
|
if(T<-20.) T2=-20.;
|
||||||
|
else if(T>30.) T2=30.;
|
||||||
|
MeteoMode &= ~SENSOR_T2;
|
||||||
|
}
|
||||||
|
if((MeteoMode & INPUT_T2)== 0 && (MeteoMode & SENSOR_T2))
|
||||||
|
val_T2 = T2;
|
||||||
|
//printf("Get T=%.1f\n", T2);
|
||||||
|
tok = t;
|
||||||
|
}
|
||||||
|
if(chan<3 && (ctm&0x93) == 0x93) { /* áãð-0,1,4,7 - Ok */
|
||||||
|
tok = t;
|
||||||
|
ctm=0;
|
||||||
|
}
|
||||||
|
tlast=t;
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
if(stop_prog) can_exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
1143
BTA_modbusmeteo/olddaemon/bta_shdata.h
Normal file
1143
BTA_modbusmeteo/olddaemon/bta_shdata.h
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user