Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
cy_log.c
00001 /* 00002 * Copyright 2019-2021, Cypress Semiconductor Corporation (an Infineon company) or 00003 * an affiliate of Cypress Semiconductor Corporation. All rights reserved. 00004 * 00005 * This software, including source code, documentation and related 00006 * materials ("Software") is owned by Cypress Semiconductor Corporation 00007 * or one of its affiliates ("Cypress") and is protected by and subject to 00008 * worldwide patent protection (United States and foreign), 00009 * United States copyright laws and international treaty provisions. 00010 * Therefore, you may use this Software only as provided in the license 00011 * agreement accompanying the software package from which you 00012 * obtained this Software ("EULA"). 00013 * If no EULA applies, Cypress hereby grants you a personal, non-exclusive, 00014 * non-transferable license to copy, modify, and compile the Software 00015 * source code solely for use in connection with Cypress's 00016 * integrated circuit products. Any reproduction, modification, translation, 00017 * compilation, or representation of this Software except as specified 00018 * above is prohibited without the express written permission of Cypress. 00019 * 00020 * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, 00021 * EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED 00022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress 00023 * reserves the right to make changes to the Software without notice. Cypress 00024 * does not assume any liability arising out of the application or use of the 00025 * Software or any product or circuit described in the Software. Cypress does 00026 * not authorize its products for use in any products where a malfunction or 00027 * failure of the Cypress product may reasonably be expected to result in 00028 * significant property damage, injury or death ("High Risk Product"). By 00029 * including Cypress's product in a High Risk Product, the manufacturer 00030 * of such system or application assumes all risk of such use and in doing 00031 * so agrees to indemnify Cypress against all liability. 00032 */ 00033 00034 /** 00035 * @file Cypress log routines 00036 */ 00037 00038 #include <stdio.h> 00039 #include <stdlib.h> 00040 #include <string.h> 00041 #include <stdarg.h> 00042 00043 #include "cy_result.h" 00044 #include "cyabs_rtos.h" 00045 #include "cy_log.h " 00046 00047 #ifdef __cplusplus 00048 extern "C" { 00049 #endif 00050 /****************************************************** 00051 * Macros 00052 ******************************************************/ 00053 00054 /****************************************************** 00055 * Constants 00056 ******************************************************/ 00057 00058 /** Size of the logging buffer */ 00059 #ifndef CY_LOGBUF_SIZE 00060 #define CY_LOGBUF_SIZE (1024) 00061 #endif 00062 00063 /****************************************************** 00064 * Enumerations 00065 ******************************************************/ 00066 00067 /****************************************************** 00068 * Type Definitions 00069 ******************************************************/ 00070 00071 /****************************************************** 00072 * Structures 00073 ******************************************************/ 00074 00075 typedef struct 00076 { 00077 bool init; 00078 cy_mutex_t mutex; 00079 CY_LOG_LEVEL_T loglevel[CYLF_MAX]; 00080 uint32_t start_time; 00081 char logbuf[CY_LOGBUF_SIZE]; 00082 uint16_t seq_num; 00083 log_output platform_log; 00084 platform_get_time platform_time; 00085 void *worker_thread; 00086 } cy_log_data_t; 00087 00088 /****************************************************** 00089 * Function Declarations 00090 ******************************************************/ 00091 00092 /****************************************************** 00093 * Variables Definitions 00094 ******************************************************/ 00095 00096 static cy_log_data_t cy_log; 00097 00098 /****************************************************** 00099 * Function Definitions 00100 ******************************************************/ 00101 00102 00103 /* 00104 * Default implementation to output the log messages. This function is called, if the user doesn't define a output logging function. 00105 */ 00106 static int cy_log_output(CY_LOG_FACILITY_T facility, CY_LOG_LEVEL_T level, char *logmsg) 00107 { 00108 (void)facility; 00109 (void)level; 00110 printf("[F%d] : [L%d] : %s", facility, level, logmsg); 00111 00112 return 1; 00113 } 00114 00115 /* 00116 * Default implementation to get the time. This function is called, if the user doesn't provide a callback function to get time. 00117 */ 00118 static cy_rslt_t cy_log_get_time(uint32_t* time) 00119 { 00120 cy_rtos_get_time(time); 00121 return CY_RSLT_SUCCESS; 00122 } 00123 00124 00125 cy_rslt_t cy_log_init(CY_LOG_LEVEL_T level, log_output platform_output, platform_get_time platform_time) 00126 { 00127 cy_rslt_t result = CY_RSLT_SUCCESS; 00128 int i; 00129 00130 if (cy_log.init) 00131 { 00132 return CY_RSLT_SUCCESS; 00133 } 00134 00135 memset(&cy_log, 0x00, sizeof(cy_log)); 00136 cy_rtos_get_time(&cy_log.start_time); 00137 00138 /* 00139 * Create our mutex. 00140 */ 00141 00142 result = cy_rtos_init_mutex(&cy_log.mutex); 00143 if (result != CY_RSLT_SUCCESS) 00144 { 00145 return result; 00146 } 00147 00148 /* 00149 * Set the starting log level. 00150 */ 00151 00152 if ( level >= CY_LOG_MAX ) 00153 { 00154 level = (CY_LOG_LEVEL_T)(CY_LOG_MAX - 1); 00155 } 00156 00157 /* For all facilities */ 00158 00159 for (i = 0; i < CYLF_MAX; i++) 00160 { 00161 cy_log.loglevel[i] = level; 00162 } 00163 00164 /* 00165 * Set the platform output and time routines. 00166 */ 00167 00168 if (platform_output != NULL) 00169 { 00170 cy_log.platform_log = platform_output; 00171 } 00172 else 00173 { 00174 cy_log.platform_log = cy_log_output; 00175 } 00176 00177 if (platform_time != NULL) 00178 { 00179 cy_log.platform_time = platform_time; 00180 } 00181 else 00182 { 00183 cy_log.platform_time = cy_log_get_time; 00184 } 00185 /* 00186 * All done. 00187 */ 00188 00189 cy_log.init = true; 00190 00191 return result; 00192 } 00193 00194 00195 cy_rslt_t cy_log_shutdown(void) 00196 { 00197 if (!cy_log.init) 00198 { 00199 return CY_RSLT_TYPE_ERROR; 00200 } 00201 00202 cy_log.init = false; 00203 00204 cy_rtos_deinit_mutex(&cy_log.mutex); 00205 00206 return CY_RSLT_SUCCESS; 00207 } 00208 00209 cy_rslt_t cy_log_set_platform_output(log_output platform_output_func) 00210 { 00211 if (!cy_log.init) 00212 { 00213 return CY_RSLT_TYPE_ERROR; 00214 } 00215 00216 cy_log.platform_log = platform_output_func; 00217 00218 return CY_RSLT_SUCCESS; 00219 } 00220 00221 00222 cy_rslt_t cy_log_set_platform_time(platform_get_time platform_time) 00223 { 00224 if (!cy_log.init) 00225 { 00226 return CY_RSLT_TYPE_ERROR; 00227 } 00228 00229 cy_log.platform_time = platform_time; 00230 00231 return CY_RSLT_SUCCESS; 00232 } 00233 00234 cy_rslt_t cy_log_set_facility_level(CY_LOG_FACILITY_T facility, CY_LOG_LEVEL_T level) 00235 { 00236 if (!cy_log.init) 00237 { 00238 return CY_RSLT_TYPE_ERROR; 00239 } 00240 00241 if (facility >= CYLF_MAX) 00242 { 00243 facility = CYLF_DEF; 00244 } 00245 00246 if (level >= CY_LOG_MAX) 00247 { 00248 level = (CY_LOG_LEVEL_T)(CY_LOG_MAX - 1); 00249 } 00250 cy_log.loglevel[facility] = level; 00251 00252 return CY_RSLT_SUCCESS; 00253 } 00254 00255 00256 cy_rslt_t cy_log_set_all_levels(CY_LOG_LEVEL_T level) 00257 { 00258 int i; 00259 00260 if (!cy_log.init) 00261 { 00262 return CY_RSLT_TYPE_ERROR; 00263 } 00264 00265 if (level >= CY_LOG_MAX) 00266 { 00267 level = (CY_LOG_LEVEL_T)(CY_LOG_MAX - 1); 00268 } 00269 00270 for (i = 0; i < CYLF_MAX; i++) 00271 { 00272 cy_log.loglevel[i] = level; 00273 } 00274 00275 return CY_RSLT_SUCCESS; 00276 } 00277 00278 00279 CY_LOG_LEVEL_T cy_log_get_facility_level(CY_LOG_FACILITY_T facility) 00280 { 00281 CY_LOG_LEVEL_T local_loglevel = CY_LOG_OFF; 00282 00283 if (!cy_log.init) 00284 { 00285 return local_loglevel; 00286 } 00287 00288 if (facility >= CYLF_MAX) 00289 { 00290 facility = CYLF_DEF; 00291 } 00292 00293 local_loglevel = cy_log.loglevel[facility]; 00294 00295 return local_loglevel; 00296 } 00297 00298 00299 cy_rslt_t cy_log_msg(CY_LOG_FACILITY_T facility, CY_LOG_LEVEL_T level, const char *fmt, ...) 00300 { 00301 cy_rslt_t result = CY_RSLT_SUCCESS; 00302 uint32_t time_from_start; 00303 uint32_t cur_time; 00304 int hrs, mins, secs, ms; 00305 va_list args; 00306 int len; 00307 00308 if (!cy_log.init) 00309 { 00310 return CY_RSLT_TYPE_ERROR; 00311 } 00312 00313 /* Is logging enabled for the requested level of the requested facility? */ 00314 if (facility >= CYLF_MAX) 00315 { 00316 facility = CYLF_DEF; 00317 } 00318 if ((cy_log.platform_log == NULL) || (cy_log.loglevel[facility] == CY_LOG_OFF) || (level > cy_log.loglevel[facility])) 00319 { 00320 return CY_RSLT_SUCCESS; 00321 } 00322 00323 /* 00324 * Create the time stamp. 00325 */ 00326 00327 if (cy_log.platform_time != NULL) 00328 { 00329 result = cy_log.platform_time(&time_from_start); 00330 if (result != CY_RSLT_SUCCESS) 00331 { 00332 return result; 00333 } 00334 } 00335 else 00336 { 00337 cy_rtos_get_time(&cur_time); 00338 time_from_start = cur_time - cy_log.start_time; 00339 } 00340 00341 ms = time_from_start % 1000; 00342 time_from_start /= 1000; 00343 00344 secs = time_from_start % 60; 00345 time_from_start /= 60; 00346 00347 mins = time_from_start % 60; 00348 hrs = (time_from_start / 60) % 24; 00349 00350 /* 00351 * We use a common buffer for composing the log messages so we need to protect against 00352 * multiple threads calling us simultaneously. 00353 */ 00354 00355 result = cy_rtos_get_mutex(&cy_log.mutex, CY_RTOS_NEVER_TIMEOUT); 00356 if (result != CY_RSLT_SUCCESS) 00357 { 00358 return CY_RSLT_TYPE_ERROR; 00359 } 00360 00361 len = snprintf(cy_log.logbuf, CY_LOGBUF_SIZE, "%04d %02d:%02d:%02d.%03d ", cy_log.seq_num, hrs, mins, secs, ms); 00362 00363 va_start(args, fmt); 00364 len = vsnprintf(&cy_log.logbuf[len], CY_LOGBUF_SIZE - len, fmt, args); 00365 if ((len == -1) || (len >= CY_LOGBUF_SIZE)) 00366 { 00367 /* The vsnprintf() output was truncated. */ 00368 cy_log.logbuf[CY_LOGBUF_SIZE - 1] = '\0'; 00369 } 00370 va_end(args); 00371 00372 cy_log.platform_log(facility, level, cy_log.logbuf); 00373 00374 /* increment sequence number for next line*/ 00375 cy_log.seq_num++; 00376 00377 cy_rtos_set_mutex(&cy_log.mutex); 00378 00379 return result; 00380 } 00381 00382 cy_rslt_t cy_log_printf(const char *fmt, ...) 00383 { 00384 cy_rslt_t result; 00385 va_list args; 00386 00387 va_start(args, fmt); 00388 result = cy_log_vprintf(fmt, args); 00389 va_end(args); 00390 00391 return result; 00392 } 00393 00394 cy_rslt_t cy_log_vprintf(const char *fmt, va_list varg) 00395 { 00396 cy_rslt_t result = CY_RSLT_SUCCESS; 00397 int len; 00398 00399 if (!cy_log.init) 00400 { 00401 return CY_RSLT_TYPE_ERROR; 00402 } 00403 00404 /* 00405 * We use a common buffer for composing the log messages so we need to protect against 00406 * multiple threads calling us simultaneously. 00407 */ 00408 00409 result = cy_rtos_get_mutex(&cy_log.mutex, CY_RTOS_NEVER_TIMEOUT); 00410 if (result != CY_RSLT_SUCCESS) 00411 { 00412 return CY_RSLT_TYPE_ERROR; 00413 } 00414 00415 len = vsnprintf(cy_log.logbuf, CY_LOGBUF_SIZE, fmt, varg); 00416 if ((len == -1) || (len >= CY_LOGBUF_SIZE)) 00417 { 00418 /* The vsnprintf() output was truncated. */ 00419 cy_log.logbuf[CY_LOGBUF_SIZE - 1] = '\0'; 00420 } 00421 00422 cy_log.platform_log(CYLF_DEF, CY_LOG_PRINTF, cy_log.logbuf); 00423 00424 cy_rtos_set_mutex(&cy_log.mutex); 00425 00426 return result; 00427 } 00428 #ifdef __cplusplus 00429 } 00430 #endif
Generated on Thu Jul 14 2022 12:58:39 by
