AVRly - AVR Development Resources
log_system.c
Go to the documentation of this file.
1/******************************************************************************
2 @copyright Copyright © 2022 by Jason Duffy.
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21******************************************************************************/
22
23/**
24 * @file log_system.c
25 * @ingroup log_system
26 * @author Jason Duffy
27 * @date 1st March 2022
28 * @brief Driver file providing logging functionality over USART, to print
29 * debug messages and values to a teminal program on your PC.
30 * @bug No known bugs.
31 */
32
33#include <stdbool.h>
34
35#include "usart.h"
36#include "log_system.h"
37
38
39/**
40 * Instantiation of log system config object, pass it's address into logging
41 * functions.
42 */
44{
45 .p_system_tag = "Log_System",
46 .file_log_level = INFO,
47};
48
49
50/**
51 * Flag to determine whether logging output is turned on or off globally. The
52 * flag itself however is at file scope only.
53 */
54static bool log_system_enabled = false;
55
56
57/**
58 * Variable to store the preferred maximum level of logging with global effect.
59 * Maximum level available by default. Call log_set_global_max_output_level()
60 * to change this value.
61 */
62static log_type_t global_max_output_level = VERBOSE_DEBUG;
63
64
65// Forward declaration - private helper functions.
66void print_tag_and_log_level(const char *p_tag, log_type_t level);
68 log_type_t level);
69
70
71/*
72 * Initialisation routine - call this function once at startup before using
73 * other functions. Log system will then be turned on by default - call
74 * log_global_off() if you do not wish it to be.
75 */
77{
78 init_usart();
80 log_message(&log_system_log, INFO, "Log system initialised");
81};
82
83
84/*
85 * Sends only the system tag, log level and message string.
86 * @param p_config is a pointer to the log_system config object. Instantiate
87 * the config object at the head of each file where logging is required and
88 * pass it's address into this function.
89 * @param level is the level status of the log message - see log_type_t for
90 * available options.
91 * @param msg is the message to be logged, enclose it in "" quotation marks.
92 */
94 log_type_t level,
95 const char *msg)
96{
97 // If all test expressions evaluate true, log message.
98 if (log_message_preference_check(p_config, level))
99 {
100 print_tag_and_log_level(p_config->p_system_tag, level);
102 }
103}
104
105
106/*
107 * Sends a string, followed by an 8 bit value in decimal format.
108 * @param p_config is a pointer to the log_system config object. Instantiate
109 * the config object at the head of each file where logging is required and
110 * pass it's address into this function.
111 * @param level is the level status of the log message - see log_type_t for
112 * available options.
113 * @param msg is the message to be logged, enclose it in "" quotation marks.
114 * @param val is the numerical value to be logged - Acceptable values 0 - 255.
115 */
117 log_type_t level,
118 const char *msg,
119 uint8_t val)
120{
121 // If all test expressions evaluate true, log message.
122 if (log_message_preference_check(p_config, level))
123 {
124 print_tag_and_log_level(p_config->p_system_tag, level);
127 usart_print_byte(val);
128 }
129}
130
131/*
132 * Sends a string, followed by a 16 bit value in decimal format.
133 * @param p_config is a pointer to the log_system config object. Instantiate
134 * the config object at the head of each file where logging is required and
135 * pass it's address into this function.
136 * @param level is the level status of the log message - see log_type_t for
137 * available options.
138 * @param msg is the message to be logged, enclose it in "" quotation marks.
139 * @param val is the numerical value to be logged - Acceptable values 0 - 255.
140 */
142 log_type_t level,
143 const char *msg,
144 uint8_t val)
145{
146 // If all test expressions evaluate true, log message.
147 if (log_message_preference_check(p_config, level))
148 {
149 print_tag_and_log_level(p_config->p_system_tag, level);
152 usart_print_byte(val);
153 }
154}
155
156
157/*
158 * Sends a string, followed by an 8 bit value in binary format.
159 * @param p_config is a pointer to the log_system config object. Instantiate
160 * the config object at the head of each file where logging is required and
161 * pass it's address into this function.
162 * @param level is the level status of the log message - see log_type_t for
163 * available options.
164 * @param msg is the message to be logged, enclose it in "" quotation marks.
165 * @param val is the numerical value to be logged - Acceptable values 0 - 255.
166 */
168 log_type_t level,
169 const char *msg,
170 uint8_t val)
171{
172 // If all test expressions evaluate true, log message.
173 if (log_message_preference_check(p_config, level))
174 {
175 print_tag_and_log_level(p_config->p_system_tag, level);
179 }
180}
181
182
183/*
184 * Sends a string, followed by an 8 bit value in hexadecimal format.
185 * @param p_config is a pointer to the log_system config object. Instantiate
186 * the config object at the head of each file where logging is required and
187 * pass it's address into this function.
188 * @param level is the level status of the log message - see log_type_t for
189 * available options.
190 * @param msg is the message to be logged, enclose it in "" quotation marks.
191 * @param val is the numerical value to be logged - Acceptable values 0 - 255.
192 */
194 log_type_t level,
195 const char *msg,
196 uint8_t val)
197{
198 // If all test expressions evaluate true, log message.
199 if (log_message_preference_check(p_config, level))
200 {
201 print_tag_and_log_level(p_config->p_system_tag, level);
205 }
206}
207
208
209/*
210 * Sets maximum output level of logging required, to be used at file scope.
211 * @param p_config is a pointer to the log_system config object. Instantiate
212 * the config object at the head of each file where logging is required and
213 * pass it's address into this function.
214 * @param level is the maximum level required - see log_type_t for available
215 * options.
216 */
218 log_type_t level)
219{
220 p_config->file_log_level = level;
221}
222
223
224/*
225 * Sets maximum output level of logging required, has global effect.
226 * @param level is the maximum level required - see log_type_t for available
227 * options.
228 */
230{
231 global_max_output_level = level;
232}
233
234
235/*
236 * Turns logging system on globally.
237 */
239{
240 log_system_enabled = true;
241}
242
243
244/*
245 * Turns logging system off globally.
246 */
248{
249 log_system_enabled = false;
250}
251
252
253// ------------------------------------------------------------------------- //
254// ------------------------ Private Helper Functions ----------------------- //
255// ------------------------------------------------------------------------- //
256
257/**
258 * Utility function to print labels over serial.
259 */
260void print_tag_and_log_level(const char *p_tag, log_type_t level)
261{
262 if (level == NONE)
263 {
264
265 }
266 usart_print_string("\n");
267 usart_print_string(p_tag);
268
269 if (level == ERROR)
270 {
271 usart_print_string(", ERROR: ");
272 }
273
274 else if (level == WARNING)
275 {
276 usart_print_string(", WARNING: ");
277 }
278
279 else if (level == INFO)
280 {
281 usart_print_string(", INFO: ");
282 }
283
284 else if (level == DEBUG)
285 {
286 usart_print_string(", DEBUG: ");
287 }
288
289 else if (level == VERBOSE_DEBUG)
290 {
291 usart_print_string(", VERBOSE_DEBUG: ");
292 }
293
294 else
295 {
296 usart_print_string(", INVALID_LOG_LEVEL: ");
297 }
298}
299
300
301/**
302 * Utility function to test if the log message level meets the preferences set.
303 */
305 log_type_t level)
306{
307 // Test if log_system is enabled globally, if not then do nothing.
308 if (log_system_enabled)
309 {
310 // Test if the level of this log message meets global log preferences.
311 if (level <= global_max_output_level)
312 {
313 // Test if the level of this log message meets file level preferences.
314 if (level <= p_config->file_log_level)
315 {
316 return true;
317 }
318 }
319 }
320 // If any of the above conditionals evaluate to false, return false.
321 return false;
322}
323
324/*** end of file ***/
void usart_print_string(const char myString[])
Utility function to transmit a string.
Definition: usart.c:74
void usart_print_byte(uint8_t byte)
Prints a byte out as its 3-digit ascii equivalent.
Definition: usart.c:121
void usart_print_binary_byte(uint8_t byte)
Prints a byte out in 1s and 0s.
Definition: usart.c:169
void init_usart(void)
Takes the defined BAUD and F_CPU, calculates the bit-clock multiplier, configures the hardware USART ...
Definition: usart.c:50
void usart_print_hex_byte(uint8_t byte)
Prints a byte out in hexadecimal format.
Definition: usart.c:207
void log_global_on(void)
Turns logging system on globally.
Definition: log_system.c:133
void init_log_system(void)
Initialisation routine - call this function once at startup before using other functions.
Definition: log_system.c:46
void log_global_off(void)
Turns logging system off globally.
Definition: log_system.c:139
bool log_message_preference_check(log_system_config_t *p_config, log_type_t level)
Utility function to test if the log message level meets the preferences set.
Definition: log_system.c:304
void log_set_file_max_output_level(log_system_config_t *p_config, log_type_t level)
Sets maximum output level of logging required, to be used at file scope.
Definition: log_system.c:217
void log_message_with_dec_val(log_system_config_t *p_config, log_type_t level, const char *msg, uint8_t val)
Sends a string, followed by an 8 bit value in decimal format.
Definition: log_system.c:116
void print_tag_and_log_level(const char *p_tag, log_type_t level)
Utility function to print labels over serial.
Definition: log_system.c:260
void log_set_global_max_output_level(log_type_t level)
Sets maximum output level of logging required, has global effect.
Definition: log_system.c:229
void log_message_with_hex_val(log_system_config_t *p_config, log_type_t level, const char *msg, uint8_t val)
Sends a string, followed by an 8 bit value in hexadecimal format.
Definition: log_system.c:193
log_system_config_t log_system_log
Instantiation of log system config object, pass it's address into logging functions.
Definition: log_system.c:43
void log_message(log_system_config_t *p_config, log_type_t level, const char *msg)
Sends only the system tag, log level and message string.
Definition: log_system.c:93
void log_message_with_bin_val(log_system_config_t *p_config, log_type_t level, const char *msg, uint8_t val)
Sends a string, followed by an 8 bit value in binary format.
Definition: log_system.c:167
log_type_t
Enumerated constants for the type of message to be logged.
Definition: log_system.h:40
Driver file providing logging functionality over USART, to print debug messages and values to a temin...
Driver file providing core USART communication between the target MCU and your PC.
Config object, to be instantiated in each file the log system is to be used, then pass it's address i...
Definition: log_system.h:59