Ver código fonte

Работа с архивом/журналом и тестовыми скриптами.

TelenkovDmitry 9 meses atrás
pai
commit
4f1e503f3e

+ 83 - 66
fw/modules/log/log.c

@@ -14,12 +14,15 @@
 #define DBG if(1)
 
 
-
 static struct ringfs fs_log;
 struct ringfs fs_archive;
 
 SemaphoreHandle_t log_mutex;
 
+uint16_t log_entries_capacity;
+uint16_t archive_entries_capacity;
+
+
 
 //
 static int op_sector_erase(struct ringfs_flash_partition *flash, int address) {
@@ -107,6 +110,10 @@ void log_init(bool format)
 
 	log_mutex = xSemaphoreCreateMutex();
 
+    log_entries_capacity = ringfs_capacity(&fs_log);
+    
+    archive_entries_capacity = ringfs_capacity(&fs_archive);
+      
 	//xTaskCreate(log_task, ( char * ) "log_task", configMINIMAL_STACK_SIZE * 2, NULL, tskIDLE_PRIORITY, NULL);
 }
 
@@ -183,6 +190,18 @@ int log_append(void *entry, entry_type_t entry_type)
     
 }
 
+//
+uint16_t log_capacity(void)
+{
+    return ringfs_count_estimate(&fs_log);
+}
+
+//
+uint16_t log_arch_capacity(void)
+{
+    return ringfs_count_estimate(&fs_archive);
+}
+
 // -------------------------------------------------------------------------- //
 // misc
 
@@ -209,68 +228,91 @@ uint8_t crc_8(uint8_t *data, int length)
 // -------------------------------------------------------------------------- //
 // Tests
 
-#if 0
-// fs_log
-int log_test(void)
+// val - 0 - журнал
+// val - 1 - архив
+void log_info(uint8_t val)
 {
-    int ret;
+    if (val > 1)
+        return;
+  
+    struct ringfs *fs = val == 0 ? &fs_log : &fs_archive;
     
-}
-#endif
-
-
-// fs_archive
-int test_archive(void)
-{
-    int ret;
-    archive_entry_t entry;
     int capacity_flash = 0;
     int count_flash = 0;
+    int count_estimate = 0;
     
-    capacity_flash = ringfs_capacity(&fs_archive);
-    count_flash = ringfs_count_exact(&fs_archive);
-      
-    DBG printf("Fetching...\r\n");
-    
-    
+    capacity_flash = ringfs_capacity(fs);
+    count_flash = ringfs_count_exact(fs);
+    count_estimate = ringfs_count_estimate(fs);
     
-    if (log_fetch(&entry, ARCHIVE_ENTRY, portMAX_DELAY)) 
+    if (val == 0)
     {
-        printf("%" PRId64 "\n", entry.timestamp);
+        DBG printf("Log partition capasity: %u\r\n", capacity_flash);
+        DBG printf("Count log entry: %u\r\n", count_flash);
+        DBG printf("Estimate count: %u\r\n", count_estimate);
     }
     else 
     {
-        DBG printf("fail\r\n");
+        DBG printf("Archive partition capasity: %u\r\n", capacity_flash);
+        DBG printf("Count archive entry: %u\r\n", count_flash);
+        DBG printf("Estimate count: %u\r\n", count_estimate);
     }
-#if 0    
-    DBG printf("Discarding\r\n");
-    if (log_discard)
-#endif    
-    return 0;
 }
 
-
+// val - 0 - журнал
+// val - 1 - архив
+void log_format(uint8_t val)
+{
+    if (val == 0) {
+        DBG printf("Formating log partition...\r\n");
+        ringfs_format(&fs_log);
+    } 
+    else if (val == 1) {
+        DBG printf("Formating archive partition...\r\n");
+        ringfs_format(&fs_archive);
+    }
+}
 
 // Добавить n архивных записей
-int test_add_random_archive_entry(uint32_t cnt_entry)
+int log_add_random_entry(uint8_t val, uint32_t cnt_entry)
 {
     int ret;
-    archive_entry_t entry = {0};
-    static uint32_t index = 0;
+    log_entry_t log_entry = {0};
+    archive_entry_t archive_entry = {0};
     
-    DBG printf("Try append %u archive entry\r\n", cnt_entry);
-
-    for (uint32_t i = 0; i < cnt_entry; i++)
+    static uint8_t log_index = 0;
+    static uint32_t archive_index = 0;
+    
+    if (val == 0)
     {
-        //entry.input_value = ringfs_count_exact(&fs_archive);
-        entry.input_value = index++;
+        DBG printf("Appending %u archive entries\r\n", cnt_entry);
         
-        ret = log_append(&entry, ARCHIVE_ENTRY);
+        for (uint32_t i = 0; i < cnt_entry; i++)
+        {
+            log_entry.code_type = log_index++;
+            log_entry.code_type = log_index++;
+            log_entry.code_type = log_index++;
+            log_entry.value = (float)log_index++;
+            
+            ret = log_append((void*)&log_entry, LOG_ENTRY);
+        }
+        DBG printf("Result: %u\r\n", ret);
     }
-    return ret;
-}
+      
+    if (val == 1)
+    {
+        DBG printf("Appending %u archive entries\r\n", cnt_entry);
 
+        for (uint32_t i = 0; i < cnt_entry; i++)
+        {
+            archive_entry.input_value = archive_index++;
 
+            ret = log_append((void*)&archive_entry, ARCHIVE_ENTRY);
+        }
+        DBG printf("Result: %u\r\n", ret);
+    }
+    return ret;
+}
 
 //
 void test_fetch(void)
