Skip to content

Commit 4fd55a3

Browse files
committed
mmc: extract FileBufferedWriter
1 parent 0493c8d commit 4fd55a3

2 files changed

Lines changed: 134 additions & 104 deletions

File tree

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* @file file_writer.h
3+
*/
4+
5+
#pragma once
6+
7+
#include <cstring>
8+
9+
#include "buffered_writer.h"
10+
11+
#if EFI_PROD_CODE
12+
13+
#include "ff.h"
14+
#include "mmc_card_util.h"
15+
16+
// TODO: do we need this additioal layer of buffering?
17+
// FIL structure already have buffer of FF_MAX_SS size
18+
// check if it is better to increase FF_MAX_SS and drop BufferedWriter?
19+
struct FileBufferedWriter final : public BufferedWriter<512> {
20+
bool failed = false;
21+
22+
int init(FIL *fd) {
23+
if (m_fd) {
24+
efiPrintf("File writer already started!");
25+
return -1;
26+
}
27+
28+
m_size = 0;
29+
30+
m_fd = fd;
31+
32+
return 0;
33+
}
34+
35+
void stop() {
36+
m_fd = nullptr;
37+
38+
flush();
39+
40+
m_size = 0;
41+
}
42+
43+
size_t write(const char* buffer, size_t count) override {
44+
size_t ret = BufferedWriter::write(buffer, count);
45+
m_size += ret;
46+
return ret;
47+
}
48+
49+
size_t size() {
50+
return m_size;
51+
}
52+
53+
size_t writeInternal(const char* buffer, size_t count) override {
54+
if ((!m_fd) || (failed)) {
55+
return 0;
56+
}
57+
58+
size_t bytesWritten;
59+
efiAssert(ObdCode::CUSTOM_STACK_6627, hasLotsOfRemainingStack(), "sdlow#3", 0);
60+
FRESULT err = f_write(m_fd, buffer, count, &bytesWritten);
61+
62+
if (err) {
63+
printFatFsError("file_writer write", err);
64+
failed = true;
65+
return 0;
66+
} else if (bytesWritten != count) {
67+
printFatFsError("file_writer partitial write", err);
68+
failed = true;
69+
return 0;
70+
}
71+
72+
return bytesWritten;
73+
}
74+
75+
void sync() {
76+
if ((!m_fd) || (failed)) {
77+
return;
78+
}
79+
80+
f_sync(m_fd);
81+
}
82+
83+
private:
84+
FIL *m_fd = nullptr;
85+
size_t m_size = 0;
86+
};
87+
88+
#else // not EFI_PROD_CODE (simulator)
89+
90+
#include <fstream>
91+
92+
class FileBufferedWriter final : public BufferedWriter<512> {
93+
public:
94+
bool failed = false;
95+
96+
FileBufferedWriter()
97+
: m_stream("rusefi_simulator_log.mlg", std::ios::binary | std::ios::trunc)
98+
{
99+
sdLoggerReady = true;
100+
}
101+
102+
size_t writeInternal(const char* buffer, size_t count) override {
103+
m_stream.write(buffer, count);
104+
m_stream.flush();
105+
return count;
106+
}
107+
108+
void sync() {
109+
// NOP
110+
}
111+
112+
private:
113+
std::ofstream m_stream;
114+
};
115+
116+
#endif

firmware/hw_layer/mmc_card.cpp

Lines changed: 18 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
#if EFI_FILE_LOGGING
1818

19-
#include "buffered_writer.h"
19+
#include "file_writer.h"
2020
#include "status_loop.h"
2121
#include "binary_mlg_logging.h"
2222

@@ -47,106 +47,9 @@ static bool sdLoggerReady = false;
4747
#include "storage_sd.h"
4848
#endif // EFI_STORAGE_SD
4949

