├── LICENSE ├── README.md ├── README_ZH.md ├── SConscript ├── ulog_easyflash.h ├── ulog_easyflash_be.c └── ulog_easyflash_cfg.c /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 RT-Thread packages by armink 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ulog plugin based on EasyFlash 2 | 3 | [中文页](README_ZH.md) | English 4 | 5 | ## 1. Introduction 6 | 7 | ulog is a brand new log component of RT-Thread. Its front-end and back-end separation design allows more back-ends to be easily connected. This software package mainly implements the two functions of **ulog's Flash backend** and **ulog's filter parameter storage**. Its bottom layer is based on the Flash flash library [EasyFlash](https://github.com/armink) /EasyFlash) makes it easy to save logs and filter parameters from ulog on Flash. Its main features are as follows: 8 | 9 | - Small resource occupation, seamless connection with ENV and LOG functions of EasyFlash; 10 | - Logs are stored in a circular replacement method. When the log partition is full, the oldest log will be automatically deleted; 11 | - The stored history log can be read into the RT-Thread console for easy reading and debugging; 12 | - Optionally read a part of recent logs to the RT-Thread console; 13 | - Automatically load the saved ulog filter parameters at startup; 14 | - All functions provide Finsh/MSH commands, support: log reading, log cleaning, saving filter parameters. 15 | 16 | ### 1.1 License 17 | 18 | This package complies with the MIT license, see the `LICENSE` file for details. 19 | 20 | ### 1.2 Dependency 21 | 22 | - RT-Thread 3.1.1+ 23 | - EasyFlash 3.0.0+ 24 | 25 | ## 2. How to open 26 | 27 | To use this package, you need to select it in the package manager of RT-Thread. The specific path is as follows: 28 | 29 | ``` 30 | RT-Thread online packages 31 | tools packages ---> 32 | [*] ulog_easyflash: The ulog flash plugin by EasyFlash. 33 | [*] Enable the flash backend for ulog 34 | [*] Save the ulog filter configuration to flash 35 | Version (latest) ---> 36 | ``` 37 | 38 | - `Enable the flash backend for ulog`: Enable the flash backend function of ulog; 39 | - `Save the ulog filter configuration to flash`: Turn on the function of saving ulog filter parameters. 40 | 41 | Then let RT-Thread's package manager automatically update, or use the `pkgs --update` command to update the package to the BSP. 42 | 43 | > **Note**: 44 | > 45 | >- If the LOG function of EasyFlash has not been enabled before, after opening this software package, you need to configure the log area size in the EasyFlash options. The configuration name is: Saved log area size. 46 | >- Before using the function of saving filter parameters, ensure that the runtime filter function is enabled on the ulog side, and the configuration name is: Enable runtime log filter. 47 | 48 | ## 3. Instructions for use 49 | 50 | ### 3.1 Flash backend initialization 51 | 52 | You need to call the initialization function `ulog_ef_backend_init()` at the application layer. If the project enables automatic component initialization, even this function does not need to be called. The component initialization function has been added to this function in the software package. 53 | 54 | ### 3.2 Set Flash log save level 55 | 56 | Through this function: `void ulog_ef_log_lvl_set(rt_uint32_t level)`, you can set the log level you want to save to Flash. Logs below this level will be **discarded**. Example: To set to save only the logs at the warning level and above, you can execute the following code: 57 | 58 | ```c 59 | ulog_ef_log_lvl_set(LOG_LVL_WARNING); 60 | ``` 61 | 62 | ### 3.3 Load ulog filter parameters 63 | 64 | Through this function: `void ulog_ef_filter_cfg_load(void)`, you can reprint the ulog filtering parameters already stored in Flash. If the project has enabled component auto-initialization, this function will run automatically upon power-up. 65 | 66 | ### 3.4 Save ulog filter parameters 67 | 68 | Through this function: `void ulog_ef_filter_cfg_save(void)`, you can save the filtering parameters that ulog has set to flash. This function also has a corresponding Finsh/MSH command: `ulog_filter_save`. When you need to save, just execute it. 69 | 70 | ### 3.5 Use of Finsh/MSH commands 71 | 72 | The command format related to Flash log is `ulog_flash ` 73 | 74 | #### 3.5.1 Historical log reading 75 | 76 | After the history log is saved in Flash, it can be read to the console through the following command, which is convenient for developers to review the log and analyze the problem. 77 | 78 | - To read all historical logs, enter the command: `ulog_flash read` 79 | 80 | ```shell 81 | msh />ulog_flash read 82 | 10-23 10:28:51.618 D/example tshell: LOG_D(1): RT-Thread is an open source IoT operating system from China. 83 | 10-23 10:28:51.618 I/example tshell: LOG_I(1): RT-Thread is an open source IoT 84 | ...... 85 | msh /> 86 | ``` 87 | 88 | - To read the recent 200-byte log, enter the command: `ulog_flash read 200` 89 | 90 | ```shell 91 | msh />ulog_flash read 200 92 | log_w(50): RT-Thread is an open source IoT operating system from China. 93 | 10-23 19:37:05.137 E/test tshell: ulog_e(50): RT-Thread is an open source IoT operating system from China. 94 | 95 | msh /> 96 | ``` 97 | 98 | #### 3.5.2 Clear history log 99 | 100 | When you need to clear all historical logs in the log area, you can enter the command: `ulog_flash clean` 101 | 102 | ```shell 103 | msh />ulog_flash clean 104 | 10-24 10:00:22.307 I/easyflash tshell: All logs which in flash is clean OK. 105 | msh /> 106 | ``` 107 | 108 | Wait for a while, the log cleaning is complete, a prompt of successful cleaning will be displayed. 109 | 110 | #### 3.5.3 Save ulog filter parameters to Flash 111 | 112 | In the debugging and development process, after the ulog filter parameters are set, if you need to save, you can enter the command: `ulog_filter_save`. After saving, restart and use the `ulog_filter` command again, you can see the previously saved filter parameters. 113 | 114 | ```shell 115 | msh />ulog_filter_save 116 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:821) Calculate ENV CRC32 number is 0x10C41F91. 117 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:774) Erased ENV OK. 118 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:788) Saved ENV OK. 119 | msh /> 120 | ``` 121 | 122 | ## 4. Matters needing attention 123 | 124 | - Before using this package, make sure that the dependent options are opened in advance, otherwise the options cannot be seen in menuconfig. 125 | 126 | ## 5. Contact & Thanks 127 | 128 | * Maintenance: [armink](https://github.com/armink) 129 | * Homepage: https://github.com/armink-rtt-pkgs/ulog_easyflash 130 | -------------------------------------------------------------------------------- /README_ZH.md: -------------------------------------------------------------------------------- 1 | # 基于 EasyFlash 的 ulog 插件 2 | 3 | 中文页 | [English](README.md) 4 | 5 | ## 1、介绍 6 | 7 | ulog 是 RT-Thread 全新的日志组件,其前后端分离式设计,使得更多的后端可以轻松的对接上去。该软件包主要实现了 **ulog 的 Flash 后端** 以及 **ulog 的过滤器参数存储** 两大功能,它的底层基于 Flash 闪存库 [EasyFlash](https://github.com/armink/EasyFlash) ,使得来自于 ulog 的日志及过滤参数可以轻松保存在 Flash 上。其主要功能特点如下: 8 | 9 | - 资源占用小,与 EasyFlash 的 ENV 及 LOG 功能无缝对接; 10 | - 日志采用循环替换方式进行存储,当日志分区满了以后,会自动删除最久的日志; 11 | - 已存储的历史日志支持读取到 RT-Thread 控制台中,便于阅读、调试; 12 | - 可选择性的读取近期一部分日志到 RT-Thread 控制台中; 13 | - 开机自动装载已保存的 ulog 过滤参数; 14 | - 所有功能提供了 Finsh/MSH 命令,支持:日志读取,日志清理,保存过滤参数。 15 | 16 | ### 1.1 许可证 17 | 18 | 本软件包遵循 MIT 许可,详见 `LICENSE` 文件。 19 | 20 | ### 1.2 依赖 21 | 22 | - RT-Thread 3.1.1+ 23 | - EasyFlash 3.0.0+ 24 | 25 | ## 2、如何打开 26 | 27 | 使用本软件包需要在 RT-Thread 的包管理器中选择它,具体路径如下: 28 | 29 | ``` 30 | RT-Thread online packages 31 | tools packages ---> 32 | [*] ulog_easyflash: The ulog flash plugin by EasyFlash. 33 | [*] Enable the flash backend for ulog 34 | [*] Save the ulog filter configuration to flash 35 | Version (latest) ---> 36 | ``` 37 | 38 | - `Enable the flash backend for ulog`:开启 ulog 的 flash 后端功能; 39 | - `Save the ulog filter configuration to flash`:开启保存 ulog 过滤参数的功能。 40 | 41 | 然后让 RT-Thread 的包管理器自动更新,或者使用 `pkgs --update` 命令更新包到 BSP 中。 42 | 43 | > **注意** : 44 | > 45 | > - 如果之前未开启 EasyFlash 的 LOG 功能,开启本软件包后,需要在 EasyFlash 选项中配置日志区域大小,配置名称为: Saved log area size。 46 | > - 使用保存过滤参数功能前,需保证 ulog 那边开启了运行时过滤功能,配置名称为:Enable runtime log filter. 47 | 48 | ## 3、使用说明 49 | 50 | ### 3.1 Flash 后端初始化 51 | 52 | 需要在应用层调用 `ulog_ef_backend_init()` 初始化函数即可。如果项目开启了组件自动初始化,甚至连这个函数都无需调用,软件包里已经为这个函数添加了组件初始化功能。 53 | 54 | ### 3.2 设定 Flash 日志保存级别 55 | 56 | 通过该函数:`void ulog_ef_log_lvl_set(rt_uint32_t level)` ,可以设定想要保存到 Flash 里的日志级别,低于该级别的日志将被 **丢弃** 。举例:设定只保存警告(含)以上级别的日志,可以执行如下代码 : 57 | 58 | ```c 59 | ulog_ef_log_lvl_set(LOG_LVL_WARNING); 60 | ``` 61 | 62 | ### 3.3 装载 ulog 过滤参数 63 | 64 | 通过该函数:`void ulog_ef_filter_cfg_load(void)` ,可以转载 Flash 中已经存储的 ulog 过滤参数。如果项目开启了组件自动初始化,这个函数会在上电时自动运行。 65 | 66 | ### 3.4 保存 ulog 过滤参数 67 | 68 | 通过该函数:`void ulog_ef_filter_cfg_save(void)` ,可以将 ulog 已设定的过滤参数保存至 flash 中,该函数也有对应的 Finsh/MSH 命令:`ulog_filter_save` ,需要保存时,执行一下即可。 69 | 70 | ### 3.5 Finsh/MSH 命令的使用 71 | 72 | Flash 日志相关的命令格式为 `ulog_flash ` 73 | 74 | #### 3.5.1 历史日志读取 75 | 76 | 历史日志存到 Flash 后,可以通过下面的命令读取到控制台上,方便开发者回顾日志,分析问题。 77 | 78 | - 读取全部的历史日志,输入命令:`ulog_flash read` 79 | 80 | ```shell 81 | msh />ulog_flash read 82 | 10-23 10:28:51.618 D/example tshell: LOG_D(1): RT-Thread is an open source IoT operating system from China. 83 | 10-23 10:28:51.618 I/example tshell: LOG_I(1): RT-Thread is an open source IoT 84 | ...... 85 | msh /> 86 | ``` 87 | 88 | - 读取近期的 200 字节日志,输入命令:`ulog_flash read 200` 89 | 90 | ```shell 91 | msh />ulog_flash read 200 92 | log_w(50): RT-Thread is an open source IoT operating system from China. 93 | 10-23 19:37:05.137 E/test tshell: ulog_e(50): RT-Thread is an open source IoT operating system from China. 94 | 95 | msh /> 96 | ``` 97 | 98 | #### 3.5.2 清空历史日志 99 | 100 | 当需要清空日志区的全部历史日志时,可以输入命令: `ulog_flash clean` 101 | 102 | ```shell 103 | msh />ulog_flash clean 104 | 10-24 10:00:22.307 I/easyflash tshell: All logs which in flash is clean OK. 105 | msh /> 106 | ``` 107 | 108 | 稍等片刻,日志清理完成将会显示清理成功的提示。 109 | 110 | #### 3.5.3 保存 ulog 的过滤参数至 Flash 111 | 112 | 在调试开发过程中,ulog 的过滤参数设定完成后,如果需要保存,可以输入命令:`ulog_filter_save` 。保存完完成后,重启再次使用 `ulog_filter` 命令,可以看到之前保存的过滤参数。 113 | 114 | ```shell 115 | msh />ulog_filter_save 116 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:821) Calculate ENV CRC32 number is 0x10C41F91. 117 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:774) Erased ENV OK. 118 | [Flash] (../packages/EasyFlash-latest/src/ef_env.c:788) Saved ENV OK. 119 | msh /> 120 | ``` 121 | 122 | ## 4、注意事项 123 | 124 | - 使用本软件包前,需保证依赖的选项被提前打开,否则在 menuconfig 无法看到选项。 125 | 126 | ## 5、联系方式 & 感谢 127 | 128 | * 维护:[armink](https://github.com/armink) 129 | * 主页:https://github.com/armink-rtt-pkgs/ulog_easyflash 130 | -------------------------------------------------------------------------------- /SConscript: -------------------------------------------------------------------------------- 1 | from building import * 2 | 3 | cwd = GetCurrentDir() 4 | src = Glob('*.c') 5 | CPPPATH = [cwd] 6 | 7 | group = DefineGroup('EasyFlash', src, depend = ['PKG_USING_ULOG_EASYFLASH'], CPPPATH = CPPPATH) 8 | 9 | Return('group') 10 | -------------------------------------------------------------------------------- /ulog_easyflash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the EasyFlash Library. 3 | * 4 | * Copyright (c) 2014-2018, Armink, 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files (the 8 | * 'Software'), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * The ulog flash plugin by EasyFlash. 26 | * Created on: 2018-10-22 27 | */ 28 | 29 | #ifndef _ULOG_EASYFLASH_H_ 30 | #define _ULOG_EASYFLASH_H_ 31 | 32 | int ulog_ef_backend_init(void); 33 | void ulog_ef_log_clean(void); 34 | void ulog_ef_log_lvl_set(rt_uint32_t level); 35 | int ulog_ef_filter_cfg_load(void); 36 | void ulog_ef_filter_cfg_save(void); 37 | 38 | #endif /* _ULOG_EASYFLASH_H_ */ 39 | -------------------------------------------------------------------------------- /ulog_easyflash_be.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the EasyFlash Library. 3 | * 4 | * Copyright (c) 2014-2018, Armink, 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files (the 8 | * 'Software'), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * The ulog backend implementation for EasyFlash. 26 | * Created on: 2018-10-22 27 | */ 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #define LOG_TAG "easyflash" 35 | #include 36 | 37 | #ifdef ULOG_EASYFLASH_BACKEND_ENABLE 38 | 39 | #if defined(ULOG_ASYNC_OUTPUT_BY_THREAD) && ULOG_ASYNC_OUTPUT_THREAD_STACK < 1024 40 | #error "The thread stack size must more than 1024 when using async output by thread (ULOG_ASYNC_OUTPUT_BY_THREAD)" 41 | #endif 42 | 43 | static struct ulog_backend flash_backend; 44 | static rt_uint32_t log_saving_lvl = LOG_FILTER_LVL_ALL; 45 | 46 | /** 47 | * Read and output log to console. 48 | * 49 | * @param index index for saved log. 50 | * Minimum index is 0. 51 | * Maximum index is log used flash total size - 1. 52 | * @param size 53 | */ 54 | static void read_flash_log(size_t index, size_t size) 55 | { 56 | /* 64 bytes buffer */ 57 | uint32_t buf[16] = { 0 }; 58 | size_t log_total_size = ef_log_get_used_size(); 59 | size_t buf_size = sizeof(buf); 60 | size_t read_size = 0; 61 | 62 | /* word alignment for index and size */ 63 | index = RT_ALIGN_DOWN(index, 4); 64 | size = RT_ALIGN_DOWN(size, 4); 65 | if (index + size > log_total_size) 66 | { 67 | rt_kprintf("The output position and size is out of bound. The max size is %d.\n", log_total_size); 68 | return; 69 | } 70 | 71 | while (1) 72 | { 73 | if (read_size + buf_size < size) 74 | { 75 | ef_log_read(index + read_size, buf, buf_size); 76 | rt_kprintf("%.*s", buf_size, buf); 77 | read_size += buf_size; 78 | } 79 | else 80 | { 81 | ef_log_read(index + read_size, buf, size - read_size); 82 | rt_kprintf("%.*s", size - read_size, buf); 83 | /* output newline sign */ 84 | rt_kprintf(ULOG_NEWLINE_SIGN); 85 | break; 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * Read and output all log which saved in flash. 92 | */ 93 | static void read_all_flash_log(void) 94 | { 95 | read_flash_log(0, ef_log_get_used_size()); 96 | } 97 | 98 | 99 | /** 100 | * Read and output recent log which saved in flash. 101 | * 102 | * @param size recent log size 103 | */ 104 | static void read_recent_flash_log(size_t size) 105 | { 106 | size_t max_size = ef_log_get_used_size(); 107 | 108 | if (size == 0) 109 | { 110 | return; 111 | } 112 | 113 | if (size > max_size) 114 | { 115 | rt_kprintf("The output size is out of bound. The max size is %d.\n", max_size); 116 | } 117 | else 118 | { 119 | read_flash_log(max_size - size, size); 120 | } 121 | } 122 | 123 | /** 124 | * clean all log which in flash 125 | */ 126 | void ulog_ef_log_clean(void) 127 | { 128 | EfErrCode clean_result = EF_NO_ERR; 129 | 130 | /* clean all log which in flash */ 131 | clean_result = ef_log_clean(); 132 | 133 | if (clean_result == EF_NO_ERR) 134 | { 135 | LOG_I("All logs which in flash is clean OK."); 136 | } 137 | else 138 | { 139 | LOG_E("Clean logs which in flash has an error!"); 140 | } 141 | } 142 | 143 | static void ulog_easyflash_backend_output(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw, 144 | const char *log, size_t len) 145 | { 146 | /* write some '\r' for word alignment */ 147 | char write_overage_c[4] = { '\r', '\r', '\r', '\r' }; 148 | size_t write_size_temp = 0; 149 | EfErrCode result = EF_NO_ERR; 150 | 151 | /* saving level filter for flash log */ 152 | if (level <= log_saving_lvl) 153 | { 154 | /* calculate the word alignment write size */ 155 | write_size_temp = RT_ALIGN_DOWN(len, 4); 156 | 157 | result = ef_log_write((uint32_t *) log, write_size_temp); 158 | /* write last word alignment data */ 159 | if ((result == EF_NO_ERR) && (write_size_temp != len)) 160 | { 161 | memcpy(write_overage_c, log + write_size_temp, len - write_size_temp); 162 | ef_log_write((uint32_t *) write_overage_c, sizeof(write_overage_c)); 163 | } 164 | } 165 | } 166 | 167 | /** 168 | * Set flash log saving level. The log which level less than setting will stop saving to flash. 169 | * 170 | * @param level setting level 171 | */ 172 | void ulog_ef_log_lvl_set(rt_uint32_t level) 173 | { 174 | log_saving_lvl = level; 175 | } 176 | 177 | int ulog_ef_backend_init(void) 178 | { 179 | flash_backend.output = ulog_easyflash_backend_output; 180 | 181 | ulog_backend_register(&flash_backend, "easyflash", RT_TRUE); 182 | 183 | return 0; 184 | } 185 | INIT_APP_EXPORT(ulog_ef_backend_init); 186 | 187 | #if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) 188 | #include 189 | static void ulog_flash(uint8_t argc, char **argv) 190 | { 191 | if (argc >= 2) 192 | { 193 | if (!strcmp(argv[1], "read")) 194 | { 195 | if (argc >= 3) 196 | { 197 | read_recent_flash_log(atol(argv[2])); 198 | } 199 | else 200 | { 201 | read_all_flash_log(); 202 | } 203 | } 204 | else if (!strcmp(argv[1], "clean")) 205 | { 206 | ulog_ef_log_clean(); 207 | } 208 | else 209 | { 210 | rt_kprintf("Please input ulog_flash .\n"); 211 | } 212 | } 213 | else 214 | { 215 | rt_kprintf("Please input ulog_flash .\n"); 216 | } 217 | } 218 | MSH_CMD_EXPORT(ulog_flash, ulog flash log by EasyFlash backend); 219 | #endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */ 220 | 221 | #endif /* ULOG_EASYFLASH_BACKEND_ENABLE */ 222 | -------------------------------------------------------------------------------- /ulog_easyflash_cfg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the EasyFlash Library. 3 | * 4 | * Copyright (c) 2014-2018, Armink, 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining 7 | * a copy of this software and associated documentation files (the 8 | * 'Software'), to deal in the Software without restriction, including 9 | * without limitation the rights to use, copy, modify, merge, publish, 10 | * distribute, sublicense, and/or sell copies of the Software, and to 11 | * permit persons to whom the Software is furnished to do so, subject to 12 | * the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 | * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 | * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 | * 25 | * The ulog filter configuration store implement by EasyFlash. 26 | * Created on: 2018-11-08 27 | */ 28 | 29 | #include 30 | 31 | #ifdef ULOG_EASYFLASH_CFG_SAVE_ENABLE 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #define LOG_TAG "easyflash" 38 | #include 39 | 40 | #define ENV_FILTER_GLOBAL_LVL_NAME "ulog.lvl" 41 | #define ENV_FILTER_GLOBAL_TAG_NAME "ulog.tag" 42 | #define ENV_FILTER_GLOBAL_KW_NAME "ulog.kw" 43 | #define ENV_FILTER_TAG_LVL_NAME "ulog.tag_lvl" 44 | 45 | extern size_t ulog_ultoa(char *s, unsigned long int n); 46 | 47 | /** 48 | * load the ulog configuration on flash 49 | * 50 | * @return result, 0 : success, else error 51 | * 52 | * @note don't using `&` and `##` on log tag definition when using this function. 53 | */ 54 | int ulog_ef_filter_cfg_load(void) 55 | { 56 | char *value; 57 | 58 | /* restore the saving global level */ 59 | if ((value = ef_get_env(ENV_FILTER_GLOBAL_LVL_NAME)) != NULL) 60 | { 61 | ulog_global_filter_lvl_set(atoi(value)); 62 | } 63 | 64 | /* restore the saving global tag */ 65 | if ((value = ef_get_env(ENV_FILTER_GLOBAL_TAG_NAME)) != NULL) 66 | { 67 | ulog_global_filter_tag_set(value); 68 | } 69 | 70 | /* restore the saving global kw */ 71 | if ((value = ef_get_env(ENV_FILTER_GLOBAL_KW_NAME)) != NULL) 72 | { 73 | ulog_global_filter_kw_set(value); 74 | } 75 | 76 | /* restore the saving tag level list */ 77 | if ((value = ef_get_env(ENV_FILTER_TAG_LVL_NAME)) != NULL) 78 | { 79 | char lvl_num[11], tag[ULOG_FILTER_TAG_MAX_LEN + 1], *lvl_pos, *next_node; 80 | rt_size_t node_len; 81 | /* decode every tag's level */ 82 | while (1) 83 | { 84 | /* find every node */ 85 | if ((next_node = strstr(value, "##")) != NULL) 86 | { 87 | node_len = next_node - value; 88 | } 89 | else 90 | { 91 | node_len = rt_strlen(value); 92 | } 93 | /* find level pos */ 94 | lvl_pos = strstr(value, "&"); 95 | if (lvl_pos != NULL && lvl_pos < value + node_len) 96 | { 97 | rt_strncpy(tag, value, lvl_pos - value); 98 | rt_strncpy(lvl_num, lvl_pos + 1, value + node_len - lvl_pos - 1); 99 | tag[lvl_pos - value] = '\0'; 100 | lvl_num[value + node_len - lvl_pos - 1] = '\0'; 101 | /* add a tag's level filter */ 102 | ulog_tag_lvl_filter_set(tag, atoi(lvl_num)); 103 | } 104 | else 105 | { 106 | LOG_W("Warning: tag's level decode failed!"); 107 | break; 108 | } 109 | 110 | if (next_node) 111 | { 112 | value = next_node + 2; 113 | } 114 | else 115 | { 116 | break; 117 | } 118 | } 119 | } 120 | 121 | return 0; 122 | } 123 | INIT_APP_EXPORT(ulog_ef_filter_cfg_load); 124 | 125 | /** 126 | * save the ulog filter configuration to flash 127 | * 128 | * @note don't using `&` and `##` on log tag definition when using this function. 129 | */ 130 | void ulog_ef_filter_cfg_save(void) 131 | { 132 | unsigned char *cfgs = NULL; 133 | char lvl_num[11]; 134 | 135 | /* set the global level env */ 136 | { 137 | ulog_ultoa(lvl_num, ulog_global_filter_lvl_get()); 138 | ef_set_env(ENV_FILTER_GLOBAL_LVL_NAME, lvl_num); 139 | } 140 | 141 | /* set the global tag env */ 142 | if (rt_strlen(ulog_global_filter_tag_get())) 143 | { 144 | ef_set_env(ENV_FILTER_GLOBAL_TAG_NAME, ulog_global_filter_tag_get()); 145 | } 146 | else if(ef_get_env(ENV_FILTER_GLOBAL_TAG_NAME)) 147 | { 148 | ef_del_env(ENV_FILTER_GLOBAL_TAG_NAME); 149 | } 150 | 151 | /* set the global kw env */ 152 | if (rt_strlen(ulog_global_filter_kw_get())) 153 | { 154 | ef_set_env(ENV_FILTER_GLOBAL_KW_NAME, ulog_global_filter_kw_get()); 155 | } 156 | else if(ef_get_env(ENV_FILTER_GLOBAL_KW_NAME)) 157 | { 158 | ef_del_env(ENV_FILTER_GLOBAL_KW_NAME); 159 | } 160 | 161 | /* set the tag's level env */ 162 | { 163 | rt_slist_t *node; 164 | ulog_tag_lvl_filter_t tag_lvl = NULL; 165 | rt_size_t node_size, tag_len, lvl_len; 166 | int cfgs_size = 0; 167 | 168 | for (node = rt_slist_first(ulog_tag_lvl_list_get()); node; node = rt_slist_next(node)) 169 | { 170 | tag_lvl = rt_slist_entry(node, struct ulog_tag_lvl_filter, list); 171 | ulog_ultoa(lvl_num, tag_lvl->level); 172 | tag_len = rt_strlen(tag_lvl->tag); 173 | lvl_len = rt_strlen(lvl_num); 174 | /* env string format: tag_name1&tag_lvl1##tag_name2&tag_lvl2## */ 175 | node_size = tag_len + 1 + lvl_len + 2; 176 | cfgs_size += node_size; 177 | cfgs = (unsigned char *) rt_realloc(cfgs, cfgs_size); 178 | if (cfgs == NULL) 179 | { 180 | LOG_W("Warning: no memory for save cfgs"); 181 | goto __exit; 182 | } 183 | rt_memcpy(cfgs + cfgs_size - node_size , tag_lvl->tag, tag_len); 184 | rt_memcpy(cfgs + cfgs_size - node_size + tag_len , "&", 1); 185 | rt_memcpy(cfgs + cfgs_size - node_size + tag_len + 1 , lvl_num, lvl_len); 186 | rt_memcpy(cfgs + cfgs_size - node_size + tag_len + 1 + lvl_len, "##", 2); 187 | } 188 | 189 | if((cfgs)&&(cfgs_size>2)) 190 | { 191 | cfgs[cfgs_size - 2] = '\0'; 192 | ef_set_env(ENV_FILTER_TAG_LVL_NAME, (char *)cfgs); 193 | } 194 | else if(ef_get_env(ENV_FILTER_TAG_LVL_NAME)) 195 | { 196 | ef_del_env(ENV_FILTER_TAG_LVL_NAME); 197 | } 198 | } 199 | 200 | __exit: 201 | /* save the ulog filter env */ 202 | ef_save_env(); 203 | 204 | if (cfgs) 205 | { 206 | rt_free(cfgs); 207 | } 208 | } 209 | #if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) 210 | #include 211 | MSH_CMD_EXPORT_ALIAS(ulog_ef_filter_cfg_save, ulog_filter_save, Save the ulog filter settings); 212 | #endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */ 213 | 214 | #endif /* ULOG_EASYFLASH_CFG_SAVE_ENABLE */ 215 | --------------------------------------------------------------------------------