@@ -281,34 +323,9 @@ void test_fetch(void)
     printf("[entry] timestamp = % " PRId64 ", value = %u, crc = %u\r\n", entry.timestamp, entry.input_value, entry.crc);
 }
 
-//
-void test_archive_info(void)
-{
-    int capacity_flash = 0;
-    int count_flash = 0;
-    int count_estimate = 0;
-    
-    capacity_flash = ringfs_capacity(&fs_archive);
-    count_flash = ringfs_count_exact(&fs_archive);
-    count_estimate = ringfs_count_estimate(&fs_archive);
-    
-    printf("Archive partition capasity: %u\r\n", capacity_flash);
-    printf("Count archive entry: %u\r\n", count_flash);
-    printf("Estimate count: %u\r\n", count_estimate);
-}
 
-//
-void test_archive_format(void)
-{
-    ringfs_format(&fs_archive);
-}
 
-//
-void test_print_all_archive(void)
-{
-    test_archive_info();
-    
-}
+
 
 
 

+ 34 - 11
fw/modules/log/log.h

@@ -4,7 +4,10 @@
 #include "at32f403a_407.h"
 #include <stdbool.h>
 
-
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
 #define LOG_ENTRY_VERSION               1
 
 #define ARCHIV_ENTRY_VERSION            1
@@ -59,23 +62,28 @@ typedef enum
 } entry_type_t;
 
 
+//
 typedef __packed struct 
 {
     uint64_t timestamp;
     
 } common_entry_t;
 
-//
+
+// Структура записи журанала
 typedef __packed struct 
 {
 	uint64_t timestamp;
-	log_type_t type:8;
-	char data[50];
+    uint8_t code_type;  // код типа события
+    uint8_t code_state; // код состояния
+    uint8_t channel_number; // номер канала
+    float value;        // значение
     uint8_t crc;
     
 } log_entry_t;
 
 
+// Структура архивной записи
 typedef __packed struct
 {
     uint64_t timestamp;
@@ -97,6 +105,11 @@ int log_discard(void *entry, entry_type_t entry_type, uint32_t timeout);
 // 
 int log_append(void *entry, entry_type_t entry_type);
 
+//
+uint16_t log_capacity(void);
+
+//
+uint16_t log_arch_capacity(void);
 
 // -------------------------------------------------------------------------- //
 // misc
@@ -106,17 +119,14 @@ uint8_t crc_8(uint8_t *data, int length);
 // -------------------------------------------------------------------------- //
 // Tests
 
-// fs_log
-int log_test(void);
-
-// fs_archive
-int test_archive(void);
+//
+void log_info(uint8_t val);
 
 //
-int test_add_random_archive_entry(uint32_t cnt_entry);
+void log_format(uint8_t val);
 
 //
-void test_archive_info(void);
+int log_add_random_entry(uint8_t val, uint32_t cnt_entry);
 
 //
 void test_fetch(void);
@@ -124,6 +134,19 @@ void test_fetch(void);
 //
 void test_archive_format(void);
 
+// -------------------------------------------------------------------------- //
+
+extern uint16_t log_entries_capacity;
+extern uint16_t archive_entries_capacity;
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
 
 #if 0
 

+ 4 - 3
fw/modules/log/log_api.c

@@ -62,10 +62,10 @@ int mb_log_get_entry(uint8_t *buf, uint16_t entry_index)
     buf[2] = 0x06;  // Reference type
     
     log_get_entry(entry_index, &fs_archive, &archive_entry);
-    
+#if 0    
     printf("[entry] timestamp = % " PRId64 ", value = %u, crc = %u\r\n", 
            archive_entry.timestamp, archive_entry.input_value, archive_entry.crc);
-    
+#endif    
     memcpy(&buf[3], &archive_entry, sizeof(archive_entry_t));
     pack_len += sizeof(archive_entry_t);
     
@@ -73,4 +73,5 @@ int mb_log_get_entry(uint8_t *buf, uint16_t entry_index)
     buf[1] = pack_len; // File Resp. length, 1 byte
     
     return pack_len;
-}
+}
+

