This commit is contained in:
Ken Van Hoeylandt 2026-01-24 00:29:42 +01:00
parent 46447f8f5a
commit ff8887d9b6
17 changed files with 39 additions and 36 deletions

View File

@ -20,8 +20,10 @@ jobs:
- name: "Build Tests" - name: "Build Tests"
run: cmake --build build --target build-tests run: cmake --build build --target build-tests
- name: "Run TactilityCore Tests" - name: "Run TactilityCore Tests"
run: build/Tests/TactilityCore/TactilityCoreTests --exit run: build/Tests/TactilityCore/TactilityCoreTests
- name: "Run TactilityFreeRtos Tests" - name: "Run TactilityFreeRtos Tests"
run: build/Tests/TactilityFreeRtos/TactilityFreeRtosTests --exit run: build/Tests/TactilityFreeRtos/TactilityFreeRtosTests
- name: "Run TactilityHeadless Tests" - name: "Run TactilityHeadless Tests"
run: build/Tests/Tactility/TactilityTests --exit run: build/Tests/Tactility/TactilityTests
- name: "Run TactilityKernel Tests"
run: build/Tests/TactilityKernel/TactilityKernelTests

View File

@ -5,7 +5,7 @@ from source.main import *
def print_help(): def print_help():
print("Usage: python compile.py [in_file] [out_path] [arguments]\n") print("Usage: python compile.py [in_file] [out_path] [arguments]\n")
print(f"\t[in_file] the .dts file") print(f"\t[in_path] the path where the root devicetree.yaml file is")
print(f"\t[out_path] output folder for C file output") print(f"\t[out_path] output folder for C file output")
print("") print("")
print("Optional arguments:\n") print("Optional arguments:\n")

View File

@ -13,7 +13,7 @@ from source.config import *
def main(config_path: str, output_path: str, verbose: bool): def main(config_path: str, output_path: str, verbose: bool):
print(f"Generating devicetree code\n config: {config_path}\n output: {output_path}") print(f"Generating devicetree code\n config: {config_path}\n output: {output_path}")
if not os.path.isdir(config_path): if not os.path.isdir(config_path):
raise Exception(f"Not found: {config_path}") raise Exception(f"Directory not found: {config_path}")
config = parse_config(config_path, os.getcwd()) config = parse_config(config_path, os.getcwd())
if verbose: if verbose:

View File

@ -1,4 +1,5 @@
dependencies: dependencies:
- Devices/lilygo-tlora-pager/Source/bindings
- Drivers/PlatformEsp32 - Drivers/PlatformEsp32
bindings: ./ bindings: ./
dts: lilygo,tlora_pager.dts dts: lilygo,tlora-pager.dts

View File

