Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/backplane/sensor_module/src/c_sensor_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// F-Core Tenant
#include <f_core/messaging/c_msgq_message_port.h>
#include <f_core/os/n_rtos.h>
#include <f_core/os/tenants/c_timed_tenant.h> // TODO: Blast once we have CCpuMonitorTenant inherit this
#include <f_core/utils/n_time_utils.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(sensor_module);
Expand Down
20 changes: 20 additions & 0 deletions include/f_core/os/tenants/c_timed_tenant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef C_TIMED_TENANT_H
#define C_TIMED_TENANT_H

#include "f_core/os/c_tenant.h"
#include "f_core/utils/c_soft_timer.h"

class CTimedTenant : public CTenant {
public:
/**
* @brief Constructor
* @param name Name of the tenant
* @param intervalMillis Interval in milliseconds for the timeout
*/
explicit CTimedTenant(const char* name, const uint32_t intervalMillis);

private:
CSoftTimer timer;
};

#endif //C_TIMED_TENANT_H
15 changes: 13 additions & 2 deletions include/f_core/utils/c_soft_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ class CSoftTimer {
k_timer_init(&timer, expirationFn, stopFn);
}

/**
* Constructor
* @param timeoutMillis Time in milliseconds until the timer expires
* @param expirationFn Function to call when the timer expires
* @param stopFn Function to call when the timer is stopped
*/
CSoftTimer(const uint32_t timeoutMillis, k_timer_expiry_t expirationFn = nullptr, k_timer_stop_t stopFn = nullptr) {
k_timer_init(&timer, expirationFn, stopFn);
StartTimer(timeoutMillis);
}

/**
* Destructor
*/
Expand All @@ -24,7 +35,7 @@ class CSoftTimer {
* Start the timer with the given expiration time
* @param millis Time in milliseconds until the timer expires
*/
void StartTimer(int millis) {
void StartTimer(uint32_t millis) {
// Duration (second arg) is the initial expiration time
// Period (third arg) is the time set after each expiration
k_timer_start(&timer, K_MSEC(millis), K_MSEC(millis));
Expand Down Expand Up @@ -59,7 +70,7 @@ class CSoftTimer {
* @param millis Time in milliseconds until the timer expires
* @param initialExpirationMillis Time in milliseconds to wait before the first expiration
*/
void StartTimer(int millis, int initialExpirationMillis) {
void StartTimer(uint32_t millis, uint32_t initialExpirationMillis) {
// Duration (second arg) is the initial expiration time
// Period (third arg) is the time set after each expiration
k_timer_start(&timer, K_MSEC(initialExpirationMillis), K_MSEC(millis));
Expand Down
2 changes: 1 addition & 1 deletion lib/f_core/os/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
# SPDX-License-Identifier: Apache-2.0

zephyr_library()
FILE(GLOB sources *.cpp)
FILE(GLOB sources *.cpp tenants/*.cpp)
zephyr_library_sources(${sources})

20 changes: 20 additions & 0 deletions lib/f_core/os/tenants/c_timed_tenant.cpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From an abstraction point of view, does this deserve the name tenant?
Before now, tenants were things that were on tasks and managed by StartRTOS/StopRTOS
As far as I can tell, the timed 'tenant' is not run on a task nor is it started/stopped by Start/StopRTOS just by the constructor

Also, I believe the idea of the timer expiry function is that it is 'interrupt-esque' if not fully in an interrupt context
image
https://docs.zephyrproject.org/latest/kernel/services/timing/timers.html#using-a-timer-expiry-function

To me, Calling this a tenant and having the Run method on it disguises this limitation since all other Run's are not required to be interrupt safe.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk what the correct place to go from here is tbh,

  • Just documenting the limitation seems dangerous bc its really easy to not read documentatino and now our beautiful little abstraction isnt so conceptually solid bc some tenants arent tenatns
  • Idk the exact workings of this but if the timer just signalled to the task thats running the TimedTenant that would solve this, but, that kinda defeats the point of the timed scheduling that this was supposed to handle bc you're on a timer but still beholden to the loop on the task that runs its tenants and the delays between the runs

I think this needs a little more considering before it goes in

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair this was like a 15 minute thing to write

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "f_core/os/tenants/c_timed_tenant.h"

#include "f_core/os/n_rtos.h"
#include "zephyr/logging/log.h"

LOG_MODULE_REGISTER(CTimedTenant);

static void timerExpirationCallback(struct k_timer* timer) {
auto* tenant = static_cast<CTimedTenant*>(k_timer_user_data_get(timer));
if (tenant != nullptr) {
tenant->Run();
} else {
LOG_ERR("Timed tenant callback with null tenant");
}
}

CTimedTenant::CTimedTenant(const char* name, const uint32_t intervalMillis)
: CTenant(name), timer(intervalMillis, timerExpirationCallback, nullptr) {
timer.SetUserData(this);
}
Loading