lpcmanager

5fe7136db081
Parents 44bcda8ef9ff
Children 8f905bbfee59
Work on RTU support, some cleanup in surrounding C code
--- a/LPCBus/MC9.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9.c Thu Mar 12 15:30:05 2015 +0100
@@ -32,6 +32,17 @@
*buffer &= ~msk;
}
+typedef struct /* Type definition for timers for right modules */
+{
+ unsigned char status; /* Current status of timer - running / expired */
+ long long actValue; /* Actual timer value */
+ long long toValue; /* Timeout value - initialized at startup */
+} commTimer;
+
+#define TIM_DISABLED 0
+#define TIM_EN_RUNNING 1
+#define TIM_EN_EXPIRED 2
+
%(bus_decl)s
%(declare_code)s
--- a/LPCBus/MC9_Devices_decl.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_Devices_decl.c Thu Mar 12 15:30:05 2015 +0100
@@ -36,7 +36,7 @@
struct gpio_device *RS485_GPIO_dev;
-int write_file_bool(int fd, int value)
+static int write_file_bool(int fd, int value)
{
int ret;
@@ -54,7 +54,7 @@
}
#define BUFF_SIZE 256
-struct gpio_device *gpio_open(int aGpioNum)
+static struct gpio_device *gpio_open(int aGpioNum)
{
struct gpio_device *dev;
int pin_file;
@@ -112,7 +112,7 @@
return dev;
}
-int gpio_close(struct gpio_device *aDev)
+static int gpio_close(struct gpio_device *aDev)
{
int unexport_file;
char buf[BUFF_SIZE];
@@ -142,7 +142,7 @@
return 0;
}
-int gpio_set_pin_value(struct gpio_device *aDev, int aValue)
+static int gpio_set_pin_value(struct gpio_device *aDev, int aValue)
{
int pin_file = aDev->pin_file;
int retval;
@@ -157,15 +157,8 @@
return aValue;
}
-int TransmitMode(int fd)
-{
- return gpio_set_pin_value(RS485_GPIO_dev, 1);
-}
-
-int RecieveMode(int fd)
-{
- return gpio_set_pin_value(RS485_GPIO_dev, 0);
-}
+#define TransmitMode gpio_set_pin_value(RS485_GPIO_dev, 1)
+#define RecieveMode gpio_set_pin_value(RS485_GPIO_dev, 0)
/*--------------------------- Serial Port handling ---------------------------*/
@@ -205,21 +198,11 @@
return 0;
}
- TransmitMode(fd);
+ TransmitMode();
return fd;
}
-typedef struct /* Type definition for timers for right modules */
-{
- unsigned char status; /* Current status of timer - running / expired */
- long long actValue; /* Actual timer value */
- long long toValue; /* Timeout value - initialized at startup */
-} commTimer;
-
-#define TIM_DISABLED 0
-#define TIM_EN_RUNNING 1
-#define TIM_EN_EXPIRED 2
#define EMPTY 0
#define LOCKED 1
@@ -429,7 +412,7 @@
+ 500000)) == -EINTR);
/* Turn to listen mode*/
- RecieveMode(UART_fd);
+ RecieveMode();
while(count < UART_BUFSIZE){
@@ -467,7 +450,7 @@
// }
/* Turn to transmit mode*/
- TransmitMode(UART_fd);
+ TransmitMode();
/* Copy received buffer */
if(count == UART_BUFSIZE){
--- a/LPCBus/MC9_OnBoard_cleanup.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_OnBoard_cleanup.c Thu Mar 12 15:30:05 2015 +0100
@@ -1,1 +1,7 @@
-/* Hello */
+mbmrtu_cleanup();
+rt_task_delete(&RTU_UART_task);
+rt_task_join(&RTU_UART_task);
+rt_task_delete(&RTU_task);
+rt_task_join(&RTU_task);
+rt_mutex_delete(&RTU_BuffMutex);
+gpio_close(RTU_GPIO_dev);
--- a/LPCBus/MC9_OnBoard_decl.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_OnBoard_decl.c Thu Mar 12 15:30:05 2015 +0100
@@ -1,4 +1,268 @@
-#define MAX_ONBOARD_DEVICES 2
-/* Tables containing information about enabled on-board devices
- (initialized by Composer) */
-unsigned char onBoardDev[MAX_ONBOARD_DEVICES][2];
+
+/*------------------------- GPIO -------------------------------------*/
+/* from armadeus/target/packages/as_devices/c/as_gpio* */
+
+//#ifdef DEBUG
+# define ERROR(fmt, ...) printf(fmt, ##__VA_ARGS__)
+//#else
+//# define ERROR(fmt, ...) /*fmt, ##__VA_ARGS__*/
+//#endif
+
+struct gpio_device {
+ int port_num;
+ int pin_file; /* pin file for 2.6.29 interface*/
+};
+
+struct gpio_device *RTU_GPIO_dev;
+
+static int write_file_bool(int fd, int value)
+{
+ int ret;
+
+ ret = write(fd, value?"1":"0", 1);
+ if (ret < 0) {
+ ERROR("write error\n");
+ return ret;
+ }
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ ERROR("lseek error\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+#define BUFF_SIZE 256
+static struct gpio_device *gpio_open(int aGpioNum)
+{
+ struct gpio_device *dev;
+ int pin_file;
+ int export_file;
+ int gpio_dir_fd;
+ int retval;
+ char buf[BUFF_SIZE];
+ int ret = 0;
+
+ export_file = open("/sys/class/gpio/export", O_WRONLY);
+ if (export_file < 0) {
+ ERROR("Can't open /sys/class/gpio/export\nBe sure that gpiolib is under your kernel\n");
+ return NULL;
+ }
+
+ snprintf(buf, BUFF_SIZE, "%%d", aGpioNum);
+ retval = write(export_file, buf, strlen(buf));
+ close(export_file);
+ if (retval < 0) {
+ ERROR("/sys/class/gpio/export can't be written\n");
+ return NULL;
+ }
+
+ snprintf(buf, BUFF_SIZE, "/sys/class/gpio/gpio%%d/direction", aGpioNum);
+ gpio_dir_fd = open(buf, O_WRONLY);
+ if (gpio_dir_fd < 0) {
+ ERROR("Can't open gpio%%d direction\n", aGpioNum);
+ return NULL;
+ }
+
+ ret = write(gpio_dir_fd, "out", 3);
+ close(gpio_dir_fd);
+ if (ret < 0){
+ ERROR("Error writing direction\n");
+ return NULL;
+ }
+
+ snprintf(buf, BUFF_SIZE, "/sys/class/gpio/gpio%%d/value", aGpioNum);
+ pin_file = open(buf, O_RDWR);
+ if (pin_file < 0) {
+ ERROR("Can't export gpio number %%d\n", aGpioNum);
+ return NULL;
+ }
+
+ dev = malloc(sizeof(struct gpio_device));
+ if (dev == NULL) {
+ ERROR("Can't allocate gpio_device structure\n");
+ close(pin_file);
+ return NULL;
+ }
+
+ dev->port_num = aGpioNum;
+ dev->pin_file = pin_file;
+
+ return dev;
+}
+
+static int gpio_close(struct gpio_device *aDev)
+{
+ int unexport_file;
+ char buf[BUFF_SIZE];
+ int retval;
+
+ if(aDev == NULL){
+ ERROR("device is NULL\n");
+ return -1;
+ }
+
+ unexport_file = open("/sys/class/gpio/unexport", O_WRONLY);
+ if (unexport_file < 0) {
+ ERROR("Can't open /sys/class/gpio/unexport\nBe sure that gpiolib is under your kernel\n");
+ return -1;
+ }
+
+ snprintf(buf, BUFF_SIZE, "%%d", aDev->port_num);
+ retval = write(unexport_file, buf, strlen(buf));
+ close(unexport_file);
+ if (retval < 0) {
+ ERROR("/sys/class/gpio/unexport can't be written\n");
+ return -1;
+ }
+
+ close(aDev->pin_file);
+
+ return 0;
+}
+
+static int gpio_set_pin_value(struct gpio_device *aDev, int aValue)
+{
+ int pin_file = aDev->pin_file;
+ int retval;
+
+ retval = write_file_bool(pin_file, aValue);
+ if (retval < 0) {
+ ERROR("Can't write value\n");
+ close(pin_file);
+ return -1;
+ }
+
+ return aValue;
+}
+
+#define REG_DISCRETE_START 0 /**< Input discrete start address */
+#define REG_DISCRETE_NREGS 511 /**< 512 bits (type: single bit, Read only) */
+
+#define REG_COILS_START 0 /**< Coils start address */
+#define REG_COILS_NREGS 511 /**< 512 bits (type: single bit, Read/Write) */
+
+#define REG_INPUT_START 0 /**< Input registers start address */
+#define REG_INPUT_NREGS 511 /**< 512 words (type: 16-bit word, Read only) */
+
+#define REG_HOLDING_START 0 /**< Holding registers start address */
+#define REG_HOLDING_NREGS 511 /**< 512 words (type: 16-bit word, Read/Write) */
+
+#define MAX_MOD_RTU_DEVICES 16
+
+typedef struct _mbRtuRdHoldingRegs {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned char length;
+ unsigned short* buffer;
+} mbRtuRdHoldingRegs;
+
+typedef struct _mbRtuRdDiscInputs {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned short length;
+ unsigned char* buffer;
+// unsigned short* buffer;
+} mbRtuRdDiscInputs;
+
+typedef struct _mbRtuRdCoils {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned short length;
+ unsigned char* buffer;
+} mbRtuRdCoils;
+
+typedef struct _mbRtuWrSingleCoil {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned char* buffer;
+} mbRtuWrSingleCoil;
+
+typedef struct _mbRtuWrCoils {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned short length;
+ unsigned char* buffer;
+} mbRtuWrCoils;
+
+typedef struct _mbRtuRdInputRegs {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned char length;
+ unsigned short* buffer;
+} mbRtuRdInputRegs;
+
+typedef struct _mbRtuWrSingleReg {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned short* buffer;
+} mbRtuWrSingleReg;
+
+typedef struct _mbRtuWrMultiRegs {
+ unsigned int use;
+ unsigned short startAddr;
+ unsigned char length;
+ unsigned short* buffer;
+} mbRtuWrMultiRegs;
+
+typedef struct _mbRtuSlaveConfig {
+ unsigned char slaveAddr;
+ mbRtuRdDiscInputs rdDiscInputs;
+ mbRtuRdCoils rdCoils;
+ mbRtuWrSingleCoil wrSingleCoil;
+ mbRtuWrCoils wrCoils;
+ mbRtuRdInputRegs rdInputRegs;
+ mbRtuRdHoldingRegs rdHoldingRegs;
+ mbRtuWrSingleReg wrSingleReg;
+ mbRtuWrMultiRegs wrMultiRegs;
+} mbRtuSlaveConfig;
+
+mbRtuSlaveConfig mbRtuSlaveDev[MAX_MOD_RTU_DEVICES]; /**< Tables containing information about connected Modbus network devices (initialized by Composer) */
+commTimer mbRtuDevTim[MAX_MOD_RTU_DEVICES]; /**< Table of timers (one for each position) */
+unsigned short usRegInputValue[REG_INPUT_NREGS]; /**< Array of Modbus input registers */
+unsigned short usRegHoldingValue[REG_HOLDING_NREGS]; /**< Array of Modbus holding registers */
+unsigned char ubCoilValue[REG_COILS_NREGS/8]; /**< Array of Modbus coils (8 coils per byte) */
+unsigned char ubRegDiscreteValue[REG_DISCRETE_NREGS/8]; /**< Array of Modbus discrete inputs (8 inputs per byte) */
+
+/* prototypes for functions defined in shared library */
+int mbmrtu_init();
+void mbmrtu_BusUpdate(void);
+
+static RT_TASK RTU_UART_task;
+static RT_TASK RTU_task;
+static RT_MUTEX RTU_BuffMutex;
+
+void LockMBRTUBuffer(void){
+ rt_mutex_acquire(&RTU_BuffMutex, TM_INFINITE );
+}
+void UnLockMBRTUBuffer(void){
+ rt_mutex_release(&RTU_BuffMutex);
+}
+
+typedef void (RTU_UART_task_proc_t*)(void*);
+void CreateMBRTUSerialTask(RTU_UART_task_proc_t* RTU_UART_task_proc, void* param){
+ int err;
+ if(rt_task_start(&RTU_UART_task, RTU_UART_task_proc, param))
+ return err;
+ return 0;
+}
+
+static void mbmrtu_BusUpdate_proc(void){
+ while (rt_task_sleep_until(TM_INFINITE) == -EINTR){
+ mbmrtu_BusUpdate();
+ }
+}
+
+RTIME now;
+void TransmitMode(void){
+ gpio_set_pin_value(RTU_GPIO_dev, 1);
+ now = rt_timer_read();
+}
+void RecieveMode(int us){
+ while(rt_task_sleep_until(
+ now + rt_timer_ns2ticks(1000LL*us)
+ )) == -EINTR);
+ gpio_set_pin_value(RTU_GPIO_dev, 0);
+}
+
+
--- a/LPCBus/MC9_OnBoard_init.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_OnBoard_init.c Thu Mar 12 15:30:05 2015 +0100
@@ -1,2 +1,75 @@
-bzero(&onBoardDev, sizeof(onBoardDev));
+int err;
+
+bzero(&usRegInputValue , sizeof(usRegInputValue ));
+bzero(&usRegHoldingValue , sizeof(usRegHoldingValue ));
+bzero(&ubCoilValue , sizeof(ubCoilValue ));
+bzero(&ubRegDiscreteValue, sizeof(ubRegDiscreteValue));
+bzero(&mbRtuSlaveDev , sizeof(mbRtuSlaveDev ));
+bzero(&mbRtuDevTim , sizeof(mbRtuDevTim ));
+
%(init_code)s
+// ******** STUB code for composer **************
+// for(i=0;i<MAX_MOD_RTU_DEVICES;i++)
+// {
+// mbRtuSlaveDev[i].slaveAddr = INVALID_RTU_ADDR;
+// mbRtuDevTim[i].toValue = 0;
+// mbRtuDevTim[i].status = TIM_DISABLED;
+//
+// mbRtuSlaveDev[i].rdDiscInputs.use = FALSE;
+// mbRtuSlaveDev[i].rdDiscInputs.startAddr = 0;
+// mbRtuSlaveDev[i].rdDiscInputs.length = 0;
+// mbRtuSlaveDev[i].rdDiscInputs.buffer = &ubRegDiscreteValue[0];
+//
+// mbRtuSlaveDev[i].rdCoils.use = FALSE;
+// mbRtuSlaveDev[i].rdCoils.startAddr = 0;
+// mbRtuSlaveDev[i].rdCoils.length = 0;
+// mbRtuSlaveDev[i].rdCoils.buffer = &ubCoilValue[0];
+//
+// mbRtuSlaveDev[i].wrSingleCoil.use = FALSE;
+// mbRtuSlaveDev[i].wrSingleCoil.startAddr = 0;
+// mbRtuSlaveDev[i].wrSingleCoil.buffer = &ubCoilValue[0];
+//
+// mbRtuSlaveDev[i].wrCoils.use = FALSE;
+// mbRtuSlaveDev[i].wrCoils.startAddr = 0;
+// mbRtuSlaveDev[i].wrCoils.length = 0;
+// mbRtuSlaveDev[i].wrCoils.buffer = &ubCoilValue[0];
+//
+// mbRtuSlaveDev[i].rdInputRegs.use = FALSE;
+// mbRtuSlaveDev[i].rdInputRegs.startAddr = 0;
+// mbRtuSlaveDev[i].rdInputRegs.length = 0;
+// mbRtuSlaveDev[i].rdInputRegs.buffer = &usRegInputValue[0];
+//
+// mbRtuSlaveDev[i].rdHoldingRegs.use = FALSE;
+// mbRtuSlaveDev[i].rdHoldingRegs.startAddr = 0;
+// mbRtuSlaveDev[i].rdHoldingRegs.length = 0;
+// mbRtuSlaveDev[i].rdHoldingRegs.buffer = &usRegHoldingValue[0];
+//
+// mbRtuSlaveDev[i].wrSingleReg.use = FALSE;
+// mbRtuSlaveDev[i].wrSingleReg.startAddr = 0;
+// mbRtuSlaveDev[i].wrSingleReg.buffer = &usRegHoldingValue[0];
+//
+// mbRtuSlaveDev[i].wrMultiRegs.use = FALSE;
+// mbRtuSlaveDev[i].wrMultiRegs.startAddr = 0;
+// mbRtuSlaveDev[i].wrMultiRegs.length = 0;
+// mbRtuSlaveDev[i].wrMultiRegs.buffer = &usRegHoldingValue[0];
+// }
+
+
+RTU_GPIO_dev = gpio_open(111);
+if (!RTU_GPIO_dev) {
+ fprintf(stderr, "Error while initializing RTU GPIO.\n");
+ return 1;
+}
+if((err = rt_mutex_create (&RTU_BuffMutex, "RTU_BuffMutex")))
+ return err;
+
+if((err = rt_task_create(&RTU_UART_task, "RTU_UART_task", 0, 50, T_JOINABLE)))
+ return err;
+
+mbmrtu_init();
+
+if((err = rt_task_create(&RTU_task, "RTU_task", 0, 50, T_JOINABLE)))
+ return err;
+
+if(rt_task_start(&RTU_task, &mbmrtu_BusUpdate, NULL))
+ return err;
--- a/LPCBus/MC9_OnBoard_publish.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_OnBoard_publish.c Thu Mar 12 15:30:05 2015 +0100
@@ -1,1 +1,9 @@
+LockMBRTUBuffer()
+
%(publish_code)s
+/* STUB CODE XXX */
+// setWord16(&usRegHoldingValue[0],*__MW4_1_1_0);
+// setBit(&ubRegDiscreteValue[0],0,*__QX4_1_2_0);
+// setBit(&ubCoilValue[0],0,*__MX4_1_0_0);
+// setWord16(&usRegInputValue[0],*__QW4_1_3_0);
+// setBit(&ubRegDiscreteValue[0],1,*__QX4_1_2_1);
--- a/LPCBus/MC9_OnBoard_retrieve.c Tue Feb 10 11:44:28 2015 +0100
+++ b/LPCBus/MC9_OnBoard_retrieve.c Thu Mar 12 15:30:05 2015 +0100
@@ -1,1 +1,9 @@
%(retrieve_code)s
+/*
+*__MW4_1_1_0=getWord16(&usRegHoldingValue[0]);
+*__MX4_1_0_0=getBit(&ubCoilValue[0],0);
+*/
+
+UnLockMBRTUBuffer();
+
+