@ -36,11 +36,12 @@ static bool set_options(Device* device, gpio_pin_t pin, gpio_flags_t options) {
} else if (options & GPIO_DIRECTION_OUTPUT) { } else if (options & GPIO_DIRECTION_OUTPUT) {
mode = GPIO_MODE_OUTPUT; mode = GPIO_MODE_OUTPUT;
} else { } else {
assert(false); ESP_LOGE(TAG, "set_options: no direction flag specified for pin %d", pin);
return false;
} }
const gpio_config_t esp_config = { const gpio_config_t esp_config = {
.pin_bit_mask = 1UL << pin, .pin_bit_mask = 1ULL << pin,
.mode = mode, .mode = mode,
.pull_up_en = (options & GPIO_PULL_UP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pull_up_en = (options & GPIO_PULL_UP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE,
.pull_down_en = (options & GPIO_PULL_DOWN) ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE, .pull_down_en = (options & GPIO_PULL_DOWN) ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE,

View File

@ -38,7 +38,7 @@ struct Device {
struct Mutex mutex; struct Mutex mutex;
/** The device state */ /** The device state */
struct { struct {
uint8_t start_result; int start_result;
bool started : 1; bool started : 1;
bool added : 1; bool added : 1;
} state; } state;
@ -154,7 +154,7 @@ static inline void device_unlock(struct Device* device) {
} }
static inline const struct DeviceType* device_get_type(struct Device* device) { static inline const struct DeviceType* device_get_type(struct Device* device) {
return device->internal.driver->device_type; return device->internal.driver ? device->internal.driver->device_type : nullptr;
} }
/** /**
* Iterate through all the known devices * Iterate through all the known devices

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <Tactility/FreeRTOS/semphr.h>
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <Tactility/FreeRTOS/semphr.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdbool.h> #include <stdbool.h>
#include <assert.h>
#include <Tactility/FreeRTOS/semphr.h> #include <Tactility/FreeRTOS/semphr.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -37,22 +37,28 @@ static DeviceLedger& get_ledger() {
extern "C" { extern "C" {
#define ledger_lock() mutex_lock(&ledger.mutex); #define ledger_lock() mutex_lock(&ledger.mutex)
#define ledger_unlock() mutex_unlock(&ledger.mutex); #define ledger_unlock() mutex_unlock(&ledger.mutex)
#define get_device_data(device) static_cast<DeviceData*>(device->internal.data) #define get_device_data(device) static_cast<DeviceData*>(device->internal.data)
int device_construct(Device* device) { int device_construct(Device* device) {
LOG_I(TAG, "construct %s", device->name);
device->internal.data = new(std::nothrow) DeviceData; device->internal.data = new(std::nothrow) DeviceData;
if (device->internal.data == nullptr) { if (device->internal.data == nullptr) {
return ENOMEM; return ENOMEM;
} }
LOG_I(TAG, "construct %s", device->name);
mutex_construct(&device->internal.mutex); mutex_construct(&device->internal.mutex);
return 0; return 0;
} }
int device_destruct(Device* device) { int device_destruct(Device* device) {
if (device->internal.state.started || device->internal.state.added) {
return ERROR_INVALID_STATE;
}
if (!get_device_data(device)->children.empty()) {
return ERROR_INVALID_STATE;
}
LOG_I(TAG, "destruct %s", device->name); LOG_I(TAG, "destruct %s", device->name);
mutex_destruct(&device->internal.mutex); mutex_destruct(&device->internal.mutex);
delete get_device_data(device); delete get_device_data(device);
@ -189,7 +195,7 @@ void for_each_device(void* callback_context, bool(*on_device)(Device* device, vo
break; break;
} }
} }
ledger_unlock() ledger_unlock();
} }
void for_each_device_child(Device* device, void* callback_context, bool(*on_device)(struct Device* device, void* context)) { void for_each_device_child(Device* device, void* callback_context, bool(*on_device)(struct Device* device, void* context)) {
@ -213,7 +219,7 @@ void for_each_device_of_type(const DeviceType* type, void* callback_context, boo
} }
} }
} }
ledger_unlock() ledger_unlock();
} }
} // extern "C" } // extern "C"

View File

@ -69,6 +69,7 @@ static bool driver_remove(Driver* driver) {
const auto iterator = std::ranges::find(ledger.drivers, driver); const auto iterator = std::ranges::find(ledger.drivers, driver);
// check that there actually is a 3 in our vector // check that there actually is a 3 in our vector
if (iterator == ledger.drivers.end()) { if (iterator == ledger.drivers.end()) {
ledger.unlock();
return false; return false;
} }
ledger.drivers.erase(iterator); ledger.drivers.erase(iterator);

View File

@ -23,9 +23,7 @@ void test_task(void* parameter) {
data->result = context.run(); data->result = context.run();
if (context.shouldExit()) { // important - query flags (and --exit) rely on the user doing this vTaskEndScheduler();
vTaskEndScheduler();
}
vTaskDelete(nullptr); vTaskDelete(nullptr);
} }

View File

@ -23,9 +23,7 @@ void test_task(void* parameter) {
data->result = context.run(); data->result = context.run();
if (context.shouldExit()) { // important - query flags (and --exit) rely on the user doing this vTaskEndScheduler();
vTaskEndScheduler();
}
vTaskDelete(nullptr); vTaskDelete(nullptr);
} }

View File

@ -23,9 +23,7 @@ void test_task(void* parameter) {
data->result = context.run(); data->result = context.run();
if (context.shouldExit()) { // important - query flags (and --exit) rely on the user doing this vTaskEndScheduler();
vTaskEndScheduler();
}
vTaskDelete(nullptr); vTaskDelete(nullptr);
} }

View File

@ -146,14 +146,14 @@ TEST_CASE("device_remove should remove the device from its parent") {
TEST_CASE("device_remove should clear the state 'added'") { TEST_CASE("device_remove should clear the state 'added'") {
Device device = { 0 }; Device device = { 0 };
device_construct(&device); CHECK_EQ(device_construct(&device), 0);
device_add(&device); CHECK_EQ(device_add(&device), 0);
CHECK_EQ(device.internal.state.added, true); CHECK_EQ(device.internal.state.added, true);
device_remove(&device); CHECK_EQ(device_remove(&device), 0);
CHECK_EQ(device.internal.state.added, false); CHECK_EQ(device.internal.state.added, false);
device_destruct(&device); CHECK_EQ(device_destruct(&device), 0);
} }
TEST_CASE("device_is_ready should return true only when it is started") { TEST_CASE("device_is_ready should return true only when it is started") {
@ -177,8 +177,7 @@ TEST_CASE("device_is_ready should return true only when it is started") {
CHECK_EQ(device.internal.state.started, false); CHECK_EQ(device.internal.state.started, false);
CHECK_EQ(device_add(&device), 0); CHECK_EQ(device_add(&device), 0);
CHECK_EQ(device.internal.state.started, false); CHECK_EQ(device.internal.state.started, false);
int result = device_start(&device); CHECK_EQ(device_start(&device), 0);
CHECK_EQ(result, 0);
CHECK_EQ(device.internal.state.started, true); CHECK_EQ(device.internal.state.started, true);
CHECK_EQ(device_stop(&device), 0); CHECK_EQ(device_stop(&device), 0);
CHECK_EQ(device.internal.state.started, false); CHECK_EQ(device.internal.state.started, false);

View File

@ -13,7 +13,7 @@ TEST_CASE("driver_construct and driver_destruct should set and unset the correct
CHECK_EQ(driver.internal.data, nullptr); CHECK_EQ(driver.internal.data, nullptr);
} }
TEST_CASE("driver_is_comptable should return true if a compatible value is found") { TEST_CASE("driver_is_compatible should return true if a compatible value is found") {
Driver driver = { Driver driver = {
.name = "test_driver", .name = "test_driver",
.compatible = (const char*[]) { "test_compatible", nullptr }, .compatible = (const char*[]) { "test_compatible", nullptr },
@ -28,7 +28,7 @@ TEST_CASE("driver_is_comptable should return true if a compatible value is found
CHECK_EQ(driver_is_compatible(&driver, nullptr), false); CHECK_EQ(driver_is_compatible(&driver, nullptr), false);
} }
TEST_CASE("driver_is_comptable should return true if a compatible value is found") { TEST_CASE("driver_is_compatible should return true if a compatible value is found") {
Driver driver = { Driver driver = {
.name = "test_driver", .name = "test_driver",
.compatible = nullptr, .compatible = nullptr,

View File

@ -22,9 +22,7 @@ void test_task(void* parameter) {
data->result = context.run(); data->result = context.run();
if (context.shouldExit()) { // important - query flags (and --exit) rely on the user doing this vTaskEndScheduler();
vTaskEndScheduler();
}
vTaskDelete(nullptr); vTaskDelete(nullptr);
} }