Skip to content

Commit 527ca40

Browse files
committed
add pressure control task
1 parent cc86c2b commit 527ca40

File tree

11 files changed

+205
-2
lines changed

11 files changed

+205
-2
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
5+
#include "i2c_comms.hpp"
6+
#include "systemwide.h"
7+
8+
namespace control_policy {
9+
using namespace i2c::hardware;
10+
11+
class ControlPolicy {
12+
public:
13+
ControlPolicy(I2C *i2c) : i2c_comms{i2c} {}
14+
15+
template <size_t Len>
16+
auto i2c_write(uint8_t device_address, uint8_t register_address,
17+
std::array<uint8_t, Len> &data) -> bool {
18+
auto ret = i2c_comms->i2c_write(device_address, register_address,
19+
data.data(), Len);
20+
return ret == 0;
21+
}
22+
auto static sleep_ms(uint32_t ms) -> void;
23+
24+
private:
25+
I2C *i2c_comms;
26+
};
27+
} // namespace control_policy

stm32-modules/include/vacuum-module/firmware/firmware_tasks.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,7 @@ constexpr uint8_t SYSTEM_TASK_PRIORITY = 1;
2020

2121
constexpr size_t UI_STACK_SIZE = 256;
2222
constexpr uint8_t UI_TASK_PRIORITY = 1;
23+
24+
constexpr size_t CONTROL_STACK_SIZE = 256;
25+
constexpr uint8_t CONTROL_TASK_PRIORITY = 1;
2326
} // namespace tasks

stm32-modules/include/vacuum-module/firmware/freertos_tasks.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ namespace system_control_task {
2222
// Actual function that runs in the task
2323
auto run(tasks::FirmwareTasks::QueueAggregator* aggregator) -> void;
2424
} // namespace system_control_task
25+
26+
namespace pressure_control_task {
27+
// Actual function that runs in the task
28+
auto run(tasks::FirmwareTasks::QueueAggregator* aggregator,
29+
i2c::hardware::I2C* i2c_comms) -> void;
30+
} // namespace pressure_control_task
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#pragma once
2+
#include <cmath>
3+
#include <cstdint>
4+
5+
#include "core/ack_cache.hpp"
6+
#include "core/queue_aggregator.hpp"
7+
#include "core/version.hpp"
8+
#include "firmware/control_policy.hpp"
9+
#include "vacuum-module/errors.hpp"
10+
#include "vacuum-module/messages.hpp"
11+
#include "vacuum-module/tasks.hpp"
12+
#include "hal/message_queue.hpp"
13+
#include "messages.hpp"
14+
15+
namespace control_task {
16+
template <typename P>
17+
concept PressureControlPolicy = requires(P p) {
18+
{ p.sleep_ms(1) };
19+
};
20+
21+
using ControlPolicy = control_policy::ControlPolicy;
22+
using Message = messages::ControlMessage;
23+
using Error = errors::ErrorCode;
24+
25+
template <template <class> class QueueImpl>
26+
requires MessageQueue<QueueImpl<Message>, Message>
27+
class ControlTask {
28+
private:
29+
using Queue = QueueImpl<Message>;
30+
using Aggregator = typename tasks::Tasks<QueueImpl>::QueueAggregator;
31+
using Queues = typename tasks::Tasks<QueueImpl>;
32+
33+
public:
34+
explicit ControlTask(Queue& q, Aggregator* aggregator, ControlPolicy* policy)
35+
: _message_queue(q),
36+
_task_registry(aggregator) {}
37+
ControlTask(const ControlTask& other) = delete;
38+
auto operator=(const ControlTask& other) -> ControlTask& = delete;
39+
ControlTask(ControlTask&& other) noexcept = delete;
40+
auto operator=(ControlTask&& other) noexcept -> ControlTask& = delete;
41+
~ControlTask() = default;
42+
43+
auto provide_aggregator(Aggregator* aggregator) {
44+
_task_registry = aggregator;
45+
}
46+
47+
template <PressureControlPolicy Policy>
48+
auto run_once(Policy& policy) -> void {
49+
if (!_task_registry) {
50+
return;
51+
}
52+
53+
if (!_initialized) {
54+
_message_queue.set_ready();
55+
_initialized = true;
56+
}
57+
58+
auto message = Message(std::monostate());
59+
_message_queue.recv(&message);
60+
auto visit_helper = [this, &policy](auto& message) -> void {
61+
this->visit_message(message, policy);
62+
};
63+
std::visit(visit_helper, message);
64+
}
65+
66+
private:
67+
auto send_error_message(Error error) -> void {
68+
if (_task_registry) {
69+
auto msg = messages::ErrorMessage{.code = error};
70+
static_cast<void>(
71+
_task_registry->send_to_address(msg, Queues::HostCommsAddress));
72+
}
73+
}
74+
75+
auto send_ack_message(uint32_t response_id, Error error = Error::NO_ERROR)
76+
-> void {
77+
if (_task_registry) {
78+
auto msg = messages::AcknowledgePrevious{
79+
.responding_to_id = response_id, .with_error = error};
80+
static_cast<void>(
81+
_task_registry->send_to_address(msg, Queues::HostCommsAddress));
82+
}
83+
}
84+
85+
template <PressureControlPolicy Policy>
86+
auto visit_message(const std::monostate& m, Policy& policy) -> void {
87+
static_cast<void>(m);
88+
static_cast<void>(policy);
89+
}
90+
91+
Queue& _message_queue;
92+
Aggregator* _task_registry;
93+
bool _initialized{false};
94+
};
95+
96+
} // namespace control_task

