Skip to content

Commit 81ac05d

Browse files
committed
Export to VCD files, additional logging macros added
1 parent fa475bb commit 81ac05d

27 files changed

+1958
-77
lines changed

Code/RTEmsg.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@
411411
<ClInclude Include="text.h" />
412412
<ClInclude Include="timestamp.h" />
413413
<ClInclude Include="utf8_helpers.h" />
414+
<ClInclude Include="vcd.h" />
414415
</ItemGroup>
415416
<ItemGroup>
416417
<ClCompile Include="cmd_line.c" />
@@ -442,6 +443,7 @@
442443
<ClCompile Include="statistics.c" />
443444
<ClCompile Include="process_bin_data.c" />
444445
<ClCompile Include="utf8_helpers.c" />
446+
<ClCompile Include="vcd.c" />
445447
</ItemGroup>
446448
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
447449
<ImportGroup Label="ExtensionTargets">

Code/RTEmsg.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@
8787
<ClInclude Include="timestamp.h">
8888
<Filter>Header Files</Filter>
8989
</ClInclude>
90+
<ClInclude Include="vcd.h">
91+
<Filter>Header Files</Filter>
92+
</ClInclude>
9093
</ItemGroup>
9194
<ItemGroup>
9295
<ClCompile Include="pch.c">
@@ -149,5 +152,8 @@
149152
<ClCompile Include="messages.c">
150153
<Filter>Source Files</Filter>
151154
</ClCompile>
155+
<ClCompile Include="vcd.c">
156+
<Filter>Source Files</Filter>
157+
</ClCompile>
152158
</ItemGroup>
153159
</Project>

Code/cmd_line.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,10 @@ static void process_one_cmd_line_parameter(char *argv)
285285
{
286286
g_msg.param.purge_defines = true;
287287
}
288+
else if (strcmp(argv, "-no_gtkw") == 0)
289+
{
290+
g_msg.param.do_not_generate_gtkw_file = true;
291+
}
288292
else if (strncmp(argv, "-T=", 3) == 0)
289293
{
290294
g_msg.param.timestamp_print = (char *)allocate_memory(strlen(argv) - 2, "tstamp");

Code/decoder.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ void process_message(uint32_t last_index)
312312

313313
if (current_fmt_id >= MAX_FMT_IDS)
314314
{
315+
g_msg.print_nl_to_main_log = true;
315316
report_no_definition_for_current_message(current_fmt_id, last_index);
316317
return;
317318
}
@@ -326,6 +327,7 @@ void process_message(uint32_t last_index)
326327

327328
if (p_fmt == NULL)
328329
{
330+
g_msg.print_nl_to_main_log = true;
329331
report_no_definition_for_current_message(current_fmt_id, last_index);
330332
return;
331333
}
@@ -342,6 +344,7 @@ void process_message(uint32_t last_index)
342344
g_msg.asm_words++; // Also print the extended data.
343345
}
344346

347+
g_msg.print_nl_to_main_log = true;
345348
hex_dump_current_message(true);
346349
return;
347350
}

