47 s_current_num = find_next_file_number();
52 s_current_num = find_next_file_number();
55 return open_file(s_current_num);
59 static void write(
const char* str) {
61 size_t len = strlen(str);
64 size_t space = BUF_SIZE - s_pos;
65 size_t chunk = len < space ? len : space;
66 memcpy(s_buf + s_pos, p, chunk);
70 if (s_pos >= BUF_SIZE) {
79 if (!s_open || s_pos == 0)
return;
81 bool time_to_flush =
true;
83 uint32_t now = s_cfg.
millis();
84 uint32_t elapsed = now - s_last_flush_ms;
86 (s_pos >= BUF_SIZE * 3 / 4);
96 if (!s_open || s_pos == 0)
return;
111 static constexpr size_t BUF_SIZE = 512;
112 static constexpr size_t NAME_BUF = 16;
114 static void make_filename(
char* buf, uint16_t num) {
117 const char* p = s_cfg.
prefix;
118 while (*p && i < 4) buf[i++] = *p++;
120 buf[i++] =
'0' + (num / 100) % 10;
121 buf[i++] =
'0' + (num / 10) % 10;
122 buf[i++] =
'0' + num % 10;
130 static uint16_t find_next_file_number() {
134 for (uint16_t n = 0; n < s_cfg.
max_files; n++) {
135 make_filename(name, n);
136 if (f_stat(name, &fno) != FR_OK) {
143 static void delete_oldest() {
148 for (uint16_t n = 0; n < s_cfg.
max_files; n++) {
149 make_filename(name, n);
150 if (f_stat(name, &fno) == FR_OK) {
157 static bool open_file(uint16_t num) {
159 make_filename(name, num);
160 FRESULT fr = f_open(&s_fil, name, FA_WRITE | FA_CREATE_NEW);
161 if (fr != FR_OK)
return false;
167 static bool rotate_file() {
175 s_current_num = find_next_file_number();
178 return open_file(s_current_num);
181 static void flush_buffer() {
182 if (s_pos == 0)
return;
187 if (!rotate_file()) {
194 f_write(&s_fil, s_buf, s_pos, &bw);
200 s_last_flush_ms = s_cfg.
millis();
204 static inline SdLogConfig s_cfg;
205 static inline FIL s_fil;
206 static inline char s_buf[BUF_SIZE];
207 static inline size_t s_pos = 0;
208 static inline size_t s_file_bytes = 0;
209 static inline uint16_t s_current_num = 0;
210 static inline uint32_t s_last_flush_ms = 0;
211 static inline bool s_open =
false;