Remove old HAL components and refactored GPS-related code (#583)
- Added generic GPS/GNSS support with device detection, configuration, and persistent settings. - Improved device and module lifecycle management. - Added flexible filesystem locking support for displays and storage. - Improved display-idle and keyboard backlight handling. - Updated architecture, driver, module, testing, and licensing documentation. - Removed old HAL device and related code.
This commit is contained in:
committed by
GitHub
parent
29e80cfd65
commit
2a2558b29a
@@ -4,7 +4,9 @@
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <tactility/filesystem/file_mutex.h>
|
||||
#include <tactility/log.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
|
||||
namespace tt::hal::sdcard {
|
||||
@@ -15,30 +17,25 @@ namespace tt::file {
|
||||
|
||||
constexpr auto* TAG = "file";
|
||||
|
||||
class NoLock final : public Lock {
|
||||
bool lock(TickType_t timeout) const override { return true; }
|
||||
void unlock() const override { /* NO-OP */ }
|
||||
class FileMutexLock final : public Lock {
|
||||
FileMutex mutex;
|
||||
|
||||
public:
|
||||
explicit FileMutexLock(const std::string& path) {
|
||||
file_mutex_get(&mutex, path.c_str());
|
||||
}
|
||||
|
||||
bool lock(TickType_t timeout) const override {
|
||||
return file_mutex_try_lock(&mutex, timeout);
|
||||
}
|
||||
|
||||
void unlock() const override {
|
||||
file_mutex_unlock(&mutex);
|
||||
}
|
||||
};
|
||||
|
||||
static std::shared_ptr<Lock> noLock = std::make_shared<NoLock>();
|
||||
static std::function<std::shared_ptr<Lock>(const std::string&)> findLockFunction = nullptr;
|
||||
|
||||
std::shared_ptr<Lock> getLock(const std::string& path) {
|
||||
if (findLockFunction == nullptr) {
|
||||
LOG_W(TAG, "File lock function not set!");
|
||||
return noLock;
|
||||
}
|
||||
|
||||
auto lock = findLockFunction(path);
|
||||
if (lock == nullptr) {
|
||||
return noLock;
|
||||
}
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
void setFindLockFunction(const FindLockFunction& function) {
|
||||
findLockFunction = function;
|
||||
return std::make_shared<FileMutexLock>(path);
|
||||
}
|
||||
|
||||
std::string getChildPath(const std::string& basePath, const std::string& childPath) {
|
||||
@@ -68,7 +65,8 @@ bool listDirectory(
|
||||
const std::string& path,
|
||||
std::function<void(const dirent&)> onEntry
|
||||
) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
LOG_I(TAG, "listDir start %s", path.c_str());
|
||||
@@ -95,7 +93,8 @@ int scandir(
|
||||
ScandirFilter filterMethod,
|
||||
ScandirSort sortMethod
|
||||
) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
LOG_I(TAG, "scandir start");
|
||||
@@ -221,7 +220,8 @@ bool writeString(const std::string& filepath, const std::string& content) {
|
||||
}
|
||||
|
||||
static bool findOrCreateDirectoryInternal(std::string path, mode_t mode) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
struct stat dir_stat;
|
||||
@@ -336,32 +336,37 @@ bool deleteRecursively(const std::string& path) {
|
||||
}
|
||||
|
||||
bool deleteFile(const std::string& path) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
return remove(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
bool deleteDirectory(const std::string& path) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
return rmdir(path.c_str()) == 0;
|
||||
}
|
||||
|
||||
bool isFile(const std::string& path) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
return access(path.c_str(), F_OK) == 0;
|
||||
}
|
||||
|
||||
bool isDirectory(const std::string& path) {
|
||||
auto lock = getLock(path)->asScopedLock();
|
||||
auto lockable = getLock(path);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
struct stat stat_result;
|
||||
return stat(path.c_str(), &stat_result) == 0 && S_ISDIR(stat_result.st_mode);
|
||||
}
|
||||
|
||||
bool readLines(const std::string& filePath, bool stripNewLine, std::function<void(const char* line)> callback) {
|
||||
auto lock = getLock(filePath)->asScopedLock();
|
||||
auto lockable = getLock(filePath);
|
||||
auto lock = lockable->asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
auto* file = fopen(filePath.c_str(), "r");
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#include "Tactility/file/FileLock.h"
|
||||
|
||||
#include <Tactility/hal/SdCard.h>
|
||||
|
||||
namespace tt::file {
|
||||
|
||||
std::shared_ptr<Lock> findLock(const std::string& path) {
|
||||
return hal::sdcard::findSdCardLock(path);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/drivers/display.h>
|
||||
#include <tactility/drivers/spi_controller.h>
|
||||
#include <tactility/filesystem/file_mutex.h>
|
||||
#include <tactility/filesystem/file_system.h>
|
||||
#include <tactility/lvgl_module.h>
|
||||
|
||||
constexpr auto* TAG = "file_mutex_lvgl";
|
||||
|
||||
struct Device;
|
||||
namespace tt {
|
||||
|
||||
static const FileMutex lvgl_mutex = {
|
||||
.lock = lvgl_lock,
|
||||
.try_lock = lvgl_try_lock,
|
||||
.unlock = lvgl_unlock,
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds file systems with a device (e.g. sd card) that is owned by a SPI controller.
|
||||
* If the SPI controller has a display on the bus, we create an LVGL lock for the file system path.
|
||||
*/
|
||||
void initFileMutexForLvgl() {
|
||||
file_system_for_each(nullptr, [](FileSystem* fs, void* context) {
|
||||
char mount_path[64];
|
||||
if (file_system_get_path(fs, mount_path, sizeof(mount_path)) != ERROR_NONE) {
|
||||
return true;
|
||||
}
|
||||
LOG_D(TAG, "Mount path %s", mount_path);
|
||||
|
||||
// We only care about file system with a Device (owner)
|
||||
auto* owner = file_system_get_owner(fs);
|
||||
if (owner == nullptr) {
|
||||
LOG_D(TAG, "Owner: none");
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_D(TAG, "Owner: %s", owner->name);
|
||||
|
||||
// Ignore devices without a parent (root)
|
||||
auto* parent = device_get_parent(owner);
|
||||
if (parent == nullptr) {
|
||||
LOG_D(TAG, "Owner: no parent");
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_D(TAG, "Owner: parent %s", parent->name);
|
||||
|
||||
// If the FileSystem is on a SPI bus and there's more than 1 device, we assume the other one is the display.
|
||||
auto* type = device_get_type(parent);
|
||||
if (type != &SPI_CONTROLLER_TYPE || device_get_child_count(parent) <= 1) {
|
||||
LOG_D(TAG, "Owner parent not SPI controller or not enough children");
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Context {
|
||||
const char* mountPath;
|
||||
};
|
||||
Context ctx = { .mountPath = mount_path };
|
||||
|
||||
device_for_each_child(parent, &ctx, [](Device* child, void* context) -> bool {
|
||||
Context* ctx = static_cast<Context*>(context);
|
||||
if (device_get_type(child) == &DISPLAY_TYPE) {
|
||||
LOG_I(TAG, "Adding file mutex for %s as it shares a bus with a display", ctx->mountPath);
|
||||
file_mutex_register(
|
||||
&lvgl_mutex,
|
||||
ctx->mountPath
|
||||
);
|
||||
return false;
|
||||
} else {
|
||||
LOG_D(TAG, "child of parent, %s: not DISPLAY_TYPE", child->name);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user