diff --git a/app/include/common.h b/app/include/common.h
index 9212e45..3818295 100755
--- a/app/include/common.h
+++ b/app/include/common.h
@@ -65,6 +65,8 @@
#define E_NOT_IDENTIFY -7
#define E_TIMEOUT -8
#define E_SAME -9
+#define E_EMPTY -10
+#define E_FULL -11
#define OUT
diff --git a/app/include/dbg.h b/app/include/dbg.h
index efad35c..80dff38 100755
--- a/app/include/dbg.h
+++ b/app/include/dbg.h
@@ -71,6 +71,8 @@ typedef enum
DBG_M_SERIAL,
DBG_M_PD_MODBUS,
DBG_M_PD_MODBUS_ERR,
+ DBG_M_FILE_FIFO,
+ DBG_M_FILE_FIFO_ERR,
DBG_M_COUNT
} DBG_MODULE_E;
diff --git a/app/include/file_fifo.h b/app/include/file_fifo.h
new file mode 100755
index 0000000..e10ac64
--- /dev/null
+++ b/app/include/file_fifo.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+ * file include/file_fifo.h
+ * author YuLiang
+ * version 1.0.0
+ * date 10-Jun-2025
+ * brief This file provides all the headers of the file fifo functions.
+
+ ******************************************************************************
+ * Attention
+ *
+ *
© COPYRIGHT(c) 2025 LandPower
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of LandPower nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+#ifndef _FILE_FIFO_H_
+#define _FILE_FIFO_H_
+
+/* Includes ------------------------------------------------------------------*/
+
+/* Define --------------------------------------------------------------------*/
+#define FILE_FIFO_PATH_LEN 256
+
+/* Exported types ------------------------------------------------------------*/
+/* 配置文件结构体 */
+typedef struct
+{
+ char dir[FILE_FIFO_PATH_LEN]; // 目录路径
+ int32_t files_max; // 存储最大文件数量
+ int64_t index_min; // 目录当前最小索引
+ int64_t index_max; // 目录当前最大索引, 该索引为下次下入的文件名
+} file_fifo_t;
+
+typedef struct
+{
+ uint32_t len;
+ char *content;
+} fifo_arr;
+
+/* Exported macro ------------------------------------------------------------*/
+
+/* Extern global variables ---------------------------------------------------*/
+
+/* Extern functions ----------------------------------------------------------*/
+extern int32_t file_fifo_write(file_fifo_t *config, const char *content, int32_t len);
+extern int32_t file_fifo_read(file_fifo_t *config, char *content, int32_t *len);
+extern void file_fifo_delete_by_min_index(file_fifo_t *config);
+extern int32_t file_fifo_init(file_fifo_t *config);
+
+#endif
+/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
diff --git a/app/include/hwgpio.h b/app/include/hwgpio.h
index 7d9dc19..30de754 100755
--- a/app/include/hwgpio.h
+++ b/app/include/hwgpio.h
@@ -45,6 +45,12 @@
#define GPIO_WATCHDONG 915
#define GPIO_485_BUS 154 // GPIO4_D2 (4*32+3*8+2)
+#define GPIO_DAU1 95 // GPIO2_D7
+#define GPIO_DAU2 18 // GPIO0_C2
+#define GPIO_DAU3 20 // GPIO0_C4
+#define GPIO_DAU4 14 // GPIO0_B6
+#define GPIO_DAU5 65 // GPIO2_A1
+#define GPIO_DAU6 81 // GPIO2_C1
/* Exported types ------------------------------------------------------------*/
/* 记录每个打开的gpio信息 */
@@ -59,9 +65,16 @@ typedef struct
/* Exported macro ------------------------------------------------------------*/
#define GPIO_485BUS(_v_) gpio_val_set(gpio_485bus_idx, _v_)
+#define GPIO_DAU1_VAL() gpio_val_get(gpio_dau1_idx)
/* Extern global variables ---------------------------------------------------*/
extern int32_t gpio_485bus_idx;
+extern int32_t gpio_dau1_idx;
+extern int32_t gpio_dau2_idx;
+extern int32_t gpio_dau3_idx;
+extern int32_t gpio_dau4_idx;
+extern int32_t gpio_dau5_idx;
+extern int32_t gpio_dau6_idx;
/* Extern functions ----------------------------------------------------------*/
extern int32_t gpio_val_set(uint16_t gpio, uint8_t value);
diff --git a/app/include/pd_csg.h b/app/include/pd_csg.h
index 35a6e47..32dbc83 100755
--- a/app/include/pd_csg.h
+++ b/app/include/pd_csg.h
@@ -43,6 +43,8 @@
#include
#include
+#include "file_fifo.h"
+#include "pd_hf.h"
/* Define --------------------------------------------------------------------*/
#define CSG_FIFO_CMD "CSG_FIFO_CMD"
@@ -61,12 +63,19 @@
#define CSG_TREND_PRPD_PORT_LEN (0X20000) // 128K
#define CSG_TREND_ORIG_PORT_LEN (0X20400) // 129K
+#define CSG_TREND_NAME "/media/Data/Trend"
+#define CSG_EVENT_NAME "/media/Data/Event"
+
+#define CSG_SEND_TIMEOUT (2)
+#define CSG_SEND_ERR_CNT (3)
+#define CSG_FILE_FIFO_PATH_LEN 256
+
-#define MAX_FILES (128)
-#define MAX_PATH_LEN (256)
-#define THRESHOLD_MS 10 // 时间差阈值
-#define CSG_SEND_TIMEOUT (2)
-#define CSG_SEND_ERR_CNT (3)
+//#define MAX_FILES (128)
+//#define MAX_PATH_LEN (256)
+//#define THRESHOLD_MS 10 // 时间差阈值
+//#define CSG_SEND_TIMEOUT (2)
+//#define CSG_SEND_ERR_CNT (3)
#define CSG_FILE_NAME_LEN (128)
#define DAU_INSERT 1
@@ -123,6 +132,7 @@ enum CSG_TREND_TYPE
typedef int32_t (*csg_send_cb)(uint8_t, uint8_t, void*);
typedef int32_t (*csg_send_fun_cb)(uint8_t, void*);
+typedef int32_t (*csg_write_file_cb)(uint8_t, void *);
// 定义命令字常量
@@ -153,6 +163,14 @@ typedef struct {
uint32_t port; /* 端口号 0 ~ 7 */
uint32_t length; /* 端口数据长度 */
}port_info_t;
+
+typedef struct
+{
+ char dir[CSG_FILE_FIFO_PATH_LEN]; // 目录路径
+ int32_t files_max; // 存储最大文件数量
+ int64_t index_min; // 目录当前最小索引
+ int64_t index_max; // 目录当前最大索引, 该索引为下次下入的文件名
+} csg_file_fifo_t;
/* . */
typedef struct
@@ -181,6 +199,8 @@ typedef struct
uint32_t event_booster_id;
time_t heartbeat_timeout;
time_t heartbeat_timeout_cnt;
+ file_fifo_t event_file;
+ csg_file_fifo_t trend_file;
sem_t event_sem;
sem_t trend_sem;
sem_t event_booster_sem;
@@ -188,6 +208,8 @@ typedef struct
pthread_mutex_t mutex;
pthread_mutex_t lock;
csg_send_cb send_cb;
+ csg_write_file_cb event_write_file_cb;
+ csg_write_file_cb trend_write_file_cb;
} csg_t;
/* 报文头结构. */
@@ -332,6 +354,18 @@ typedef struct{
uint32_t utc; // 同步时间
uint32_t len; // 当前包长度
} csg_trend_t;
+
+typedef struct
+{
+ uint8_t type; // 数据类型 TREND_TYPE 0:prpd 1:原始波形 2:10秒prps 3:统计数据
+ uint8_t vport; // 通道号
+ uint8_t port_num; // 通道数
+ uint8_t slot; // 槽位号,保存文件使用
+ uint32_t identifier; // 数据编号
+ uint32_t utc; // 同步时间
+ uint32_t len; // data长度
+} csg_trend_file_t;
+
typedef struct{
uint16_t data_cnt; // 数据计数.
int16_t max; // 通道的最大值.
@@ -351,7 +385,8 @@ typedef struct {
int16_t max; // 通道的最大值.
uint32_t power_fre; // 工频周期.
uint8_t type; // 事件类型.
- uint8_t reserved[3]; // 保留
+ uint8_t slot; // 槽位,保存文件使用
+ uint8_t reserved[2]; // 保留
uint32_t identifier; // 数据编号: 0 - (2^32-1) 循环.
uint32_t utc; // UTC 时标.
uint32_t cnt; // 通道每秒脉冲计数值.
@@ -359,7 +394,13 @@ typedef struct {
uint16_t avg; // 脉冲平均值.
uint32_t point_cnt; // 数据累计点数
uint32_t len; // 当前包长度
-} csg_event_t;
+} csg_event_head_t;
+
+typedef struct {
+ csg_event_head_t head;
+ hf_data_point_t point[PD_EVENT_POINT_MAX];
+} csg_event_t;
+
/* 升级文件包结构体 */
typedef struct {
uint8_t type; // 升级类型
@@ -441,7 +482,6 @@ typedef struct
uint8_t reserved[2];
uint8_t result;
} csg_add_dau_ack_t;
-
/* Exported macro ------------------------------------------------------------*/
diff --git a/app/include/pd_modbus.h b/app/include/pd_modbus.h
index 832c3ca..9bbb4db 100755
--- a/app/include/pd_modbus.h
+++ b/app/include/pd_modbus.h
@@ -6,10 +6,11 @@
#define WRITE 1
#define READ 0
-#define MODBUS_IR_CURRENT_ADDR 0x0 // 铁芯
-#define MODBUS_IR_CURRENT_LEN 2
-#define MODBUS_DC_CURRENT_ADDR 0x34 // 直流偏磁
-#define MODBUS_DC_CURRENT_LEN 2
+#define MODBUS_DEVICE_TYPE_ADDR 0x0
+#define MODBUS_IR_CURRENT_ADDR 0x10 // 铁芯
+#define MODBUS_IR_CURRENT_LEN 2
+#define MODBUS_DC_CURRENT_ADDR 0x34 // 直流偏磁
+#define MODBUS_DC_CURRENT_LEN 2
#define MODBUS_UNIT_IR 0x01
@@ -17,6 +18,23 @@
#define MODBUS_ADDR_ALARM 0x32
#define MODBUS_ALARM_LEN 2
+#define DEVICE_IR_TYPE 0x0304
+#define DEVICE_DC_TYPE 0x0305
+
+#define POS_UINT_ID 6
+#define POS_FUNCTION 7
+
+#define MAX_SLOT 6
+
+typedef struct
+{
+ uint8_t unit_id;
+ uint8_t status;
+ uint16_t type;
+ uint32_t current;
+ uint16_t alarm;
+} stat_t;
+
// 定义Modbus TCP MBAP头
//#pragma pack(push, 1)
@@ -42,8 +60,10 @@ typedef struct
int fd;
uint8_t txbuf[512];
uint8_t rxbuf[512];
+ stat_t stat[MAX_SLOT];
}modbus_t;
+extern int32_t modbus_handle_init(void);
extern int32_t modbus_handle_init_after(void);
#endif
#endif
diff --git a/app/lib/a_process/pd_csg.c b/app/lib/a_process/pd_csg.c
index 042b959..d4b5ea6 100755
--- a/app/lib/a_process/pd_csg.c
+++ b/app/lib/a_process/pd_csg.c
@@ -75,6 +75,7 @@
/* Private variables ---------------------------------------------------------*/
csg_t csg;
+static csg_event_t _csg_event;
/* Private function prototypes -----------------------------------------------*/
void _csg_server_set(int32_t ip, uint16_t port);
@@ -1015,8 +1016,8 @@ int32_t _csg_send_prps_data(uint8_t slot, void *data)
int32_t _csg_send_event_data(uint8_t slot, void *data)
{
char *pkt = csg.event_buf;
- csg_event_t *head = (csg_event_t *)(pkt + sizeof(csg_pkt_head_t));
- char *pdata = pkt + sizeof(csg_pkt_head_t) + sizeof(csg_event_t);
+ csg_event_head_t *head = (csg_event_head_t *)(pkt + sizeof(csg_pkt_head_t));
+ char *pdata = pkt + sizeof(csg_pkt_head_t) + sizeof(csg_event_head_t);
hf_event_t *event = (hf_event_t *)data;
struct timespec ts;
uint8_t err_cnt = 0;
@@ -1062,7 +1063,7 @@ int32_t _csg_send_event_data(uint8_t slot, void *data)
head->index = index;
memcpy(pdata, event->point + index * CSG_PKT_LEN, head->len);
- _csg_send_data(CSG_PRV_REPLY, CSG_PRV_EVENT, pkt, head->len + sizeof(csg_event_t), slot + 1);
+ _csg_send_data(CSG_PRV_REPLY, CSG_PRV_EVENT, pkt, head->len + sizeof(csg_event_head_t), slot + 1);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += CSG_SEND_TIMEOUT; // 设置 3 秒超时
@@ -1085,6 +1086,180 @@ int32_t _csg_send_event_data(uint8_t slot, void *data)
return E_NONE;
}
+int32_t _csg_event_file_send(void)
+{
+ struct timespec ts;
+ csg_event_head_t *head = NULL;
+ char *pdata = NULL;
+ char *pkt = csg.event_booster_buf;
+ csg_event_head_t *pack = (csg_event_head_t *)(pkt + sizeof(csg_pkt_head_t));
+ char *data = pkt + sizeof(csg_pkt_head_t) + sizeof(csg_event_head_t);
+ uint8_t err_cnt = 0;
+ uint32_t index = 0;
+ uint32_t event_len = 0;
+ uint32_t sum = 0;
+ uint8_t slot = 0;
+
+ head = &_csg_event.head;
+ pdata = (char *)_csg_event.point;
+ event_len = head->point_cnt * sizeof(pd_data_point_t);
+ sum = event_len / CSG_PKT_LEN;
+ if (event_len % CSG_PKT_LEN)
+ {
+ sum += 1;
+ }
+
+ slot = head->slot;
+ pack->sum = sum;
+ pack->vport = head->vport;
+ pack->boosterpack = 1;
+ pack->power_fre = head->power_fre;
+ pack->type = head->type;
+ pack->max = head->max;
+ pack->identifier = head->index;
+ pack->utc = head->utc;
+ pack->cnt = head->cnt;
+ pack->avg_o = head->avg_o;
+ pack->avg = head->avg;
+ pack->point_cnt = head->point_cnt;
+
+ while (index < sum)
+ {
+ csg.event_booster_id = index;
+ pack->len = event_len > CSG_PKT_LEN ? CSG_PKT_LEN : event_len;
+ pack->index = index;
+
+ memcpy(data, pdata + index * CSG_PKT_LEN, pack->len);
+ _csg_send_data(CSG_PRV_REPLY, CSG_PRV_EVENT, pkt, pack->len + sizeof(csg_event_head_t), slot + 1);
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += CSG_SEND_TIMEOUT; // 设置 3 秒超时
+ if (sem_timedwait(&csg.event_booster_sem, &ts) != 0)
+ {
+ err_cnt++;
+ if (err_cnt >= CSG_SEND_ERR_CNT)
+ {
+ _csg_disconnect_set(__FUNCTION__);
+ return E_TIMEOUT;
+ }
+ DBG(DBG_M_PD_CSG_ERR, "event sem error:%s\r\n", strerror(errno));
+ continue;
+ }
+
+ event_len -= pack->len;
+ index++;
+ err_cnt = 0;
+ }
+
+ return E_NONE;
+}
+
+/* 趋势文件发送 */
+int32_t _csg_trend_file_send(char *filename)
+{
+ struct timespec ts;
+ FILE *file = NULL;
+ csg_trend_file_t filehead = {0};
+ char *pkt = csg.trend_booster_buf;
+ csg_trend_t *pack = (csg_trend_t *)(pkt + sizeof(csg_pkt_head_t));
+ char *data = pkt + sizeof(csg_pkt_head_t) + sizeof(csg_trend_t);
+ uint8_t err_cnt = 0;
+ uint32_t index = 0;
+ uint32_t prps_len = 0;
+ uint32_t sum = 0;
+ uint32_t len = 0;
+ uint32_t readbyte = 0;
+ int offset = 0;
+ uint8_t slot;
+
+ if (csg.trend_file.index_min == csg.trend_file.index_max)
+ {
+ return E_EMPTY;
+ }
+
+ file = fopen(filename, "r");
+ if (!file)
+ {
+ DBG(DBG_M_PD_CSG_ERR, "Open failed!\r\n");
+ return E_NONE;
+ }
+
+ while(1)
+ {
+ fseek(file, offset, SEEK_SET);
+ readbyte = fread(&filehead, 1, sizeof(csg_trend_file_t), file);
+ if (readbyte != sizeof(csg_trend_file_t))
+ {
+ if (readbyte != 0)
+ {
+ DBG(DBG_M_PD_CSG_ERR,"read %d != %d\r\n", len, readbyte, strerror(errno));
+ }
+ fclose(file);
+ return E_NONE;
+ }
+
+ printf("#1 %d %d %d %d %d\r\n", filehead.vport, filehead.type, filehead.len, filehead.identifier, filehead.utc);
+ pack->type = filehead.type;
+ pack->vport = filehead.vport;
+ pack->boosterpack = 1;
+ pack->identifier = filehead.identifier;
+ pack->utc = filehead.utc;
+ slot = filehead.slot;
+ prps_len = filehead.len;
+ sum = prps_len / CSG_PKT_LEN;
+ if (prps_len % CSG_PKT_LEN)
+ {
+ sum += 1;
+ }
+ pack->sum = sum;
+
+ offset += sizeof(csg_trend_file_t);
+ index = 0;
+ while (index < sum)
+ {
+ fseek(file, offset, SEEK_SET);
+ csg.trend_booster_id = index;
+ len = prps_len > CSG_PKT_LEN ? CSG_PKT_LEN : prps_len;
+
+ pack->len = len;
+ pack->index = index;
+
+ readbyte = fread(data, 1, len, file);
+ if (readbyte != len)
+ {
+ DBG(DBG_M_PD_CSG_ERR,"read %d != %d err:%s\r\n", len, readbyte, strerror(errno));
+ fclose(file);
+ return E_NONE;
+ }
+
+ _csg_send_data(CSG_PRV_REPLY, CSG_PRV_TREND, pkt, len + sizeof(csg_trend_t), slot + 1);
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += CSG_SEND_TIMEOUT; // 设置 3 秒超时
+ if (sem_timedwait(&csg.trend_booster_sem, &ts) != 0)
+ {
+ err_cnt++;
+ if (err_cnt >= CSG_SEND_ERR_CNT)
+ {
+ fclose(file);
+ _csg_disconnect_set(__FUNCTION__);
+ return E_TIMEOUT;
+ }
+ DBG(DBG_M_PD_CSG_ERR, "trend sem error:%s\r\n", strerror(errno));
+ continue;
+ }
+
+ prps_len -= len;
+ index++;
+ err_cnt = 0;
+ offset += len;
+ }
+ }
+
+ fclose(file);
+ return E_NONE;
+}
+
int32_t _csg_send_trend_prps_data(uint8_t slot, void *data)
{
struct timespec ts;
@@ -1332,6 +1507,282 @@ int32_t _csg_send_process(uint8_t type, uint8_t slot, void *data)
return E_NONE;
}
+/* 创建目录 */
+int32_t _csg_create_dir(char *dir)
+{
+ uint32_t i = 0;
+ uint32_t len = 0;
+
+ len = strlen(dir);
+
+ /* 循环创建前级目录 */
+ for(i = 0; i < len; i++)
+ {
+ if(dir[i] == '/')
+ {
+ dir[i] = '\0';
+ if(access(dir, 0) != 0)
+ {
+ mkdir(dir, 744);
+ }
+ dir[i] ='/';
+ }
+ }
+
+ /* 创建最后级目录 */
+ if(len > 0 && access(dir, 0) != 0)
+ {
+ mkdir(dir, 744);
+ }
+
+ return E_NONE;
+}
+
+/* 在文件末尾写入数据 */
+int32_t _csg_write_file(char *filename, char *filehead, int headsize, char *filedata, int datasize)
+{
+ /* 写入文件 */
+ FILE *file = fopen(filename, "ab");
+ if (!file)
+ {
+ DBG(DBG_M_PD_CSG_ERR, "Open error.\r\n");
+ return E_SYS_CALL;
+ }
+
+ fseek(file, 0, SEEK_END); // 移动到文件末尾
+
+ size_t bytes_written = fwrite(filehead, 1, headsize, file);
+ if (bytes_written != headsize)
+ {
+ DBG(DBG_M_PD_CSG_ERR, "Write error.\r\n");
+ fclose(file);
+ unlink(filename); // 删除不完整文件
+ return E_SYS_CALL;
+ }
+
+ bytes_written = fwrite(filedata, 1, datasize, file);
+ if (bytes_written != datasize)
+ {
+ DBG(DBG_M_PD_CSG_ERR, "Write error.\r\n");
+ fclose(file);
+ unlink(filename); // 删除不完整文件
+ return E_SYS_CALL;
+ }
+
+ /* 确保数据落盘 */
+ fsync(fileno(file));
+ fclose(file);
+ return E_NONE;
+}
+
+/* 趋势 prps 写入文件 */
+int32_t _csg_trend_prps_write_file(uint8_t slot, uint8_t port, char *filepath)
+{
+ hf_trend_prps_port_t *data_port = NULL;
+ csg_trend_file_t file_head = {0};
+
+ dau_t *dau = &daus[slot];
+ hf_data_t *hf_data = (hf_data_t*)dau->private_data;
+ hf_trend_prps_t *prps = &hf_data->trend.prps;
+ hf_trend_col_t *col = &hf_data->trend.col;
+
+ data_port = &prps->port[port];
+
+ file_head.type = CSG_TREND_TYPE_PRPS;
+ file_head.vport = port + 1;
+ file_head.port_num = 1;
+ file_head.slot = slot;
+ file_head.identifier = col->index;
+ file_head.utc = col->utc;
+ file_head.len = data_port->point_cnt * sizeof(pd_data_point_t);
+
+ LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_write_file(filepath, (char *)&file_head, sizeof(file_head), (char*)data_port->point, file_head.len));
+
+ return E_NONE;
+}
+
+/* 趋势 prpd 写入文件 */
+int32_t _csg_trend_prpd_write_file(uint8_t slot, uint8_t port, char *filepath)
+{
+ pd_trend_prpd_port_t *data_port = NULL;
+ csg_trend_file_t file_head = {0};
+
+ dau_t *dau = &daus[slot];
+ hf_data_t *hf_data = (hf_data_t*)dau->private_data;
+ hf_trend_prpd_t *prpd = &hf_data->trend.prpd;
+ hf_trend_col_t *col = &hf_data->trend.col;
+
+ data_port = &prpd->port[port];
+
+ file_head.type = CSG_TREND_TYPE_PRPD;
+ file_head.vport = port + 1;
+ file_head.port_num = 1;
+ file_head.slot = slot;
+ file_head.identifier = col->index;
+ file_head.utc = col->utc;
+ file_head.len = sizeof(pd_trend_prpd_port_t);
+
+ LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_write_file(filepath, (char *)&file_head, sizeof(file_head), (char*)data_port, file_head.len));
+
+ return E_NONE;
+}
+
+/* 趋势统计数据写入文件 */
+int32_t _csg_trend_statistics_write_file(uint8_t slot, uint8_t port, char *filepath)
+{
+ hf_trend_stat *data_port = NULL;
+ csg_trend_file_t file_head = {0};
+ csg_trend_stat stat = {0};
+
+ dau_t *dau = &daus[slot];
+ hf_data_t *hf_data = (hf_data_t*)dau->private_data;
+ hf_trend_col_t *col = &hf_data->trend.col;
+
+ data_port = &col->port[port];
+
+ file_head.type = CSG_TREND_TYPE_STAT;
+ file_head.vport = port + 1;
+ file_head.port_num = 1;
+ file_head.slot = slot;
+ file_head.identifier = col->index;
+ file_head.utc = col->utc;
+ file_head.len = sizeof(csg_trend_stat);
+
+ stat.data_cnt = data_port->data_cnt;
+ stat.max = data_port->max;
+ stat.avg = data_port->avg;
+ stat.cnt = data_port->cnt;
+ stat.phase = data_port->phase;
+ stat.noise = data_port->noise;
+ stat.event_cnt = data_port->event_cnt;
+
+ LD_E_RETURN(DBG_M_PD_CSG_ERR, _csg_write_file(filepath, (char *)&file_head, sizeof(file_head), (char *)&stat, file_head.len));
+
+
+ return E_NONE;
+}
+
+int32_t _csg_event_write_file(uint8_t slot, void *data)
+{
+ int32_t len = 0;
+ hf_event_t *event = (hf_event_t *)data;
+ if (NULL == event)
+ {
+ return E_BAD_PARAM;
+ }
+
+ csg_event_head_t *head = (csg_event_head_t *)data;
+ head->slot = slot;
+
+ len = sizeof(event->head) + event->head.point_cnt * sizeof(hf_data_point_t);
+ file_fifo_write(&csg.event_file, (char*)event, len);
+ return E_NONE;
+}
+
+/* 趋势数据写入文件 */
+int32_t _csg_trend_write_file(uint8_t slot, void *data)
+{
+ int ret = E_NONE;
+ char filepath[CSG_FILE_FIFO_PATH_LEN] = {0};
+
+ uint8_t port = *(uint32_t *)data;
+ if (port >= 8)
+ return E_BAD_PARAM;
+
+ if (csg.trend_file.index_max - csg.trend_file.index_min >= csg.trend_file.files_max)
+ {
+ return E_FULL;
+ }
+
+ snprintf(filepath, 128, "%s/%ld", CSG_TREND_NAME, csg.trend_file.index_max);
+
+ ret |= _csg_trend_prps_write_file(slot, port, filepath);
+ ret |= _csg_trend_prpd_write_file(slot, port, filepath);
+ ret |= _csg_trend_statistics_write_file(slot, port, filepath);
+ if (E_NONE == ret)
+ {
+ csg.trend_file.index_max++;
+ }
+
+ return ret;
+}
+
+
+/* 初始化最大最小索引 */
+int32_t _csg_file_fifo_init(csg_file_fifo_t *config)
+{
+ DIR *dir = opendir(config->dir);
+ struct dirent *entry;
+ uint8_t first = 1;
+ int64_t index = 0;
+
+ /* 初始化最大最小 index */
+ config->index_max = 0;
+ config->index_min = 0;
+
+ if (!dir)
+ {
+ _csg_create_dir(config->dir);
+ }
+ else
+ {
+ while ((entry = readdir(dir)) != NULL)
+ {
+ if (entry->d_type != DT_REG)
+ {
+ continue;
+ }
+
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+ //printf("filename:%s\n", entry->d_name);
+
+ index = strtoll(entry->d_name, NULL, 10);
+ if (first)
+ {
+ config->index_max = config->index_min = index;
+ first = 0;
+ }
+ else
+ {
+ if (index > config->index_max)
+ {
+ config->index_max = index;
+ }
+
+ if (index < config->index_min)
+ {
+ config->index_min = index;
+ }
+ }
+ }
+
+ /* 非空目录最大索引要加一 */
+ if (!first)
+ {
+ config->index_max++;
+ }
+
+ closedir(dir);
+ }
+
+ return E_NONE;
+}
+
+/* 删除最小索引文件 */
+void _csg_file_fifo_delete_by_min_index(csg_file_fifo_t *config)
+{
+ char filename[512];
+
+ snprintf(filename, sizeof(filename), "%s/%ld", config->dir, config->index_min);
+ remove(filename);
+
+ /* 更新最小索引 */
+ config->index_min++;
+}
+
/* 普通命令发送平台线程 */
void *_csg_send_cmd_handle(void *arg)
{
@@ -1418,10 +1869,17 @@ void *_csg_send_trend_handle(void *arg)
}
/* 响应其他报文 */
- if (csg.send_cb)
- {
- csg.send_cb(recv_msg->type, recv_msg->slot, recv_msg->data);
- }
+ if (csg.is_connect)
+ {
+ if (csg.send_cb)
+ {
+ csg.send_cb(recv_msg->type, recv_msg->slot, recv_msg->data);
+ }
+ }
+ else
+ {
+ csg.trend_write_file_cb(recv_msg->slot, recv_msg->data);
+ }
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
XFREE(MTYPE_CSG, recv_msg->data);
@@ -1451,10 +1909,17 @@ void *_csg_send_event_handle(void *arg)
}
/* 响应其他报文 */
- if (csg.send_cb)
- {
- csg.send_cb(recv_msg->type, recv_msg->slot, recv_msg->data);
- }
+ if (csg.is_connect)
+ {
+ if (csg.send_cb)
+ {
+ csg.send_cb(recv_msg->type, recv_msg->slot, recv_msg->data);
+ }
+ }
+ else
+ {
+ csg.event_write_file_cb(recv_msg->slot, recv_msg->data);
+ }
/* 释放数据内存, 注意一定要在 fifo_push 之前调用, 因为 fifo_push 后 recv_msg 已被释放. */
XFREE(MTYPE_CSG, recv_msg->data);
@@ -1463,6 +1928,48 @@ void *_csg_send_event_handle(void *arg)
return NULL;
}
+
+void *_csg_boosterpack_handle(void *arg)
+{
+ char filepath[260];
+ int32_t len = 0;
+
+ /* 等待初始化完成 */
+ while(!is_system_init)
+ {
+ sleep(1);
+ }
+
+ while (1)
+ {
+ sleep(1);
+
+ if (!csg.is_connect)
+ {
+ continue;
+ }
+
+ /* 事件重发 */
+ len = sizeof(_csg_event);
+ if (E_NONE == file_fifo_read(&csg.event_file, (char*)(&_csg_event), &len))
+ {
+ if (E_NONE == _csg_event_file_send())
+ {
+ file_fifo_delete_by_min_index(&csg.event_file);
+ }
+ continue;
+ }
+
+ /* 趋势重发 */
+ snprintf(filepath, sizeof(filepath), "%s/%ld", csg.trend_file.dir, csg.trend_file.index_min);
+ if (E_NONE == _csg_trend_file_send(filepath))
+ {
+ _csg_file_fifo_delete_by_min_index(&csg.trend_file);
+ }
+ }
+ return NULL;
+}
+
/* 后台接收处理函数. */
void *_csg_recv_handle(void *arg)
@@ -1681,7 +2188,17 @@ int32_t csg_handle_init_after(void)
sem_init(&csg.event_booster_sem, 0, 0);
sem_init(&csg.trend_booster_sem, 0, 0);
+ snprintf(csg.event_file.dir, FILE_FIFO_PATH_LEN, "%s", CSG_EVENT_NAME);
+ csg.event_file.files_max = pd_config.config.event_storage;
+ file_fifo_init(&csg.event_file);
+
+ snprintf(csg.trend_file.dir, CSG_FILE_FIFO_PATH_LEN, "%s", CSG_TREND_NAME);
+ csg.trend_file.files_max = pd_config.config.trend_storage;
+ _csg_file_fifo_init(&csg.trend_file);
+
csg.send_cb = _csg_send_process;
+ csg.event_write_file_cb = _csg_event_write_file;
+ csg.trend_write_file_cb = _csg_trend_write_file;
param.arg = NULL;
param.log_module = LOG_CSG;
diff --git a/app/lib/a_process/pd_main.c b/app/lib/a_process/pd_main.c
index fe35d8b..63647d4 100755
--- a/app/lib/a_process/pd_main.c
+++ b/app/lib/a_process/pd_main.c
@@ -625,6 +625,7 @@ int32_t pd_main(void)
rv |= dau_handle_init();
rv |= csg_handle_init();
rv |= debug_handle_init();
+ rv |= modbus_handle_init();
return E_NONE;
}
diff --git a/app/lib/a_process/pd_modbus.c b/app/lib/a_process/pd_modbus.c
index bccf3a1..5fb0bbd 100755
--- a/app/lib/a_process/pd_modbus.c
+++ b/app/lib/a_process/pd_modbus.c
@@ -15,8 +15,7 @@
/* Private variables ---------------------------------------------------------*/
modbus_t modbus;
-int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id,
- uint16_t start_addr, uint16_t data_num)
+int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id, uint16_t start_addr, uint16_t data_num)
{
int txlen = 0;
int rxlen = 0;
@@ -37,7 +36,7 @@ int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id,
pdata[datalen++] = data_num & 0xFF; // 数据数量低字节
txlen = datalen + sizeof(modbus_tcp_t);
-
+
// 发送请求帧
GPIO_485BUS(WRITE);
if (serial_write(modbus.fd, modbus.txbuf, txlen) < 0)
@@ -45,7 +44,7 @@ int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id,
DBG(DBG_M_PD_MODBUS_ERR, "Modbus write error\r\n");
return E_ERROR;
}
- DBG(DBG_M_PD_MODBUS_ERR, "Modbus write len = %d\r\n", txlen);
+ DBG(DBG_M_PD_MODBUS, "Modbus write len = %d\r\n", txlen);
buf_print((char *)modbus.txbuf, txlen);
// 等待传输完成
@@ -55,11 +54,17 @@ int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id,
rxlen = serial_read(modbus.fd, modbus.rxbuf, sizeof(modbus.rxbuf));
if (rxlen > 0)
{
- DBG(DBG_M_PD_MODBUS_ERR, "Modbus read len = %d\r\n", rxlen);
+ DBG(DBG_M_PD_MODBUS, "Modbus read len = %d\r\n", rxlen);
buf_print((char *)modbus.rxbuf, rxlen);
+ uint16_t trans_id = (modbus.rxbuf[0] << 8) + modbus.rxbuf[1];
+ if (trans_id == transaction_id
+ && modbus.rxbuf[POS_UINT_ID] == unit_id)
+ {
+ return E_NONE;
+ }
}
- return E_NONE;
+ return E_ERROR;
}
int32_t _modbus_rtu_transaction(void)
@@ -97,8 +102,61 @@ int32_t _modbus_rtu_transaction(void)
return E_NONE;
}
+int32_t _modbus_get_device_type(uint8_t unit, uint16_t *type)
+{
+ uint16_t device_type = 0;
+ if (!_modbus_tcp_transaction(5, unit, MODBUS_DEVICE_TYPE_ADDR, 1))
+ {
+ device_type = modbus.rxbuf[9] << 8;
+ device_type += modbus.rxbuf[10];
+ }
+ *type = device_type;
+ return E_NONE;
+}
+
+int32_t _modbus_get_current(uint8_t unit, uint16_t addr, uint16_t len, uint32_t *current)
+{
+ uint32_t cur = 0;
+ if (!_modbus_tcp_transaction(5, unit, addr, len))
+ {
+ //cur = modbus.rxbuf[9] << 24;
+ //cur += modbus.rxbuf[10] << 16;
+ //cur += modbus.rxbuf[11] << 8;
+ //cur += modbus.rxbuf[12];
+ memcpy(&cur, &modbus.rxbuf[9], sizeof(uint32_t));
+ }
+ *current = cur;
+ return E_NONE;
+}
+
+void _modbus_read_slot_stat(stat_t *pstat)
+{
+ stat_t *ptmp = pstat;
+ for (int slot = 0; slot < MAX_SLOT; slot++)
+ {
+ //pstat[slot].status = 0;
+ ptmp->status = 0;
+ ptmp++;
+ }
+
+ ptmp = pstat;
+ gpio_val_get(gpio_dau1_idx, &ptmp->status);
+ ptmp++;
+ gpio_val_get(gpio_dau2_idx, &ptmp->status);
+ ptmp++;
+ gpio_val_get(gpio_dau3_idx, &ptmp->status);
+ ptmp++;
+ gpio_val_get(gpio_dau4_idx, &ptmp->status);
+ ptmp++;
+ gpio_val_get(gpio_dau5_idx, &ptmp->status);
+ ptmp++;
+ gpio_val_get(gpio_dau6_idx, &ptmp->status);
+}
+
+
void *_modbus_send_handle()
{
+ stat_t *pstat = NULL;
while (1)
{
#if 0
@@ -115,9 +173,30 @@ void *_modbus_send_handle()
}
}
#else
- //_modbus_rtu_transaction();
-
- _modbus_tcp_transaction(5, MODBUS_UNIT_IR, MODBUS_IR_CURRENT_ADDR, MODBUS_IR_CURRENT_LEN);
+ pstat = modbus.stat;
+ _modbus_read_slot_stat(pstat);
+
+ for (int slot = 0; slot < MAX_SLOT; slot++)
+ {
+ if (pstat->status)
+ {
+ _modbus_get_device_type(pstat->unit_id, &pstat->type);
+
+ if (DEVICE_IR_TYPE == pstat->type)
+ {
+ _modbus_get_current(pstat->unit_id,
+ MODBUS_IR_CURRENT_ADDR, MODBUS_IR_CURRENT_LEN, &pstat->current);
+ DBG(DBG_M_PD_MODBUS, "current:%d\n", pstat->current);
+ }
+ else if (DEVICE_DC_TYPE == pstat->type)
+ {
+ _modbus_get_current(pstat->unit_id,
+ MODBUS_DC_CURRENT_ADDR, MODBUS_DC_CURRENT_LEN, &pstat->current);
+ }
+ }
+ pstat++;
+ }
+
#endif
sleep(2);
}
@@ -132,6 +211,10 @@ void *_modbus_send_handle()
int32_t modbus_handle_init(void)
{
memset(&modbus, 0, sizeof(modbus));
+ for (int slot = 0; slot < MAX_SLOT; slot++)
+ {
+ modbus.stat[slot].unit_id = slot + 1;
+ }
modbus.fd = -1;
return E_NONE;
}
diff --git a/app/lib/m_management/dbg.c b/app/lib/m_management/dbg.c
index e477dc3..8b0b842 100755
--- a/app/lib/m_management/dbg.c
+++ b/app/lib/m_management/dbg.c
@@ -73,8 +73,10 @@ dbg_module_t _dbg_module[DBG_M_COUNT] =
{DBG_M_PD_HF, FALSE, "pd_hf"},
{DBG_M_PD_HF_ERR, TRUE, "pd_hf_err"},
{DBG_M_SERIAL, TRUE, "serial"},
- {DBG_M_PD_MODBUS, TRUE, "pd_modbus"},
- {DBG_M_PD_MODBUS_ERR, TRUE, "pd_modbus_err"},
+ {DBG_M_PD_MODBUS, FALSE, "pd_modbus"},
+ {DBG_M_PD_MODBUS_ERR, FALSE, "pd_modbus_err"},
+ {DBG_M_FILE_FIFO, TRUE, "file_fifo"},
+ {DBG_M_FILE_FIFO_ERR, TRUE, "file_fifo_err"},
};
/* Private function prototypes -----------------------------------------------*/
diff --git a/app/lib/m_management/file_fifo.c b/app/lib/m_management/file_fifo.c
new file mode 100755
index 0000000..d7b4d52
--- /dev/null
+++ b/app/lib/m_management/file_fifo.c
@@ -0,0 +1,243 @@
+/******************************************************************************
+ * file lib/management/file_fifo.c
+ * author YuLiang
+ * version 1.0.0
+ * date 10-Jun-2025
+ * brief This file provides all the file fifo operation functions.
+ *
+ ******************************************************************************
+ * Attention
+ *
+ * © COPYRIGHT(c) 2025 LandPower
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of LandPower nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* 标准C库头文件. */
+#include
+#include
+#include
+#include
+
+/* 用户代码头文件. */
+#include
+
+/* Private define ------------------------------------------------------------*/
+
+/* Private macro -------------------------------------------------------------*/
+
+/* Private typedef -----------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Internal functions --------------------------------------------------------*/
+/* 创建目录 */
+int32_t _file_fifo_dir_create(char *dir)
+{
+ uint32_t i = 0;
+ uint32_t len = 0;
+
+ len = strlen(dir);
+
+ /* 循环创建前级目录 */
+ for(i = 0; i < len; i++)
+ {
+ if(dir[i] == '/')
+ {
+ dir[i] = '\0';
+ if(access(dir, 0) != 0)
+ {
+ mkdir(dir, 744);
+ }
+ dir[i] ='/';
+ }
+ }
+
+ /* 创建最后级目录 */
+ if(len > 0 && access(dir, 0) != 0)
+ {
+ mkdir(dir, 744);
+ }
+
+ return E_NONE;
+}
+
+/* Interface functions -------------------------------------------------------*/
+/* 写函数 */
+int32_t file_fifo_write(file_fifo_t *config, const char *content, int32_t len)
+{
+ FILE *fp = NULL;
+ char filename[512];
+ int32_t size = 0;
+
+ if (config->index_max - config->index_min >= config->files_max)
+ {
+ return E_FULL;
+ }
+
+ /* 确认文件名 */
+ snprintf(filename, sizeof(filename), "%s/%ld", config->dir, config->index_max);
+
+ /* 写入文件 */
+ fp = fopen(filename, "w+");
+ if (!fp)
+ {
+ DBG(DBG_M_FILE_FIFO_ERR, "Open %s ERROR\r\n", filename);
+ return E_SYS_CALL;
+ }
+
+ size = fwrite(content, 1, len, fp);
+ if (size != len)
+ {
+ fclose(fp);
+ DBG(DBG_M_FILE_FIFO_ERR, "Write %s ERROR\r\n", filename);
+ return E_SYS_CALL;
+ }
+ fclose(fp);
+
+ config->index_max++;
+ return E_NONE;
+}
+
+/* 读函数 */
+int32_t file_fifo_read(file_fifo_t *config, char *content, int32_t *len)
+{
+ FILE *fp = NULL;
+ char filename[512];
+ int32_t size = 0;
+
+ if (config->index_max == config->index_min)
+ {
+ return E_EMPTY;
+ }
+
+ /* 确认文件名 */
+ snprintf(filename, sizeof(filename), "%s/%ld", config->dir, config->index_min);
+
+ /* 打开文件 */
+ fp = fopen(filename, "r");
+ if (!fp)
+ {
+ file_fifo_delete_by_min_index(config);
+ DBG(DBG_M_FILE_FIFO_ERR, "Open %s ERROR\r\n", filename);
+ return E_SYS_CALL;
+ }
+
+ size = fread(content, 1, *len, fp);
+ if (size <= 0)
+ {
+ fclose(fp);
+ file_fifo_delete_by_min_index(config);
+ DBG(DBG_M_FILE_FIFO_ERR, "Read %s ERROR\r\n", filename);
+ return E_SYS_CALL;
+ }
+ *len = size;
+ fclose(fp);
+
+ return E_NONE;
+}
+
+/* 删除最小索引文件 */
+void file_fifo_delete_by_min_index(file_fifo_t *config)
+{
+ char filename[512];
+
+ snprintf(filename, sizeof(filename), "%s/%ld", config->dir, config->index_min);
+ remove(filename);
+
+ /* 更新最小索引 */
+ config->index_min++;
+}
+
+/* 初始化最大最小索引, 这套接口不能在不同线程同时调用, 例如 write 接口只能在单一线程调用, read可以在另一个线程调用,
+ 但是 write 接口不能同时在两个线程调用 */
+int32_t file_fifo_init(file_fifo_t *config)
+{
+ DIR *dir = opendir(config->dir);
+ struct dirent *entry;
+ uint8_t first = 1;
+ int64_t index = 0;
+
+ config->index_max = 0;
+ config->index_min = 0;
+
+ if (!dir)
+ {
+ /* 创建目录 */
+ _file_fifo_dir_create(config->dir);
+ }
+ else
+ {
+ /* 初始化最大最小 index */
+ while ((entry = readdir(dir)) != NULL)
+ {
+ if (entry->d_type != DT_REG)
+ {
+ continue;
+ }
+
+ if (!isdigit(entry->d_name[0]))
+ {
+ continue;
+ }
+
+ index = strtoll(entry->d_name, NULL, 10);
+ if (first)
+ {
+ config->index_max = config->index_min = index;
+ first = 0;
+ }
+ else
+ {
+ if (index > config->index_max)
+ {
+ config->index_max = index;
+ }
+
+ if (index < config->index_min)
+ {
+ config->index_min = index;
+ }
+ }
+ }
+
+ /* 非空目录最大索引要加一 */
+ if (!first)
+ {
+ config->index_max++;
+ }
+
+ closedir(dir);
+ }
+
+ return E_NONE;
+}
+/************************ (C) COPYRIGHT LandPower ***** END OF FILE ****************/
diff --git a/app/lib/z_hardware/hwgpio.c b/app/lib/z_hardware/hwgpio.c
index c0a3f9b..b2c9495 100755
--- a/app/lib/z_hardware/hwgpio.c
+++ b/app/lib/z_hardware/hwgpio.c
@@ -56,6 +56,13 @@
static array_t *gpios = NULL;
int32_t gpio_485bus_idx;
+int32_t gpio_dau1_idx;
+int32_t gpio_dau2_idx;
+int32_t gpio_dau3_idx;
+int32_t gpio_dau4_idx;
+int32_t gpio_dau5_idx;
+int32_t gpio_dau6_idx;
+
/* Private function prototypes -----------------------------------------------*/
@@ -329,6 +336,9 @@ int32_t gpio_export(uint16_t gpio)
int32_t gpio_init(void)
{
gpios = array_init(ARRAY_MIN_SIZE, MTYPE_GPIO);
+
+ cmd_install_element(COMMON_NODE, &gpio_show_cmd);
+
gpio_485bus_idx = gpio_export(GPIO_485_BUS);
if (gpio_485bus_idx < 0)
{
@@ -336,6 +346,54 @@ int32_t gpio_init(void)
return E_BAD_PARAM;
}
LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_485bus_idx, GPIO_DIR_OUT));
+
+ gpio_dau1_idx = gpio_export(GPIO_DAU1);
+ if (gpio_dau1_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau1_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau1_idx, GPIO_DIR_IN));
+
+ gpio_dau2_idx = gpio_export(GPIO_DAU2);
+ if (gpio_dau2_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau2_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau2_idx, GPIO_DIR_IN));
+
+ gpio_dau3_idx = gpio_export(GPIO_DAU3);
+ if (gpio_dau3_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau3_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau3_idx, GPIO_DIR_IN));
+
+ gpio_dau4_idx = gpio_export(GPIO_DAU4);
+ if (gpio_dau4_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau4_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau4_idx, GPIO_DIR_IN));
+
+ gpio_dau5_idx = gpio_export(GPIO_DAU5);
+ if (gpio_dau5_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau5_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau5_idx, GPIO_DIR_IN));
+
+ gpio_dau6_idx = gpio_export(GPIO_DAU6);
+ if (gpio_dau6_idx < 0)
+ {
+ DBG(DBG_M_GPIO, "ERROR return %d!\r\n", gpio_dau6_idx);
+ return E_BAD_PARAM;
+ }
+ LD_E_RETURN(DBG_M_GPIO, gpio_dir_set(gpio_dau6_idx, GPIO_DIR_IN));
return E_NONE;
}