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 bme280
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.
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 -128 to 127.
115 * @param format is the desired output format of val - see format_type_t for
116 * avilable options.
117 */
119 log_type_t level,
120 const char *msg,
121 int8_t val,
122 format_type_t format)
123{
124 // If all test expressions evaluate true, log message.
125 if (log_message_preference_check(p_config, level))
126 {
127 print_tag_and_log_level(p_config->p_system_tag, level);
130 if (val < 0)
131 {
133 val *= -1; // Convert to positive integer
134 }
135 usart_print_byte(val);
136 }
137}
138
139
140void log_message_with_16bit_unsigned_dec_val(log_system_config_t *p_config,
141 log_type_t level,
142 const char *msg,
143 uint16_t val)
144{
145 // If all test expressions evaluate true, log message.
146 if (log_message_preference_check(p_config, level))
147 {
148 print_tag_and_log_level(p_config->p_system_tag, level);
151 usart_print_word(val);
152 }
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 usart_print_word(uint16_t word)
Prints a word (16-bits) out as its 5-digit ascii equivalent.
Definition: usart.c:155
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 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
void log_message_with_8bit_signed_val(log_system_config_t *p_config, log_type_t level, const char *msg, int8_t val, format_type_t format)
Sends a string, followed by an 8 bit value.
Definition: log_system.c:118
enum name format_type_t
Enumerated constants to specify the output format of numerical values.
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