+ 1 - 1
fw/modules/log/log_api.h

@@ -10,7 +10,7 @@
 void log_get_entry_count(void);
 
 //
-int log_get_entry(uint32_t index, struct ringfs *fs, void *entry);
+int log_get_archive_entry(uint32_t index, struct ringfs *fs, void *entry);
 
 //
 int mb_log_get_entry(uint8_t *buf, uint16_t entry_index);

+ 398 - 323
fw/modules/modbus/modbus_params.c

@@ -1,323 +1,398 @@
-#include "at32f403a_407.h"
-#include "modbus_params.h"
-#include "settings_api.h"
-#include "io.h"
-#include "uptime.h"
-#include "rtc.h"
-#include "input.h"
-#include "output.h"
-#include <string.h>
-
-
-mb_param_t mb_param[MB_PARAM_MAX];
-
-uint32_t rtc_sinhro;
-
-void get_time(uint8_t* buf, uint8_t size);
-void get_din_mode(uint8_t* buf, uint8_t size);
-
-
-//
-void mb_init_params(void)
-{
-    uint16_t index = 0;
-    uint16_t addr = 0;
-    
-    mb_param[index].reg = 0x0100;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&input_state_bit;  // Текущее состояние входа
-	mb_param[index].set = NULL;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
-        
-    // Счетчики импульсов. Регистры 0x0102 - 0x0111
-    addr = 0x0102;
-    for (int i = 0; i < DI_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 2;
-        mb_param[index].param = (uint8_t*)&input_cnt[i];  // Счетчик ипульсов
-        mb_param[index].set = NULL;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr += 2;
-        index++;
-    } 
-    
-    // Режим работы входов
-    mb_param[index].reg = 0x0120;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&settings.di_mode_bits;  
-	mb_param[index].set = mb_set_din_mode;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
-    
-    // Нормальное состояние входов
-    mb_param[index].reg = 0x0122;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&settings.di_norm_state_bits;  
-	mb_param[index].set = NULL;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
- 
-    // Счетчики импульсов. Регистры 0x0102 - 0x0111
-    addr = 0x0124;
-    for (int i = 0; i < DI_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&settings.di_debounce[i];  // Счетчик ипульсов
-        mb_param[index].set = NULL;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr++;
-        index++;
-    }
-    
-    // Текущее состояние выходов
-    mb_param[index].reg = 0x0200;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&output_state_bit;  
-	mb_param[index].set = mb_set_do;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
-    
-    // Режим работы выходов
-    mb_param[index].reg = 0x0202;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&output_mode_bit;  
-	mb_param[index].set = mb_set_do_mode;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
-    
-    // Состояние выходов в безопасном режиме
-    mb_param[index].reg = 0x0203;
-	mb_param[index].size = 1;
-	mb_param[index].param = (uint8_t*)&settings.do_save_bits;  
-	mb_param[index].set = mb_set_do;
-    mb_param[index].get = NULL;
-    mb_param[index].check_handler = mb_check_dummy;
-    
-    index++;
-    
-    // Заполнение PWM. Регистры 0x0210 - 0x0217
-    addr = 0x0210;
-    for (int i = 0; i < DO_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&output_pwm[i];  // Счетчик ипульсов
-        mb_param[index].set = mb_set_do;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr++;
-        index++;
-    }
-    
-    // Заполнение PWM в безопасном режиме. Регистры 0x0220 - 0x0227
-    addr = 0x0220;
-    for (int i = 0; i < DO_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&output_pwm_save[i];  // Счетчик ипульсов
-        mb_param[index].set = mb_set_do;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr++;
-        index++;
-    }
-    
-    // Период PWM. Регистры 0x0220 - 0x0227
-    addr = 0x0230;
-    for (int i = 0; i < DO_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&output_pwm_period[i];  // Счетчик ипульсов
-        mb_param[index].set = mb_set_do;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr++;
-        index++;
-    }
-    
-    // Период PWM. Регистры 0x0220 - 0x0227
-    addr = 0x0240;
-    for (int i = 0; i < DO_NUMBER; i++)
-    {
-        mb_param[index].reg = addr;
-        mb_param[index].size = 1;
-        mb_param[index].param = (uint8_t*)&output_pwm_period_save[i];  // Счетчик ипульсов
-        mb_param[index].set = mb_set_do;
-        mb_param[index].get = NULL;
-        mb_param[index].check_handler = mb_check_dummy;
-        
-        addr++;
-        index++;
-    }
-}
-
-
-// Возвращает размер параметра в регистрах
-bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size)
-{
-	for (uint16_t i = 0; i < MB_PARAM_MAX; i++)
-	{
-		if (mb_param[i].reg == reg)
-		{
-			*index = i;
-			*size = mb_param[i].size;
-			return true;
-		}
-	}
-	return false;
-}
-
-
-//
-mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index)
-{
-	uint8_t *ptr = mb_param[index].param;
-
-    // Если параметр только для чтения
-    if (mb_param[index].check_handler == NULL)
-        return MB_NO_ACTION;
-    
-	for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
-	{
-		*ptr = buf[2*mb_param[index].size - 1 - i];
-		ptr++;
-	}
-  
-/*    
-    if (mb_param[index].check_handler != NULL)
-        mb_param[index].check_handler();
-*/    
-    
-    mb_param[index].check_handler();
-    
-    if (mb_param[index].set != NULL)
-        return mb_param[index].set();
-    else
-        return MB_NO_ACTION;
-    
-/*    
-    if (mb_param[index].f_activity)
-        return mb_param[index].set_handler();
-    else
-        return MB_NO_ACTION;
-*/    
-}
-
-
-//
-void mb_get_param(uint8_t *buf, uint16_t index)
-{
-    uint8_t *ptr;
-	
-    if (mb_param[index].get != NULL) {
-        mb_param[index].get(buf, mb_param[index].size);
-        return;
-    }
-
-    ptr = mb_param[index].param + 2*mb_param[index].size - 1;
-
-	for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
-	{
-		*buf = *ptr;
-		buf++;
-		ptr--;
-	}
-}
-
-
-
-
-
-// -------------------------------------------------------------------------- //
-//                          Чтение параметров
-// -------------------------------------------------------------------------- //
-
-void get_time(uint8_t* buf, uint8_t size)
-{
-    uint32_t rtc_unix = RTC_GetUnixTime();
-    uint8_t *ptr = (uint8_t*)&rtc_unix + 2*size - 1;
-
-    for (uint16_t i = 0; i < 2*size; i++)
-	{
-		*buf = *ptr;
-		buf++;
-		ptr--;
-	}
-}
-
-//
-void get_din_mode(uint8_t* buf, uint8_t size)
-{
-    
-}
-
-// -------------------------------------------------------------------------- //
-//                          Установка параметров
-// -------------------------------------------------------------------------- //
-
-//
-mb_delay_action_t mb_set_din_mode(void)
-{
-    in_set();
-    return MB_NO_ACTION;
-}
-
-//
-mb_delay_action_t mb_set_do(void)
-{
-    //do_set();
-    do_set_common();
-    return MB_NO_ACTION;
-}
-
-//
-mb_delay_action_t mb_set_do_mode(void)
-{
-    do_set_mode();
-    return MB_NO_ACTION;
-}
-
-//
-mb_delay_action_t mb_set_time(void)
-{
-    TM_RTC_SetDataTimeUnix(rtc_sinhro);
-    
-    return MB_NO_ACTION;
-}
-
-
-
-// -------------------------------------------------------------------------- //
-//                      Проверка параметров                                   //
-// -------------------------------------------------------------------------- //
-
-//
-void mb_check_dummy(void)
-{
-}
-
-
-
-
+#include "at32f403a_407.h"
+#include "modbus_params.h"
+#include "settings_api.h"
+#include "io.h"
+#include "uptime.h"
+#include "rtc.h"
+#include "input.h"
+#include "output.h"
+#include "log.h"
+#include <string.h>
+
+
+mb_param_t mb_param[MB_PARAM_MAX];
+
+uint32_t rtc_sinhro;
+
+void get_time(uint8_t* buf, uint8_t size);
+void get_din_mode(uint8_t* buf, uint8_t size);
+
+void get_log_entries_number(uint8_t* buf, uint8_t size);
+void get_archive_entries_number(uint8_t* buf, uint8_t size);
+
+
+
+
+//
+void mb_init_params(void)
+{
+    uint16_t index = 0;
+    uint16_t addr = 0;
+    
+    mb_param[index].reg = 0x0100;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&input_state_bit;  // Текущее состояние входа
+	mb_param[index].set = NULL;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+        
+    // Счетчики импульсов. Регистры 0x0102 - 0x0111
+    addr = 0x0102;
+    for (int i = 0; i < DI_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 2;
+        mb_param[index].param = (uint8_t*)&input_cnt[i];  // Счетчик ипульсов
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr += 2;
+        index++;
+    } 
+    
+    // Режим работы входов
+    mb_param[index].reg = 0x0120;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&settings.di_mode_bits;  
+	mb_param[index].set = mb_set_din_mode;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Нормальное состояние входов
+    mb_param[index].reg = 0x0122;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&settings.di_norm_state_bits;  
+	mb_param[index].set = NULL;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+ 
+    // Счетчики импульсов. Регистры 0x0102 - 0x0111
+    addr = 0x0124;
+    for (int i = 0; i < DI_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&settings.di_debounce[i];  // Счетчик ипульсов
+        mb_param[index].set = NULL;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr++;
+        index++;
+    }
+    
+    // Текущее состояние выходов
+    mb_param[index].reg = 0x0200;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&output_state_bit;  
+	mb_param[index].set = mb_set_do;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Режим работы выходов
+    mb_param[index].reg = 0x0202;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&output_mode_bit;  
+	mb_param[index].set = mb_set_do_mode;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Состояние выходов в безопасном режиме
+    mb_param[index].reg = 0x0203;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&settings.do_save_bits;  
+	mb_param[index].set = mb_set_do;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Заполнение PWM. Регистры 0x0210 - 0x0217
+    addr = 0x0210;
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&output_pwm[i];  // Счетчик ипульсов
+        mb_param[index].set = mb_set_do;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr++;
+        index++;
+    }
+    
+    // Заполнение PWM в безопасном режиме. Регистры 0x0220 - 0x0227
+    addr = 0x0220;
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&output_pwm_save[i];  // Счетчик ипульсов
+        mb_param[index].set = mb_set_do;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr++;
+        index++;
+    }
+    
+    // Период PWM. Регистры 0x0220 - 0x0227
+    addr = 0x0230;
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&output_pwm_period[i];  // Счетчик ипульсов
+        mb_param[index].set = mb_set_do;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr++;
+        index++;
+    }
+    
+    // Период PWM. Регистры 0x0220 - 0x0227
+    addr = 0x0240;
+    for (int i = 0; i < DO_NUMBER; i++)
+    {
+        mb_param[index].reg = addr;
+        mb_param[index].size = 1;
+        mb_param[index].param = (uint8_t*)&output_pwm_period_save[i];  // Счетчик ипульсов
+        mb_param[index].set = mb_set_do;
+        mb_param[index].get = NULL;
+        mb_param[index].check_handler = mb_check_dummy;
+        
+        addr++;
+        index++;
+    }
+    
+    // Журналы/рахивы
+    
+    // Емкость журнала (максимальная)
+    mb_param[index].reg = 0x0900;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&log_entries_capacity; // 
+	mb_param[index].set = NULL;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Текущее количество записей в журнале
+    mb_param[index].reg = 0x0901;
+	mb_param[index].size = 1;
+	mb_param[index].param = NULL; // 
+	mb_param[index].set = NULL;
+    mb_param[index].get = get_log_entries_number;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Емкость архива (максимальная)
+    mb_param[index].reg = 0x0902;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&archive_entries_capacity; // 
+	mb_param[index].set = NULL;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+    // Текущее количество записей в архиве
+    mb_param[index].reg = 0x0903;
+	mb_param[index].size = 1;
+	mb_param[index].param = NULL; // 
+	mb_param[index].set = NULL;
+    mb_param[index].get = get_archive_entries_number;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+    
+/*    
+    // Емкость архива (максимальная)
+    mb_param[index].reg = 0x0901;
+	mb_param[index].size = 1;
+	mb_param[index].param = (uint8_t*)&log_entries_capacity; // 
+	mb_param[index].set = NULL;
+    mb_param[index].get = NULL;
+    mb_param[index].check_handler = mb_check_dummy;
+    
+    index++;
+*/    
+}
+
+
+// Возвращает размер параметра в регистрах
+bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size)
+{
+	for (uint16_t i = 0; i < MB_PARAM_MAX; i++)
+	{
+		if (mb_param[i].reg == reg)
+		{
+			*index = i;
+			*size = mb_param[i].size;
+			return true;
+		}
+	}
+	return false;
+}
+
+
+//
+mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index)
+{
+	uint8_t *ptr = mb_param[index].param;
+
+    // Если параметр только для чтения
+    if (mb_param[index].check_handler == NULL)
+        return MB_NO_ACTION;
+    
+	for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
+	{
+		*ptr = buf[2*mb_param[index].size - 1 - i];
+		ptr++;
+	}
+  
+/*    
+    if (mb_param[index].check_handler != NULL)
+        mb_param[index].check_handler();
+*/    
+    
+    mb_param[index].check_handler();
+    
+    if (mb_param[index].set != NULL)
+        return mb_param[index].set();
+    else
+        return MB_NO_ACTION;
+    
+/*    
+    if (mb_param[index].f_activity)
+        return mb_param[index].set_handler();
+    else
+        return MB_NO_ACTION;
+*/    
+}
+
+
+//
+void mb_get_param(uint8_t *buf, uint16_t index)
+{
+    uint8_t *ptr;
+	
+    if (mb_param[index].get != NULL) {
+        mb_param[index].get(buf, mb_param[index].size);
+        return;
+    }
+
+    ptr = mb_param[index].param + 2*mb_param[index].size - 1;
+
+	for (uint16_t i = 0; i < 2*mb_param[index].size; i++)
+	{
+		*buf = *ptr;
+		buf++;
+		ptr--;
+	}
+}
+
+
+
+
+
+// -------------------------------------------------------------------------- //
+//                          Чтение параметров
+// -------------------------------------------------------------------------- //
+
+void get_time(uint8_t* buf, uint8_t size)
+{
+    uint32_t rtc_unix = RTC_GetUnixTime();
+    uint8_t *ptr = (uint8_t*)&rtc_unix + 2*size - 1;
+
+    for (uint16_t i = 0; i < 2*size; i++)
+	{
+		*buf = *ptr;
+		buf++;
+		ptr--;
+	}
+}
+
+//
+void get_din_mode(uint8_t* buf, uint8_t size)
+{
+    
+}
+
+//
+void get_log_entries_number(uint8_t* buf, uint8_t size)
+{
+    uint16_t capacity = log_capacity();
+    SWAP_16(buf, capacity);
+}
+
+//
+void get_archive_entries_number(uint8_t* buf, uint8_t size)
+{
+    uint16_t capacity = log_arch_capacity();
+    SWAP_16(buf, capacity);
+}
+
+
+// -------------------------------------------------------------------------- //
+//                          Установка параметров
+// -------------------------------------------------------------------------- //
+
+//
+mb_delay_action_t mb_set_din_mode(void)
+{
+    in_set();
+    return MB_NO_ACTION;
+}
+
+//
+mb_delay_action_t mb_set_do(void)
+{
+    //do_set();
+    do_set_common();
+    return MB_NO_ACTION;
+}
+
+//
+mb_delay_action_t mb_set_do_mode(void)
+{
+    do_set_mode();
+    return MB_NO_ACTION;
+}
+
+//
+mb_delay_action_t mb_set_time(void)
+{
+    TM_RTC_SetDataTimeUnix(rtc_sinhro);
+    
+    return MB_NO_ACTION;
+}
+
+
+
+// -------------------------------------------------------------------------- //
+//                      Проверка параметров                                   //
+// -------------------------------------------------------------------------- //
+
+//
+void mb_check_dummy(void)
+{
+}
+
+
+
+

