GPS Device
Loading...
Searching...
No Matches
log.c
Go to the documentation of this file.
1
11
12#include <stdarg.h>
13
14#include "log.h"
15#include "common.h"
16#include "err.h"
17#include "stm32f401re_gpio.h"
18#include "stm32f401re_usart.h"
19#include "stm32f401re_rtc.h"
20#include "modules.h"
21#include "init.h"
22
24extern const char *modules_names[];
25
33struct internal_state_s {
35 USART_REGDEF_ts *usart_instance;
36
39
41 bool initialized;
42};
43
45static struct internal_state_s internal_state = { 0 };
46
47/* ---- Forward declaration for internal helper ---- */
49
54
57 if(internal_state.initialized) {
59 }
60
61 internal_state.usart_instance = log_handle->usart_instance;
62
63 init_rtc();
64
65 GPIO_CFG_ts log_tx_pin = { 0 };
66 log_tx_pin.port = log_handle->gpio_port;
67 log_tx_pin.pin = log_handle->gpio_pin;
69 log_tx_pin.alternate_function = log_handle->gpio_alternate_function;
70 gpio_init(&log_tx_pin);
71
72 USART_CFG_ts log_usart = { 0 };
73 log_usart.instance = log_handle->usart_instance;
74 log_usart.baud_rate = log_handle->usart_baud_rate;
75 usart_init(&log_usart);
76
78
79 internal_state.initialized = true;
80
81 return ERR_OK;
82}
83
86 if(internal_state.usart_instance == (void*)0) {
88 }
89
90 usart_deinit(internal_state.usart_instance);
91
92 internal_state.usart_instance = 0;
93 internal_state.force_disable = 0;
94
95 return ERR_OK;
96}
97
100 if (log_level >= subsys_log_level && internal_state.force_disable == false) {
101 va_list args;
102 va_start(args, msg);
103
105
106 while (*msg != '\0') {
107 if (*msg == '%') {
108 msg++;
109
110 if (*msg == 'd') {
111 int32_t num = va_arg(args, int);
112 char num_buf[12];
113 int_to_str(num, num_buf);
114 usart_send(internal_state.usart_instance, (uint8_t*)num_buf, get_str_len(num_buf));
115 }
116 else if (*msg == 's') {
117 char *str = va_arg(args, char*);
118 usart_send(internal_state.usart_instance, (uint8_t*)str, get_str_len(str));
119 }
120 else if(*msg == '.') {
121 msg++;
122
123 char dec_places_str[2];
124 dec_places_str[0] = *msg; // There can be no more than 9 decimal places
125 dec_places_str[1] = '\0';
126
127 msg++;
128
129 if(*msg == 'f') {
130 double num = va_arg(args, double);
131 char num_buf[20] = { 0 };
132 double_to_str(num, num_buf, str_to_int(dec_places_str));
133 usart_send(internal_state.usart_instance, (uint8_t*)num_buf, get_str_len(num_buf));
134 }
135 }
136 }
137 else {
138 usart_send(internal_state.usart_instance, (uint8_t*)msg, 1);
139 }
140
141 msg++;
142 }
143
144 va_end(args);
145
146 usart_send(internal_state.usart_instance, (uint8_t*)"\r\n", 2);
147 }
148
149 return ERR_OK;
150}
151
154 char const *name;
155
156 switch(log_level) {
157 case LOG_LEVEL_NONE:
158 name = "none";
159 break;
160
161 case LOG_LEVEL_INFO:
162 name = "info";
163 break;
164
165 case LOG_LEVEL_DEBUG:
166 name = "debug";
167 break;
168
170 name = "warning";
171 break;
172
173 case LOG_LEVEL_ERROR:
174 name = "error";
175 break;
176
178 name = "critical";
179 break;
180
181 default:
182 return ERR_UNKNOWN;
183 break;
184 }
185
186 str_cpy(str, name, get_str_len(name) + 1);
187
188 return ERR_OK;
189}
190
193 if(str_cmp(str, "none") == true) {
195 }
196 else if(str_cmp(str, "info") == true) {
198 }
199 else if(str_cmp(str, "debug") == true) {
201 }
202 else if(str_cmp(str, "warning") == true) {
204 }
205 else if(str_cmp(str, "error") == true) {
207 }
208 else if(str_cmp(str, "critical") == true) {
210 }
211 else {
213 }
214
215 return ERR_OK;
216}
217
219ERR_te log_set_force_disable(bool bool_status) {
220 internal_state.force_disable = bool_status;
221
222 return ERR_OK;
223}
224
226
231
249 TIME_ts rtc_time = { 0 };
250 rtc_get_time(&rtc_time);
251
252 char seconds[2];
253 int_to_str(rtc_time.seconds, seconds);
254 if(get_str_len(seconds) == 1) {
255 char temp = seconds[0];
256 seconds[0] = '0';
257 seconds[1] = temp;
258 }
259
260 char minutes[2];
261 int_to_str(rtc_time.minutes, minutes);
262 if(get_str_len(minutes) == 1) {
263 char temp = minutes[0];
264 minutes[0] = '0';
265 minutes[1] = temp;
266 }
267
268 char hours[2];
269 int_to_str(rtc_time.hours, hours);
270 if(get_str_len(hours) == 1) {
271 char temp = hours[0];
272 hours[0] = '0';
273 hours[1] = temp;
274 }
275
276 char time_format[] = "(__:__:__)";
277
278 str_set(time_format, seconds, 2, 7);
279 str_set(time_format, minutes, 2, 4);
280 str_set(time_format, hours, 2, 1);
281
282 usart_send(internal_state.usart_instance, (uint8_t*)time_format, 10);
283
284 char log_level_str[16];
285 uint8_t log_level_len = 0;
286 log_level_str[0] = '(';
287 log_get_level_name(log_level, log_level_str + 1);
288 log_level_len = get_str_len(log_level_str);
289 log_level_str[log_level_len] = ')';
290 log_level_str[log_level_len + 1] = '\0';
291
293 internal_state.usart_instance,
294 (uint8_t*)log_level_str,
295 get_str_len(log_level_str) + 1
296 );
297
299 internal_state.usart_instance,
300 (uint8_t*)modules_names[subsys],
302 );
303
305 internal_state.usart_instance,
306 (uint8_t*)"-> ",
307 3
308 );
309
310 return ERR_OK;
311}
312
static struct internal_state_s internal_state
Singleton instance of the SysTick driver internal state.
Common utility module public API.
System-wide error code definitions.
bool str_cmp(const char *str1, const char *str2)
Compares two null-terminated strings for equality.
Definition common.c:248
int str_to_int(const char *str)
Converts a decimal string to an integer.
Definition common.c:69
int str_cpy(char *str_to, const char *str_from, uint32_t len)
Copies a null-terminated string into a destination buffer.
Definition common.c:333
void str_set(char *target_str, char const *host_str, uint32_t host_str_len, uint32_t pos)
Overwrites a region of a target string with the contents of a source string.
Definition common.c:195
uint32_t get_str_len(char const *str)
Returns the length of a string, excluding the null terminator.
Definition common.c:22
void double_to_str(double num, char *str, int8_t frac_digits)
Converts a double to a decimal string with a fixed number of fractional digits.
Definition common.c:102
void int_to_str(int num, char *str)
Converts an integer to its decimal string representation.
Definition common.c:33
@ ENABLE
Definition common.h:100
ERR_te
Standard return type used by all public API functions.
Definition err.h:35
@ ERR_UNINITIALZIED_OBJECT
Definition err.h:42
@ ERR_UNKNOWN
Definition err.h:37
@ ERR_OK
Definition err.h:36
@ ERR_MODULE_ALREADY_INITIALIZED
Definition err.h:54
ERR_te init_rtc(void)
Initializes the RTC peripheral and sets a default calendar and time.
Definition init.c:72
static ERR_te log_print_prologue(MODULES_te subsys, LOG_LEVEL_te log_level)
Prints the log message prologue: timestamp, severity, and subsystem name.
Definition log.c:248
ERR_te log_level_to_int(char const *str, LOG_LEVEL_te *log_level)
Converts a log level name string to its LOG_LEVEL_te value.
Definition log.c:192
ERR_te log_deinit()
Deinitializes the log subsystem.
Definition log.c:85
ERR_te log_set_force_disable(bool bool_status)
Enables or disables forced suppression of all log output.
Definition log.c:219
ERR_te log_init(LOG_HANDLE_ts *log_handle)
Initializes the log subsystem.
Definition log.c:56
ERR_te log_get_level_name(LOG_LEVEL_te log_level, char *str)
Converts a LOG_LEVEL_te value to its lowercase string name.
Definition log.c:153
ERR_te log_print(MODULES_te subsys, LOG_LEVEL_te subsys_log_level, LOG_LEVEL_te log_level, char *msg,...)
Prints a formatted message to the serial terminal if the severity threshold is met.
Definition log.c:99
LOG_LEVEL_te
Log severity levels, in ascending order of severity.
Definition log.h:63
@ LOG_LEVEL_CRITICAL
Definition log.h:68
@ LOG_LEVEL_DEBUG
Definition log.h:65
@ LOG_LEVEL_ERROR
Definition log.h:67
@ LOG_LEVEL_WARNING
Definition log.h:66
@ LOG_LEVEL_NONE
Definition log.h:69
@ LOG_LEVEL_INFO
Definition log.h:64
MODULES_te
Identifies a subsystem for use in logging and CLI output.
Definition modules.h:42
void gpio_init(GPIO_CFG_ts *gpio_cfg)
Initializes a GPIO pin according to the given configuration.
@ GPIO_MODE_ALTERNATE_FUNCTION
void rtc_get_time(TIME_ts *time)
Reads the current time from the RTC.
void usart_deinit(USART_REGDEF_ts const *usart_instance)
Deinitializes the USART peripheral, disables its NVIC interrupt, and disables its clock.
void usart_init(USART_CFG_ts *usart_cfg)
Initializes the USART peripheral with the given configuration.
void usart_send(USART_REGDEF_ts *usart_instance, uint8_t *tx_buffer, uint32_t len)
Blocking USART transmit. Sends len bytes from tx_buffer.
void usart_set_transmission(USART_REGDEF_ts *usart_instance, EN_STATUS_te en_status)
Enables or disables the USART transmitter (TE bit).
Common initialization public API.
const char * modules_names[]
External array mapping MODULES_te values to their name strings.
Definition modules.c:24
Log subsystem public API.
System module identifier definitions.
STM32F401RE GPIO driver public API.
STM32F401RE RTC driver public API.
STM32F401RE USART driver public API.
Configuration structure for initializing a GPIO pin.
GPIO_REGDEF_ts * port
GPIO_ALTERNATE_FUNCTION_te alternate_function
GPIO_PIN_te pin
GPIO_MODE_te mode
Configuration handle for initializing the log subsystem.
Definition log.h:80
GPIO_REGDEF_ts * gpio_port
Definition log.h:88
GPIO_ALTERNATE_FUNCTION_te gpio_alternate_function
Definition log.h:94
USART_BAUD_RATE_te usart_baud_rate
Definition log.h:85
USART_REGDEF_ts * usart_instance
Definition log.h:82
GPIO_PIN_te gpio_pin
Definition log.h:91
Holds a time-of-day value (hours, minutes, seconds).
uint8_t seconds
uint8_t hours
uint8_t minutes
Configuration structure for initializing a USART peripheral.
USART_BAUD_RATE_te baud_rate
USART_REGDEF_ts * instance
Internal state of the SysTick driver.
MODULES_te subsys
Definition button.c:95
bool force_disable
Definition log.c:38
LOG_LEVEL_te log_level
Definition button.c:92
USART_REGDEF_ts * usart_instance
Definition console.c:66