Skip to content

Commit d643515

Browse files
authored
Merge pull request #397 from henrygab/SerializeLFS
Serialize lfs
2 parents fe2e978 + 76987ca commit d643515

File tree

10 files changed

+483
-128
lines changed

10 files changed

+483
-128
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
*.o
33
*.obj
44

5+
# Visual Studio Code
6+
**/.vscode/
7+
58
# Executables
69
*.out
710
*.app

cores/nRF5/rtos.cpp

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,33 +45,23 @@ static void _redirect_task(void* arg)
4545
while(1)
4646
{
4747
taskfunc();
48+
yield();
4849
}
4950
}
5051

5152
SchedulerRTOS::SchedulerRTOS(void)
5253
{
53-
_num = 1; // loop is already created by default
5454
}
5555

56-
bool SchedulerRTOS::startLoop(taskfunc_t task, uint32_t stack_size)
56+
bool SchedulerRTOS::startLoop(taskfunc_t task, uint32_t stack_size, uint32_t prio, const char* name)
5757
{
58-
char name[8] = "loop0";
59-
name[4] += _num;
60-
61-
if ( startLoop(task, name, stack_size) )
62-
{
63-
_num++;
64-
return true;
65-
}else
58+
static char const * const name_default = "unnamed_task";
59+
if (name == NULL)
6660
{
67-
return false;
61+
name = name_default;
6862
}
69-
}
70-
71-
bool SchedulerRTOS::startLoop(taskfunc_t task, const char* name, uint32_t stack_size)
72-
{
7363
TaskHandle_t handle;
74-
return pdPASS == xTaskCreate( _redirect_task, name, stack_size, (void*) task, TASK_PRIO_LOW, &handle);
64+
return pdPASS == xTaskCreate( _redirect_task, name, stack_size, (void*) task, prio, &handle);
7565
}
7666

7767

cores/nRF5/rtos.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,12 @@ static inline void rtos_free( void *pv )
8585

8686
class SchedulerRTOS
8787
{
88-
private:
89-
uint8_t _num;
90-
9188
public:
9289
typedef void (*taskfunc_t)(void);
9390

9491
SchedulerRTOS(void);
9592

96-
bool startLoop(taskfunc_t task, uint32_t stack_size = SCHEDULER_STACK_SIZE_DFLT);
97-
bool startLoop(taskfunc_t task, const char* name, uint32_t stack_size = SCHEDULER_STACK_SIZE_DFLT);
93+
bool startLoop(taskfunc_t task, uint32_t stack_size = SCHEDULER_STACK_SIZE_DFLT, uint32_t prio = TASK_PRIO_LOW, const char* name = NULL);
9894
};
9995

10096
extern SchedulerRTOS Scheduler;

cores/nRF5/utility/AdaCallback.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ bool ada_callback_queue_resize(uint32_t new_depth)
153153
QueueHandle_t new_queue = xQueueCreate(new_depth, sizeof(void*));
154154
VERIFY(new_queue);
155155

156-
LOG_LV1("MEMORY", "AdaCallback increase queue depth to %d", new_depth);
156+
LOG_LV1("MEMORY", "AdaCallback increase queue depth to %" PRId32, new_depth);
157157

158158
vTaskSuspend(_cb_task);
159159
taskENTER_CRITICAL();

cores/nRF5/verify.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,20 @@ extern "C"
5757
//--------------------------------------------------------------------+
5858
#if CFG_DEBUG >= 1
5959
#include <stdio.h>
60-
61-
#define VERIFY_MESS(_status, _funcstr) \
62-
do { \
63-
const char* (*_fstr)(int32_t) = _funcstr;\
64-
printf("%s: %d: verify failed, error = ", __PRETTY_FUNCTION__, __LINE__);\
65-
if (_fstr) printf(_fstr(_status)); else printf("%ld", _status);\
66-
printf("\n");\
67-
}while(0)
60+
#define VERIFY_MESS(_status, _functstr) VERIFY_MESS_impl(_status, _functstr, __PRETTY_FUNCTION__, __LINE__)
61+
static inline void VERIFY_MESS_impl(int32_t _status, const char* (*_fstr)(int32_t), const char* func_name, int line_number)
62+
{
63+
printf("%s: %d: verify failed, error = ", func_name, line_number);
64+
if (_fstr)
65+
{
66+
printf(_fstr(_status));
67+
}
68+
else
69+
{
70+
printf("%ld", _status);
71+
}
72+
printf("\n");
73+
}
6874
#else
6975
#define VERIFY_MESS(_status, _funcstr)
7076
#endif

libraries/Adafruit_LittleFS/src/Adafruit_LittleFS.cpp

Lines changed: 91 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Adafruit_LittleFS::Adafruit_LittleFS (struct lfs_config* cfg)
4444
varclr(&_lfs);
4545
_lfs_cfg = cfg;
4646
_mounted = false;
47+
_mutex = xSemaphoreCreateMutexStatic(&this->_MutexStorageSpace);
4748
}
4849