+ 85 - 75
fw/modules/modbus/modbus_params.h

@@ -1,76 +1,86 @@
-#ifndef __MODBUS_PARAMS_H
-#define __MODBUS_PARAMS_H
-
-#include "mb.h"
-#include "mbport.h"
-#include "modbus.h"
-//#include "settings_sys.h"
-
-#include <stdbool.h>
-
-
-#define MB_PARAM_MAX			54
-
-
-//
-typedef struct {
-
-	uint16_t reg;
-	uint16_t size;
-	uint8_t *param;
-	bool f_activity;	
-	mb_delay_action_t (*set)(void);
-    void (*get)(uint8_t* buf, uint8_t size);
-    void (*check_handler)(void);
-
-} mb_param_t;
-
-
-//
-void mb_init_params(void);
-
-// Возвращает размер параметра в регистрах
-bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size);
-
-//
-mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index);
-
-//
-void mb_get_param(uint8_t *buf, uint16_t index);
-
-
-// Установка адреса. Запрос без параметров.
-bool mb_set_addr(uint8_t *buf, uint8_t *addr);
-
-// Установка адреса по ID
-bool mb_set_addr_id(uint8_t *buf, uint8_t *addr);
-
-// Установка адреса по серийному номеру
-bool mb_set_addr_serial(uint8_t *buf, uint8_t *addr);
-
-
-// -------------------------------------------------------------------------- //
-//                          Установка параметров
-// -------------------------------------------------------------------------- //
-
-//
-mb_delay_action_t mb_set_time(void);
-
-//
-mb_delay_action_t mb_set_din_mode(void);
-
-//
-mb_delay_action_t mb_set_do(void);
-
-//
-mb_delay_action_t mb_set_do_mode(void);
-
-// -------------------------------------------------------------------------- //
-//                      Проверка параметров                                   //
-// -------------------------------------------------------------------------- //
-
-//
-void mb_check_dummy(void);
-
-
+#ifndef __MODBUS_PARAMS_H
+#define __MODBUS_PARAMS_H
+
+#include "mb.h"
+#include "mbport.h"
+#include "modbus.h"
+//#include "settings_sys.h"
+
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define SWAP_16(x, y)   {x[0] = y >> 8; x[1] = y & 0x0FF;}
+  
+#define MB_PARAM_MAX			58//54
+
+
+//
+typedef struct {
+
+	uint16_t reg;
+	uint16_t size;
+	uint8_t *param;
+	bool f_activity;	
+	mb_delay_action_t (*set)(void);
+    void (*get)(uint8_t* buf, uint8_t size);
+    void (*check_handler)(void);
+
+} mb_param_t;
+
+
+//
+void mb_init_params(void);
+
+// Возвращает размер параметра в регистрах
+bool mb_find_param(uint16_t reg, uint16_t *index, uint16_t *size);
+
+//
+mb_delay_action_t mb_set_param(uint8_t *buf, uint16_t index);
+
+//
+void mb_get_param(uint8_t *buf, uint16_t index);
+
+
+// Установка адреса. Запрос без параметров.
+bool mb_set_addr(uint8_t *buf, uint8_t *addr);
+
+// Установка адреса по ID
+bool mb_set_addr_id(uint8_t *buf, uint8_t *addr);
+
+// Установка адреса по серийному номеру
+bool mb_set_addr_serial(uint8_t *buf, uint8_t *addr);
+
+
+// -------------------------------------------------------------------------- //
+//                          Установка параметров
+// -------------------------------------------------------------------------- //
+
+//
+mb_delay_action_t mb_set_time(void);
+
+//
+mb_delay_action_t mb_set_din_mode(void);
+
+//
+mb_delay_action_t mb_set_do(void);
+
+//
+mb_delay_action_t mb_set_do_mode(void);
+
+// -------------------------------------------------------------------------- //
+//                      Проверка параметров                                   //
+// -------------------------------------------------------------------------- //
+
+//
+void mb_check_dummy(void);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif // __MODBUS_PARAMS_H