Code/files.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <stdlib.h>
1616
#include <string.h>
1717
#include <direct.h>
18+
#include <time.h>
19+
#include <windows.h>
1820
#include "main.h"
1921
#include "errors.h"
2022
#include "files.h"
@@ -194,10 +196,10 @@ void create_main_log_file(void)
194196
void remove_file(const char *file_name)
195197
{
196198
_set_errno(0);
197-
int result = utf8_remove(file_name);
199+
int result = utf8_remove(file_name);
198200

199201
if (result == -1)
200-
{
202+
{
201203
if (errno != ENOENT) // ENOENT indicates the file does not exist, which is acceptable
202204
{
203205
report_problem_with_string(ERR_COULD_NOT_DELETE_FILE, file_name);

Code/format.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ static void print_single_value_formatting_data(FILE *out, value_format_t *p_val_
328328
}
329329

330330
fprintf(out, "%s\t%s\t", timer_name, value_statistic_name);
331+
print_indexed_text(out, p_val_fmt->special_fmt,
332+
" ,VCD_WORK,VCD_FINALIZE");
331333
fprintf(out, "\n");
332334
}
333335

@@ -354,9 +356,9 @@ void print_format_decoding_information(void)
354356
}
355357

356358
fprintf(out,
357-
"FMT\tName\tType\tLength\t"
359+
"FMT\tName\tType\tLength\tAdd_nl\t"
358360
"String\tOutput\tData type\tFmt_type\tAddr\tSize\t"
359-
"Get.memo\tPut.memo\tIn.file/memo\tOffset\tMult\tTimer\tStatistics\t\n"
361+
"Get.memo\tPut.memo\tIn.file/memo\tOffset\tMult\tTimer\tStatistics\tSpecial type\t\n"
360362
);
361363

362364
msg_data_t *p_fmt = NULL;
@@ -377,14 +379,23 @@ void print_format_decoding_information(void)
377379
print_indexed_text(out, p_fmt->msg_type, "MSG0_NN,MSGN,EXT_MSG,MSGX");
378380
fprintf(out, "%u\t", p_fmt->msg_len);
379381

382+
if (p_fmt->add_nl_to_main_log)
383+
{
384+
fprintf(out, "yes\t");
385+
}
386+
else
387+
{
388+
fprintf(out, "no\t");
389+
}
390+
380391
size_t fmt_counter = 0;
381392
value_format_t *p_val_fmt = p_fmt->format;
382393

383394
while (p_val_fmt != NULL)
384395
{
385396
if (fmt_counter > 0)
386397
{
387-
fprintf(out, "\t\t\t\t");
398+
fprintf(out, "\t\t\t\t\t");
388399
}
389400

390401
fmt_counter++;

Code/format.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ enum fmt_type_t
4646
PRINT_UINT64, // "%u", "%c", "%x", "%o", "%X", "%lu", "%lx", "%lX", "%lo" etc.
4747
PRINT_INT64, // "%d", "%i", "%ld", "%li" etc.
4848
PRINT_DOUBLE, // "%f", "%F", "%e", "%E", "%g", "%G", "%a", "%A"
49-
PRINT_BINARY, // "%b", "%B"
49+
PRINT_BINARY, // "%B"
5050
PRINT_TIMESTAMP, // "%t"
5151
PRINT_dTIMESTAMP, // "%T"
5252
PRINT_MSG_NO, // "%N"
@@ -56,6 +56,8 @@ enum fmt_type_t
5656
PRINT_BIN_TO_FILE, // "%W"
5757
PRINT_DATE, // "%D"
5858
PRINT_MSG_FMT_ID_NAME // "%M"
59+
// Not assigned: *C, I, J, K, O, P, Q, R, *S, U, V, *Z, b, j, k, m, *n, *p, q, r, v, w, y, z
60+
// '*' - see special types: https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-170
5961
};
6062

6163

@@ -95,6 +97,7 @@ typedef struct value_format
9597
enum data_type_t data_type; /*!< Type of data formatting (signed, unsigned, float, ...) */
9698
enum fmt_type_t fmt_type; /*!< Which data type should be used for the fprintf() */
9799
bool print_copy_to_main_log; /*!< != 0 => Print copy of data printed to defined file to Main.log file. */
100+
special_fmt_t special_fmt; /*!< != 0 => Special formating requirement. */
98101
double mult; /*!< Multiplier for data scaling (0 = no scaling) */
99102
double offset; /*!< Offset added before the multiplication */
100103
value_stats_t *value_stat; /*!< Value statistics (NULL = no statistics for this value) */
@@ -105,7 +108,7 @@ typedef struct value_format
105108
/*@brief Define type of message for which the decoding function must expect. */
106109
enum msg_type_t
107110
{
108-
TYPE_MSG0_4, /*!< For MSG0 .. MSGnn - known length at compile time */
111+
TYPE_MSG0_8, /*!< For MSG0 .. MSGnn - known length at compile time */
109112
TYPE_MSGN, /*!< For MSGN - known and unknown length (0 = unknown) */
110113
TYPE_EXT_MSG, /*!< For EXT_MSG0..4 - known length */
111114
TYPE_MSGX /*!< For MSGX - unknown length */
@@ -118,6 +121,7 @@ typedef struct
118121
{
119122
const char *message_name; /*!< Name of this message type - i.e. MSG2_NAME */
120123
enum msg_type_t msg_type; /*!< Type of message (most message types have known length) */
124+
bool add_nl_to_main_log; /*!< true - add newline before next message in Main.log */
121125
uint16_t ext_data_mask; /*!< AND mask used to select the extended info from the format_id */
122126
uint32_t msg_len; /*!< Expected message length in bytes (0 - unknown at compile time) */
123127
uint32_t counter; /*!< Number of same message type received and successfully processed after

Code/main.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "parse_directive.h"
3838
#include "cmd_line.h"
3939
#include "utf8_helpers.h"
40+
#include "vcd.h"
4041

4142
#pragma comment(linker, "/STACK:8388608") // Increase stack size to 8 MB
4243

@@ -197,16 +198,14 @@ static void check_print_errors(void)
197198

198199

199200
/**
200-
* @brief Prints the full binary file name and creation date, and prepares the date string
201-
* for the special format type "%D".
201+
* @brief Print the full binary file name and creation date to a file,
202+
* and prepare the date string for the special format type "%D".
203+
*
204+
* @param out Pointer to the output file.
202205
*/
203206

204-
static void print_data_file_name_and_date(void)
207+
void print_data_file_name_and_date(FILE * out)
205208
{
206-
FILE *out = g_msg.file.main_log;
207-
208-
fprintf(out, TXT_MSG_RTEMSG_VERSION, RTEMSG_VERSION, RTEMSG_SUBVERSION, RTEMSG_REVISION, __DATE__);
209-
210209
struct _stat stbuf;
211210
int rez = _stat(g_msg.param.data_file_name, &stbuf);
212211
if (rez == 0)
@@ -223,6 +222,18 @@ static void print_data_file_name_and_date(void)
223222
}
224223

225224

225+
/**
226+
* @brief Print the RTEmsg version to a file.
227+
*
228+
* @param out Pointer to the output file.
229+
*/
230+
231+
void print_rtemsg_version(FILE* out)
232+
{
233+
fprintf(out, TXT_MSG_RTEMSG_VERSION, RTEMSG_VERSION, RTEMSG_SUBVERSION, RTEMSG_REVISION, __DATE__);
234+
}
235+
236+
226237
/**
227238
* @brief Create the Timestamps.csv file and write the header
228239
* if this functionality was enabled with a command line parameter
@@ -411,7 +422,7 @@ static void prepare_sys_msg_fmt_structure(void)
411422
msg_data_t *p_fmt = allocate_memory(sizeof(msg_data_t), "sysFmt");
412423
g_fmt[MSG1_SYS_STREAMING_MODE_LOGGING] = p_fmt;
413424
p_fmt->msg_len = 4u;
414-
p_fmt->msg_type = TYPE_MSG0_4;
425+
p_fmt->msg_type = TYPE_MSG0_8;
415426
p_fmt->message_name = "sys";
416427
}
417428

@@ -427,7 +438,8 @@ static void Process_binary_data_file(int argc, char *argv[])
427438
{
428439
create_main_log_file();
429440
load_and_check_rtedbg_header(); // Read and verify the header
430-
print_data_file_name_and_date(); // Print header information
441+
print_rtemsg_version(g_msg.file.main_log); // RTEmsg version and date
442+
print_data_file_name_and_date(g_msg.file.main_log); // Binary data file info
431443
print_cmd_line_parameters(argc, argv);
432444
print_bin_file_header_info();
433445
check_timestamp_diff_values(); // Check the values of the -ts command line argument (the timestamp period is known here)
@@ -458,6 +470,7 @@ static void Process_binary_data_file(int argc, char *argv[])
458470

459471
print_msg_intro();
460472
process_bin_data_worker(); // Process the loaded binary data
473+
vcd_finalize_files(); // Finalize VCD output files (if any)
461474
write_statistics_to_file(); // Generate various statistics files (if enabled)
462475
report_decode_error_summary();
463476
print_notes_and_warnings();
@@ -524,6 +537,7 @@ int main(int argc, char *argv[])
524537
return EXIT_FATAL_FMT_PARSING_ERRORS;
525538
}
526539

540+
set_tags_for_add_newline_to_main_log();
527541
print_format_decoding_information();
528542
dump_filter_names_to_file();
529543

Code/main.h

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@
2222
#include "messages.h"
2323

2424

25-
#define MAX_FMT_IDS (1ul << MAX_FMT_ID_BITS)
26-
27-
2825
/* @brief Values returned by the functions assemble_message() and data_in_the_buffer() */
2926
typedef enum assemble_msg_code_t
3027
{
@@ -53,6 +50,7 @@ typedef struct _param_t
5350
bool purge_defines; //!< Eliminate all #define directives from the format files during parsing
5451
bool additional_newline; //!< Print additional newline after information for every message to Main.log
5552
bool codepage_utf8; //!< Use the CP_UTF8 while printing the parsing error messages to the console
53+
bool do_not_generate_gtkw_file; //!< Do not generate the .gtkw file during generation of a .vcd file.
5654
char time_unit; //!< Specify time unit for the timestamps
5755
double time_multiplier; //!< Time multiplier - used for printing of timestamps
5856
char number_of_format_id_bits; //!< Number of bits used for the format ID
@@ -113,6 +111,67 @@ typedef struct _header_data_t
113111
} rte_header_data_t;
114112

115113

114+
/**
115+
* @brief Enumeration of VCD variable data types.
116+
*/
117+
typedef enum _vcd_type
118+
{
119+
VCD_TYPE_NONE = 0,
120+
VCD_TYPE_BIT, // Single bit data type
121+
VCD_TYPE_FLOAT, // Floating point and integer data type (signed/unsigned up to 64 bits)
122+
VCD_TYPE_STRING, // String data type
123+
VCD_TYPE_ANALOG, // Analog data type
124+
VCD_TYPE_LAST
125+
} vcd_type_t;
126+
127+
128+
/**
129+
* @brief Special formatting options (VCD support implemented so far).
130+
*/
131+
typedef enum
132+
{
133+
VCD_NONE = 0, // No special handling
134+
VCD_WORK, // Processing of VCD $var value
135+
VCD_FINALIZE // Finalize the VCD $var value and write it to output file
136+
// VCD_FINALIZE may be the only one for simple format definitions
137+
} special_fmt_t;
138+
139+
#define IS_A_VCD_TYPE(type) ((type >= VCD_WORK) && (type <= VCD_FINALIZE))
140+
141+
142+
/**
143+
* @brief Structure with name, data type and id string for a $var VCD variable.
144+
*/
145+
typedef struct
146+
{
147+
char name[VCD_MAX_VAR_NAME_LENGTH]; // $var name - truncated if too long
148+
char id[VCD_MAX_ID_LENGTH]; // $var identifier
149+
vcd_type_t variable_type; // $var type (defines var size also)
150+
} vcd_var_data_t;
151+
152+
/**
153+
* @brief Structure with data for a single VCD output file.
154+
*/
155+
typedef struct
156+
{
157+
bool writing_disabled; // True if writing is disabled due to timestamp errors
158+
bool discard_excessive_variables; // True if too many variables defined for a single VCD file
159+
bool data_written; // True if at least one $var value has been written to the file
160+
bool timestamp_error_found; // True if a timestamp error has been detected for the current message
161+
char last_timestamp_error_value; // To avoid multiple reporting of same value (unnecessarily VCD file size increase)
162+
unsigned consecutive_timestamp_errors; // Number of consecutive timestamp errors found
163+
164+
uint64_t last_timestamp_ns; // Last timestamp printed
165+
unsigned msg_no_of_last_timestamp;
166+
// To check if the timestamp has been already printed for the current message
167+
unsigned no_variables; // Number of variables found during message processing for a single VCD file
168+
vcd_var_data_t* p_vcd[VCD_MAX_VARIABLES_PER_FILE];
169+
char previous_bit_value[VCD_MAX_VARIABLES_PER_FILE]; // Used for T-toggle and R-reset
170+
char pulse_variable_id[VCD_MAX_ID_LENGTH]; // ID of the variable used for pulse generation
171+
// Non-zero value indicates that a pulse is to be generated.
172+
} vcd_file_data_t;
173+
174+
116175
enum enums_type_t
117176
{
118177
FILTER_TYPE, // FILTER() data
@@ -129,6 +188,8 @@ typedef struct _enum_data_t
129188
{
130189
char *name; /*!< Name of the enumerated value: filter, memo, in_file, out_file */
131190
enum enums_type_t type; /*!< Type of data in the union */
191+
vcd_file_data_t* vcd_data; /*!< Pointer to structure with VCD specific data (NULL = not a vcd FILE) */
192+
char* file_name; /*!< Name of the file defined with OUT_FILE() or IN_FILE() */
132193
union def_union
133194
{
134195
char *filter_description; /*!< FILTER: pointer to filter description (NULL if not specified) */
@@ -140,7 +201,6 @@ typedef struct _enum_data_t
140201
how the data is formatted - how it has to be prepared */
141202
double memo_value; /*!< MEMO: memorizing of temporary values */
142203
};
143-
char *file_name; /*!< Name of the file defined with OUT_FILE() or IN_FILE() */
144204
} enum_data_t;
145205

146206

@@ -188,6 +248,9 @@ typedef struct _timestamp_t
188248
bool mark_problematic_tstamps; /*!< Add asterisk before the message number */
189249
bool no_previous_tstamp; /*!< The timestamp.old value is not valid */
190250
bool long_timestamp_found; /*!< At least one long timestamp found */
251+
bool first_timestamp_processed; /*!< First timestamp processed */
252+
uint64_t first_timestamp_ns; /*!< First timestamp found in the binary data file in ns */
253+
uint64_t last_timestamp_ns; /*!< Last timestamp found in the binary data file in ns */
191254
} timestamp_t;
192255

193256

@@ -211,6 +274,8 @@ typedef struct _rte_msg_t
211274
char date_string[BIN_FILE_DATE_LENGTH]; /*!< String with date and time of binary data file creation - for "%D" */
212275
uint32_t messages_processed_after_restart; /*!< Counter of messages processed after reset/restart */
213276
value_t value; /*!< Currently processed/printed numerical value */
277+
bool vcd_files_processed; /*!< true - VCD file definitions found. VCD file have to be processed. */
278+
bool print_nl_to_main_log; /*!< true - print additional newline before next message */
214279

215280
/* Binary data file processing variables */
216281
uint32_t index; /*!< Index to the rte_buffer */
@@ -266,6 +331,8 @@ extern rte_msg_t g_msg; /*!< Main global data structure for the
266331
void *allocate_memory(size_t size, const char *memory_name);
267332
char *duplicate_string(const char *string_to_duplicate);
268333
bool is_power_of_two(size_t n);
334+
void print_data_file_name_and_date(FILE* out);
335+
void print_rtemsg_version(FILE* out);
269336

270337
#endif // _MAIN_H
271338

0 commit comments

Comments
 (0)