4950
Adafruit_LittleFS::~Adafruit_LittleFS ()
@@ -56,105 +57,157 @@ Adafruit_LittleFS::~Adafruit_LittleFS ()
5657
// User should format the disk and try again
5758
bool Adafruit_LittleFS::begin (struct lfs_config * cfg)
5859
{
59-
if ( _mounted ) return true;
60-
61-
if (cfg) _lfs_cfg = cfg;
62-
if (!_lfs_cfg) return false;
63-
64-
VERIFY_LFS(lfs_mount(&_lfs, _lfs_cfg), false);
65-
_mounted = true;
66-
67-
return true;
60+
xSemaphoreTake(_mutex, portMAX_DELAY);
61+
bool ret;
62+
// not a loop, just an quick way to short-circuit on error
63+
do {
64+
if (_mounted) { ret = true; break; }
65+
if (cfg) { _lfs_cfg = cfg; }
66+
if (nullptr == _lfs_cfg) { ret = false; break; }
67+
// actually attempt to mount, and log error if one occurs
68+
int err = lfs_mount(&_lfs, _lfs_cfg);
69+
PRINT_LFS_ERR(err);
70+
_mounted = (err == LFS_ERR_OK);
71+
ret = _mounted;
72+
} while(0);
73+
xSemaphoreGive(_mutex);
74+
return ret;
6875
}
6976

7077
// Tear down and unmount file system
7178
void Adafruit_LittleFS::end(void)
7279
{
73-
if (!_mounted) return;
74-
75-
_mounted = false;
76-
VERIFY_LFS(lfs_unmount(&_lfs), );
80+
xSemaphoreTake(_mutex, portMAX_DELAY);
81+
if (_mounted)
82+
{
83+
_mounted = false;
84+
int err = lfs_unmount(&_lfs);
85+
PRINT_LFS_ERR(err);
86+
(void)err;
87+
}
88+
xSemaphoreGive(_mutex);
7789
}
7890

7991
bool Adafruit_LittleFS::format (void)
8092
{
81-
// if already mounted: umount -> format -> remount
82-
if(_mounted) VERIFY_LFS(lfs_unmount(&_lfs), false);
83-
84-
VERIFY_LFS(lfs_format(&_lfs, _lfs_cfg), false);
85-
86-
if (_mounted) VERIFY_LFS(lfs_mount(&_lfs, _lfs_cfg), false);
93+
xSemaphoreTake(_mutex, portMAX_DELAY);
94+
int err = LFS_ERR_OK;
95+
bool attemptMount = _mounted;
96+
// not a loop, just an quick way to short-circuit on error
97+
do
98+
{
99+
// if already mounted: umount first -> format -> remount
100+
if (_mounted)
101+
{
102+
_mounted = false;
103+
err = lfs_unmount(&_lfs);
104+
if ( LFS_ERR_OK != err) { PRINT_LFS_ERR(err); break; }
105+
}
106+
err = lfs_format(&_lfs, _lfs_cfg);
107+
if ( LFS_ERR_OK != err ) { PRINT_LFS_ERR(err); break; }
87108

88-
return true;
109+
if (attemptMount)
110+
{
111+
err = lfs_mount(&_lfs, _lfs_cfg);
112+
if ( LFS_ERR_OK != err ) { PRINT_LFS_ERR(err); break; }
113+
_mounted = true;
114+
}
115+
// success!
116+
} while(0);
117+
xSemaphoreGive(_mutex);
118+
return LFS_ERR_OK == err;
89119
}
90120

91121
// Open a file or folder
92122
Adafruit_LittleFS_Namespace::File Adafruit_LittleFS::open (char const *filepath, uint8_t mode)
93123
{
124+
// No lock is required here ... the File() object will synchronize with the mutex provided
94125
return Adafruit_LittleFS_Namespace::File(filepath, mode, *this);
95126
}
96127

97128
// Check if file or folder exists
98129
bool Adafruit_LittleFS::exists (char const *filepath)
99130
{
100131
struct lfs_info info;
101-
return 0 == lfs_stat(&_lfs, filepath, &info);
132+
xSemaphoreTake(_mutex, portMAX_DELAY);
133+
bool ret = (0 == lfs_stat(&_lfs, filepath, &info));
134+
xSemaphoreGive(_mutex);
135+
return ret;
102136
}
103137