stm32-modules/include/vacuum-module/vacuum-module/messages.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,6 @@ using SystemMessage =
122122

123123
using UIMessage = ::std::variant<std::monostate, SetStatusBarStateMessage>;
124124

125+
using ControlMessage = ::std::variant<std::monostate>;
126+
125127
}; // namespace messages

stm32-modules/include/vacuum-module/vacuum-module/tasks.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ struct Tasks {
1717
using SystemQueue = QueueImpl<messages::SystemMessage>;
1818
// Message queue for UI task
1919
using UIQueue = QueueImpl<messages::UIMessage>;
20+
// Message queue for Control task
21+
using ControlQueue = QueueImpl<messages::ControlMessage>;
2022

2123
// Central aggregator
2224
using QueueAggregator =
23-
queue_aggregator::QueueAggregator<HostCommsQueue, SystemQueue, UIQueue>;
25+
queue_aggregator::QueueAggregator<HostCommsQueue, SystemQueue, UIQueue, ControlQueue>;
2426

2527
// Addresses
2628
static constexpr size_t HostCommsAddress =
@@ -29,6 +31,8 @@ struct Tasks {
2931
QueueAggregator::template get_queue_idx<SystemQueue>();
3032
static constexpr size_t UIAddress =
3133
QueueAggregator::template get_queue_idx<UIQueue>();
34+
static constexpr size_t ControlAddress =
35+
QueueAggregator::template get_queue_idx<ControlQueue>();
3236
};
3337

3438
}; // namespace tasks