+ 25 - 5
fw/modules/terminal/terminal_sbs.cpp

@@ -53,20 +53,32 @@ int SbsTerminal::execute(int argc, const char * const *argv)
         NVIC_SystemReset();
     }
     // ---------------------------------------------------------------------- //
-    // Archive API
-    
+    // Добавить N новых записей в журнал
+    if (strcmp(argv[0], "add_lentry") == 0) {
+        if (argc > 1)
+            log_add_random_entry(0, atoi(argv[1]));
+        else
+            printf("No record counter\r\n");
+        
+        return 0;
+    }
     // Добавить N новых записей в архив
     if (strcmp(argv[0], "add_aentry") == 0) {
         if (argc > 1)
-            test_add_random_archive_entry(atoi(argv[1]));
+            log_add_random_entry(1, atoi(argv[1]));
         else
             printf("No record counter\r\n");
         
         return 0;
     }
+    // Информация о журнале
+    if (strcmp(argv[0], "linfo") == 0) {
+        log_info(0);
+        return 0;
+    }
     // Информация об архиве
     if (strcmp(argv[0], "ainfo") == 0) {
-        test_archive_info();
+        log_info(1);
         return 0;
     }
     // Fetch archive entry
@@ -74,9 +86,14 @@ int SbsTerminal::execute(int argc, const char * const *argv)
         test_fetch();
         return 0;
     }