138+
104139
// Create a directory, create intermediate parent if needed
105140
bool Adafruit_LittleFS::mkdir (char const *filepath)
106141
{
142+
bool ret = true;
107143
const char* slash = filepath;
108144
if ( slash[0] == '/' ) slash++; // skip root '/'
109145

146+
xSemaphoreTake(_mutex, portMAX_DELAY);
147+
148+
// make intermediate parent directory(ies)
110149
while ( NULL != (slash = strchr(slash, '/')) )
111150
{
112151
char parent[slash - filepath + 1] = { 0 };
113152
memcpy(parent, filepath, slash - filepath);
114153

115-
// make intermediate parent
116154
int rc = lfs_mkdir(&_lfs, parent);
117155
if ( rc != LFS_ERR_OK && rc != LFS_ERR_EXIST )
118156
{
119157
PRINT_LFS_ERR(rc);
120-
return false;
158+
ret = false;
159+
break;
121160
}
122-
123161
slash++;
124162
}
125-
126-
int rc = lfs_mkdir(&_lfs, filepath);
127-
if ( rc != LFS_ERR_OK && rc != LFS_ERR_EXIST )
163+
// make the final requested directory
164+
if (ret)
128165
{
129-
PRINT_LFS_ERR(rc);
130-
return false;
166+
int rc = lfs_mkdir(&_lfs, filepath);
167+
if ( rc != LFS_ERR_OK && rc != LFS_ERR_EXIST )
168+
{
169+
PRINT_LFS_ERR(rc);
170+
ret = false;
171+
}
131172
}
132-
133-
return true;
173+
xSemaphoreGive(_mutex);
174+
return ret;
134175
}
135176

136177
// Remove a file
137178
bool Adafruit_LittleFS::remove (char const *filepath)
138179
{
139-
VERIFY_LFS(lfs_remove(&_lfs, filepath), false);
140-
return true;
180+
xSemaphoreTake(_mutex, portMAX_DELAY);
181+
int err = lfs_remove(&_lfs, filepath);
182+
PRINT_LFS_ERR(err);
183+
xSemaphoreGive(_mutex);
184+
return LFS_ERR_OK == err;
141185
}
142186

143187
// Remove a folder
144188
bool Adafruit_LittleFS::rmdir (char const *filepath)
145189
{
146-
VERIFY_LFS(lfs_remove(&_lfs, filepath));
147-
return true;
190+
xSemaphoreTake(_mutex, portMAX_DELAY);
191+
int err = lfs_remove(&_lfs, filepath);
192+
PRINT_LFS_ERR(err);
193+
xSemaphoreGive(_mutex);
194+
return LFS_ERR_OK == err;
148195
}
149196

150197
// Remove a folder recursively
151198
bool Adafruit_LittleFS::rmdir_r (char const *filepath)
152199
{
153200
/* adafruit: lfs is modified to remove non-empty folder,
154201
According to below issue, comment these 2 line won't corrupt filesystem
155-
https://github.com/ARMmbed/littlefs/issues/43 */
156-
VERIFY_LFS(lfs_remove(&_lfs, filepath));
157-
return true;
202+
at least when using LFS v1. If moving to LFS v2, see tracked issue
203+
to see if issues (such as the orphans in threaded linked list) are resolved.
204+
https://github.com/ARMmbed/littlefs/issues/43
205+
*/
206+
xSemaphoreTake(_mutex, portMAX_DELAY);
207+
int err = lfs_remove(&_lfs, filepath);
208+
PRINT_LFS_ERR(err);
209+
xSemaphoreGive(_mutex);
210+
return LFS_ERR_OK == err;
158211
}
159212

160213
//------------- Debug -------------//

libraries/Adafruit_LittleFS/src/Adafruit_LittleFS.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
// Internal Flash uses ARM Little FileSystem
3131
// https://github.com/ARMmbed/littlefs
3232
#include "littlefs/lfs.h"
33-
3433
#include "Adafruit_LittleFS_File.h"
34+
#include "rtos.h" // tied to FreeRTOS for serialization
3535

3636
class Adafruit_LittleFS
3737
{
@@ -76,14 +76,23 @@ class Adafruit_LittleFS
7676
bool _mounted;
7777
struct lfs_config* _lfs_cfg;
7878
lfs_t _lfs;
79+
80+
// these two functions need access to the private _mutex variable:
81+
friend void Adafruit_LittleFS_Namespace::File::_LockFilesystem(void);
82+
friend void Adafruit_LittleFS_Namespace::File::_UnlockFilesystem(void);
83+
//static_assert(configSUPPORT_STATIC_ALLOCATION == 1, "Currently only supports configuration with STATIC_ALLOCATION enabled");
84+
SemaphoreHandle_t _mutex;
85+
86+
private:
87+
StaticSemaphore_t _MutexStorageSpace;
7988
};
8089

8190
#if !CFG_DEBUG
8291
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, NULL)
8392
#define PRINT_LFS_ERR(_err)
8493
#else
8594
#define VERIFY_LFS(...) _GET_3RD_ARG(__VA_ARGS__, VERIFY_ERR_2ARGS, VERIFY_ERR_1ARGS)(__VA_ARGS__, dbg_strerr_lfs)
86-
#define PRINT_LFS_ERR(_err) VERIFY_MESS((long int)_err, dbg_strerr_lfs) // LFS_ERR are of type int, VERIFY_MESS expects long_int
95+
#define PRINT_LFS_ERR(_err) do { if (_err) { VERIFY_MESS((long int)_err, dbg_strerr_lfs); } } while(0) // LFS_ERR are of type int, VERIFY_MESS expects long_int
8796

8897
const char* dbg_strerr_lfs (int32_t err);
8998
#endif

0 commit comments

Comments
 (0)