stm32-modules/vacuum-module/firmware/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ set(VENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vent")
1616
set(PUMP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/pump")
1717
set(ATMOSPHERE_PS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/atmosphere-pressure-sensor")
1818
set(VACUUM_PS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vacuum-pressure-sensor")
19+
set(CONTROL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/control_task")
1920

2021
# Add source files that should be checked by clang-tidy here
2122
set(${TARGET_MODULE_NAME}_FW_LINTABLE_SRCS
@@ -31,6 +32,8 @@ set(${TARGET_MODULE_NAME}_FW_LINTABLE_SRCS
3132
${PUMP_DIR}/pump_policy.cpp
3233
${ATMOSPHERE_PS_DIR}/atmosphere_pressure_sensor_policy.cpp
3334
${VACUUM_PS_DIR}/vacuum_pressure_sensor_policy.cpp
35+
${CONTROL_DIR}/freertos_control_task.cpp
36+
${CONTROL_DIR}/control_policy.cpp
3437
)
3538

3639
# Add source files that should NOT be checked by clang-tidy here
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include "firmware/control_policy.hpp"
2+
3+
#include <cstdint>
4+
5+
#include "FreeRTOS.h"
6+
#include "projdefs.h"
7+
#include "task.h"
8+
9+
using namespace control_policy;
10+
11+
12+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
13+
auto ControlPolicy::sleep_ms(uint32_t ms) -> void {
14+
vTaskDelay(pdMS_TO_TICKS(ms));
15+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include <cstdint>
2+
3+
#include "FreeRTOS.h"
4+
#include "firmware/firmware_tasks.hpp"
5+
#include "firmware/freertos_tasks.hpp"
6+
#include "firmware/i2c_comms.hpp"
7+
#include "firmware/control_policy.hpp"
8+
#include "vacuum-module/control_task.hpp"
9+
#include "task.h"
10+
11+
namespace pressure_control_task {
12+
using namespace control_policy;
13+
14+
enum class Notifications : uint8_t {
15+
INCOMING_MESSAGE = 1,
16+
};
17+
18+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
19+
static tasks::FirmwareTasks::ControlQueue
20+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
21+
_queue(static_cast<uint8_t>(Notifications::INCOMING_MESSAGE), "Control Queue");
22+
23+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
24+
static auto _top_task = control_task::ControlTask(_queue, nullptr, nullptr);
25+
26+
auto run(tasks::FirmwareTasks::QueueAggregator* aggregator,
27+
i2c::hardware::I2C* i2c1_comms) -> void {
28+
auto* handle = xTaskGetCurrentTaskHandle();
29+
_queue.provide_handle(handle);
30+
aggregator->register_queue(_queue);
31+
_top_task.provide_aggregator(aggregator);
32+
33+
auto policy = ControlPolicy(i2c1_comms);
34+
while (true) {
35+
_top_task.run_once(policy);
36+
}
37+
}
38+
39+
} // namespace control_task

stm32-modules/vacuum-module/firmware/main.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@
2121
using EntryPoint = std::function<void(tasks::FirmwareTasks::QueueAggregator *)>;
2222
using EntryPointUI = std::function<void(tasks::FirmwareTasks::QueueAggregator *,
2323
i2c::hardware::I2C *)>;
24+
using EntryPointControl = std::function<void(tasks::FirmwareTasks::QueueAggregator *,
25+
i2c::hardware::I2C *)>;
2426

2527
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2628
static auto ui_task_entry = EntryPointUI(ui_control_task::run);
2729
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
2830
static auto host_comms_entry = EntryPoint(host_comms_control_task::run);
2931
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
3032
static auto system_task_entry = EntryPoint(system_control_task::run);
33+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
34+
static auto control_task_entry = EntryPointControl(pressure_control_task::run);
3135

3236
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
3337
static auto host_comms_task =
@@ -41,6 +45,10 @@ static auto ui_task =
4145
static auto system_task =
4246
ot_utils::freertos_task::FreeRTOSTask<tasks::SYSTEM_STACK_SIZE, EntryPoint>(
4347
system_task_entry);
48+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
49+
static auto control_task =
50+
ot_utils::freertos_task::FreeRTOSTask<tasks::CONTROL_STACK_SIZE, EntryPointControl>(
51+
control_task_entry);
4452

4553
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
4654
static auto aggregator = tasks::FirmwareTasks::QueueAggregator();
@@ -65,6 +73,7 @@ auto main() -> int {
6573
system_task.start(tasks::SYSTEM_TASK_PRIORITY, "System", &aggregator);
6674
host_comms_task.start(tasks::COMMS_TASK_PRIORITY, "Comms", &aggregator);
6775
ui_task.start(tasks::UI_TASK_PRIORITY, "UI", &aggregator, &i2c2_comms);
76+
control_task.start(tasks::CONTROL_TASK_PRIORITY, "Control", &aggregator, &i2c2_comms);
6877

6978
vTaskStartScheduler();
7079
return 0;

0 commit comments

Comments
 (0)