50-
// TODO: do we need this additioal layer of buffering?
51-
// FIL structure already have buffer of FF_MAX_SS size
52-
// check if it is better to increase FF_MAX_SS and drop BufferedWriter?
53-
struct SdLogBufferWriter final : public BufferedWriter<512> {
54-
bool failed = false;
55-
56-
int start(FIL *fd) {
57-
if (m_fd) {
58-
efiPrintf("SD logger already started!");
59-
return -1;
60-
}
61-
62-
totalLoggedBytes = 0;
63-
writeCounter = 0;
64-
65-
m_fd = fd;
66-
67-
return 0;
68-
}
69-
70-
void stop() {
71-
flush();
72-
73-
m_fd = nullptr;
74-
75-
totalLoggedBytes = 0;
76-
writeCounter = 0;
77-
}
78-
79-
size_t writen() {
80-
return totalLoggedBytes;
81-
}
82-
83-
size_t writeInternal(const char* buffer, size_t count) override {
84-
if ((!m_fd) || (failed)) {
85-
return 0;
86-
}
87-
88-
size_t bytesWritten;
89-
efiAssert(ObdCode::CUSTOM_STACK_6627, hasLotsOfRemainingStack(), "sdlow#3", 0);
90-
FRESULT err = f_write(m_fd, buffer, count, &bytesWritten);
91-
92-
if (err) {
93-
printFatFsError("log file write", err);
94-
failed = true;
95-
return 0;
96-
} else if (bytesWritten != count) {
97-
printFatFsError("log file write partitial", err);
98-
failed = true;
99-
return 0;
100-
} else {
101-
writeCounter++;
102-
totalLoggedBytes += count;
103-
if (writeCounter >= F_SYNC_FREQUENCY) {
104-
/**
105-
* Performance optimization: not f_sync after each line, f_sync is probably a heavy operation
106-
* todo: one day someone should actually measure the relative cost of f_sync
107-
*/
108-
f_sync(m_fd);
109-
writeCounter = 0;
110-
}
111-
}
112-
113-
return bytesWritten;
114-
}
115-
116-
private:
117-
FIL *m_fd = nullptr;
118-
119-
size_t totalLoggedBytes = 0;
120-
size_t writeCounter = 0;
121-
};
122-
123-
#else // not EFI_PROD_CODE (simulator)
124-
125-
#include <fstream>
126-
127-
class SdLogBufferWriter final : public BufferedWriter<512> {
128-
public:
129-
bool failed = false;
130-
131-
SdLogBufferWriter()
132-
: m_stream("rusefi_simulator_log.mlg", std::ios::binary | std::ios::trunc)
133-
{
134-
sdLoggerReady = true;
135-
}
136-
137-
size_t writeInternal(const char* buffer, size_t count) override {
138-
m_stream.write(buffer, count);
139-
m_stream.flush();
140-
return count;
141-
}
142-
143-
private:
144-
std::ofstream m_stream;
145-
};
146-
14750
#endif
14851

149-
static NO_CACHE SdLogBufferWriter logBuffer;
52+
static NO_CACHE FileBufferedWriter logBuffer;
15053

15154
#if EFI_PROD_CODE
15255

@@ -323,7 +226,7 @@ static void sdStatistics() {
323226
efiPrintf("SDIO mode");
324227
#endif
325228
if (sdLoggerIsReady()) {
326-
efiPrintf("filename=%s size=%d", logName, logBuffer.writen());
229+
efiPrintf("filename=%s size=%d", logName, logBuffer.size());
327230
}
328231
#if EFI_FILE_LOGGING
329232
efiPrintf("%d SD card fields", MLG::getSdCardFieldsCount());
@@ -659,8 +562,8 @@ static int sdTriggerLogger();
659562
static bool sdLoggerInitDone = false;
660563
static bool sdLoggerFailed = false;
661564

662-
static int sdLogger(FIL *fd)
663-
{
565+
// actually write logs on SD card
566+
static int sdLogger(FIL *fd) {
664567
int ret = 0;
665568

666569
if (!sdLoggerInitDone) {
@@ -669,7 +572,7 @@ static int sdLogger(FIL *fd)
669572

670573
ret = sdLoggerCreateFile(fd);
671574
if (ret == 0) {
672-
ret = logBuffer.start(fd);
575+
ret = logBuffer.init(fd);
673576
}
674577

675578
sdLoggerInitDone = true;
@@ -703,7 +606,7 @@ static int sdLogger(FIL *fd)
703606
// check if we need to start next log file
704607
// in next write (assume same size as current) will cross LOGGER_MAX_FILE_SIZE boundary
705608
// TODO: use f_tell() instead ?
706-
if (logBuffer.writen() + ret > LOGGER_MAX_FILE_SIZE) {
609+
if (logBuffer.size() + ret > LOGGER_MAX_FILE_SIZE) {
707610
logBuffer.stop();
708611
sdLoggerCloseFile(fd);
709612

@@ -972,6 +875,7 @@ static THD_FUNCTION(MMCmonThread, arg) {
972875
}
973876

974877
static int mlgLogger() {
878+
static size_t writeCounter = 0;
975879
// TODO: move this check somewhere out of here!
976880
// if the SPI device got un-picked somehow, cancel SD card
977881
// Don't do this check at all if using SDMMC interface instead of SPI
@@ -990,6 +894,16 @@ static int mlgLogger() {
990894
return -1;
991895
}
992896

897+
writeCounter++;
898+
if (writeCounter >= F_SYNC_FREQUENCY) {
899+
/**
900+
* Performance optimization: not f_sync after each line, sync is probably a heavy operation
901+
* todo: one day someone should actually measure the relative cost of sync
902+
*/
903+
logBuffer.sync();
904+
writeCounter = 0;
905+
}
906+
993907
auto freq = engineConfiguration->sdCardLogFrequency;
994908
if (freq > 250) {
995909
freq = 250;

0 commit comments

Comments
 (0)