+    // Format log FS
+    if (strcmp(argv[0], "lformat") == 0) {
+        log_format(0);  
+        return 0;
+    }
     // Format archive FS
     if (strcmp(argv[0], "aformat") == 0) {
-        test_archive_format();  
+        log_format(1);  
         return 0;
     }
     // 
@@ -124,10 +141,13 @@ int SbsTerminal::help(int argc, const char * const *argv)
     printl ("You can use the following commands:");
     printl ("  version        Print software version");
     printl ("  reset          Reset");
+    printl ("  add_lentry     Add N log entries");
     printl ("  add_aentry     Add N archive entries");
+    printl ("  linfo          Print log info");
     printl ("  ainfo          Print archive info");
     printl ("  afetch         Fetch archive entry");
     printl ("  aentry         Get archive entry [position] [sector] [slot]");
+    printll("  lformat        Format log partition");
     printll("  aformat        Format archive partition");
     
     printeol();

+ 1 - 1
iap/modules/modbus/modbus.c

@@ -326,7 +326,7 @@ eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegi
 				{
 					MBDBG printf("reg: %X, index: %u, size: %u\r\n", iRegIndex, index_param, size);
                     MBDBG printf("reg: %X\r\n", iRegIndex);
-					mb_get_param(ptr_buf,  index_param); // Вызов функции записи
+					mb_get_param(ptr_buf,  index_param); // Вызов функции чтения
 					iRegIndex += size;
 					ptr_buf += 2*size;
 					regs_cnt -= size;

BIN
output/fw.bin


Diferenças do arquivo suprimidas por serem muito extensas
+ 378 - 377
project/ewarm/iap/iap.dep


Diferenças do arquivo suprimidas por serem muito extensas
+ 602 - 621
project/ewarm/module_universal_io.dep


+ 1 - 1
shared/freemodbus/functions/mbfuncfile.c

@@ -52,7 +52,7 @@ eMBException eMBFuncReadFileRecord( UCHAR * pucFrame, USHORT * usLen )
 {
     //*usLen += 1;
     
-    printf("usLen: %u\r\n", *usLen);
+    //printf("usLen: %u\r\n", *usLen);
   
     return eMBFuncReadFileRecordCB(pucFrame, usLen);
 }

BIN
tools/__pycache__/io_module.cpython-310.pyc


+ 4 - 5
tools/io_module.py

@@ -5,13 +5,11 @@ import time
 import os
 import struct
 
-ARCHIVE_ENTRY = 0x06
-LOG_ENTRY = 0x07
-
 reg_table = {'in_bits': 0x0100, 'in_cnt': 0x0102, 'in_mode': 0x0120, 'in_norm': 0x0122, 'in_deb_start': 0x124,
              'out_cur': 0x0200, 'out_mode': 0x0202, 'out_mode_save': 0x0203, 'pwm_duty': 0x0210,
              'pwm_duty_save': 0x0220, 'pwm_per': 0x0230, 'pwm_per_save': 0x0240, 
-             'rtc_unix': 0x0802, 'rtc_sinhro': 0x0804, 'uptime': 0x0800,}
+             'rtc_unix': 0x0802, 'rtc_sinhro': 0x0804, 'uptime': 0x0800, 'log_info': 0x0900, 
+             'log_ent': 0x0901, 'arch_cap': 0x0902, 'arch_ent': 0x0903}
 
 
 class IO_Module(Modbus):
