48 s_current_num = find_next_file_number();
53 s_current_num = find_next_file_number();
56 return open_file(s_current_num);
60 static void write(
const char* str) {
62 size_t len = strlen(str);
65 size_t space = BUF_SIZE - s_pos;
66 size_t chunk = len < space ? len : space;
67 memcpy(s_buf + s_pos, p, chunk);
71 if (s_pos >= BUF_SIZE) {
80 if (!s_open || s_pos == 0)
return;
82 bool time_to_flush =
true;
84 uint32_t now = s_cfg.
millis();
85 uint32_t elapsed = now - s_last_flush_ms;
87 (s_pos >= BUF_SIZE * 3 / 4);
97 if (!s_open || s_pos == 0)
return;
112 static constexpr size_t BUF_SIZE = 512;
113 static constexpr size_t NAME_BUF = 16;
115 static void make_filename(
char* buf, uint16_t num) {
118 const char* p = s_cfg.
prefix;
119 while (*p && i < 4) buf[i++] = *p++;
121 buf[i++] =
'0' + (num / 100) % 10;
122 buf[i++] =
'0' + (num / 10) % 10;
123 buf[i++] =
'0' + num % 10;
131 static uint16_t find_next_file_number() {
135 for (uint16_t n = 0; n < s_cfg.
max_files; n++) {
136 make_filename(name, n);
137 if (f_stat(name, &fno) != FR_OK) {
144 static void delete_oldest() {
149 for (uint16_t n = 0; n < s_cfg.
max_files; n++) {
150 make_filename(name, n);
151 if (f_stat(name, &fno) == FR_OK) {
158 static bool open_file(uint16_t num) {
160 make_filename(name, num);
161 FRESULT fr = f_open(&s_fil, name, FA_WRITE | FA_CREATE_NEW);
162 if (fr != FR_OK)
return false;
168 static bool rotate_file() {
176 s_current_num = find_next_file_number();
179 return open_file(s_current_num);
182 static void flush_buffer() {
183 if (s_pos == 0)
return;
188 if (!rotate_file()) {
195 f_write(&s_fil, s_buf, s_pos, &bw);
201 s_last_flush_ms = s_cfg.
millis();
205 static inline SdLogConfig s_cfg;
206 static inline FIL s_fil;
207 static inline char s_buf[BUF_SIZE];
208 static inline size_t s_pos = 0;
209 static inline size_t s_file_bytes = 0;
210 static inline uint16_t s_current_num = 0;
211 static inline uint32_t s_last_flush_ms = 0;
212 static inline bool s_open =
false;