@@ -216,13 +214,14 @@ class IO_Module(Modbus):
 
     def set_rtc(self, utc):
         self.write_uint32(reg_table['rtc_sinhro'], utc)
-
+    '''
     def get_archive_entryes(self, ent_num, ent_index):
         data = self.read_file_record(ARCHIVE_ENTRY, 1, 1)
         #print(struct.unpack('<Q', data[5:13]))
         entry = struct.unpack('<QBB', data[5:15])
         print(entry)
         return data
+    '''
 
 def main():
     colorama.init(autoreset=True)

+ 43 - 6
tools/log_reader.py

@@ -1,24 +1,54 @@
 from io_module import IO_Module
+from io_module import reg_table
+from colorama import Fore
+from random import randint
+from time import sleep
+import colorama
+import struct
+
+ARCHIVE_ENTRY = 0x06
+LOG_ENTRY = 0x07
 
 
 class LogReader(IO_Module):
-    def __init__(self) -> None:
-        pass
+    def __init__(self, tty: str, brate: int, address: int):
+        super().__init__(tty, brate, address)
+        colorama.init(autoreset=True)
+        self.log_capacity = 0
+        self.log_entries_number = 0
+        self.archive_capacity = 0
+        self.archive_entries_number = 0    
 
     def get_archive(self):
         print("LogReader")
 
+    def get_log_info(self):
+        data = self.read_holding_registers(reg_table['log_info'], 4)
+        self.log_capacity = data[0]
+        self.log_entries_number = data[1]
+        self.archive_capacity = data[2]
+        self.archive_entries_number = data[3]
+        print('Log capacity           :', Fore.CYAN + str(self.log_capacity))
+        print('Log entries number     :', Fore.CYAN + str(self.log_entries_number))
+        print('Archive capacity       :', Fore.CYAN + str(self.archive_capacity))
+        print('Archive entries number :', Fore.CYAN + str(self.archive_entries_number))
+
 
 class DigitalLogReader(LogReader):
-    def __init__(self) -> None:
-        super().__init__()
+    def __init__(self, tty: str, brate: int, address: int):
+        super().__init__(tty, brate, address)
 
     def get_archive(self):
         print("DigitalLogReader")
 
+    def get_random_archive_entry(self):
+        data = self.read_file_record(ARCHIVE_ENTRY, randint(1, self.archive_entries_number), 1)
+        entry = struct.unpack('<QBB', data[5:15])
+        print(entry)
+
 
 class AnalogInputLogReader(LogReader):
-    def __init__(self) -> None:
+    def __init__(self):
         super().__init__()
 
     def get_archive(self):
@@ -27,9 +57,16 @@ class AnalogInputLogReader(LogReader):
 
 
 def main():
-    module = DigitalLogReader()
+
+    module = DigitalLogReader('COM24', 115200, 15)
+
+    module.get_log_info()
     module.get_archive()
 
+    for i in range(500):
+        module.get_random_archive_entry()
+        sleep(0.1)
+
 
 
 if __name__ == '__main__':

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff