Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
App Class Reference

#include <app.h>

+ Inheritance diagram for App:
+ Collaboration diagram for App:

Public Types

enum class  UserNotification : uint8_t { Heartbeat = 0 }
 

Public Member Functions

 App (int port)
 
void initRoutes () override
 Define the application's HTTP routes.
 
void onStart () override
 Called once at task start before entering the main loop.
 
void poll () override
 Called during every loop iteration for non-blocking background logic.
 
void onEvent (const Event &e) override
 Called when an event is dispatched to this controller.
 
- Public Member Functions inherited from FrameworkApp
 FrameworkApp (int port, const char *name="AppTask", uint16_t stackSize=2048, UBaseType_t priority=tskIDLE_PRIORITY+1)
 Constructor.
 
virtual ~FrameworkApp ()=default
 Virtual destructor.
 
virtual void start ()
 Initializes the application and its framework services.
 
void onStart () override
 Starts the Framework Manager.
 
- Public Member Functions inherited from FrameworkController
 FrameworkController (const char *name, Router &sharedRouter, uint16_t stackSize=1024, UBaseType_t priority=tskIDLE_PRIORITY+1)
 Constructor.
 
void run () override final
 Main task loop.
 
const char * getName () const
 Get the name of this controller.
 
void enableEventQueue (size_t depth=8)
 Enable the event queue for this controller.
 
QueueHandle_t getEventQueue () const
 Get the event queue for this controller.
 
bool getNextEvent (Event &event, uint32_t timeoutMs)
 Check if there are any pending events in the queue.
 
- Public Member Functions inherited from FrameworkTask
 FrameworkTask (const char *name, uint16_t stackSize=1024, UBaseType_t priority=1)
 Constructor.
 
virtual ~FrameworkTask ()
 Destructor.
 
bool start ()
 Starts the task via FreeRTOS.
 
void suspend ()
 Suspends the task using vTaskSuspend().
 
void resume ()
 Resumes the task using vTaskResume().
 
TaskHandle_t getHandle () const
 Returns the FreeRTOS task handle.
 
const char * getName () const
 Returns the task name.
 
void notify (uint8_t index, uint32_t value=1)
 Sends a notification to this task using an index.
 
void notify (Notification n, uint32_t value=1)
 Sends a notification using a framework-defined enum.
 
void notifyFromISR (uint8_t index, uint32_t value=1, BaseType_t *pxHigherPriorityTaskWoken=nullptr)
 Sends a notification from an ISR (by index).
 
void notifyFromISR (Notification n, uint32_t value=1, BaseType_t *pxHigherPriorityTaskWoken=nullptr)
 Sends a notification from ISR using enum identifier.
 
bool waitFor (uint8_t index, TickType_t timeout=portMAX_DELAY)
 Waits for a notification (by index).
 
bool waitFor (Notification n, TickType_t timeout=portMAX_DELAY)
 Waits for a notification (by enum identifier).
 
Notification waitForAny (uint8_t index, uint32_t mask, TickType_t timeout=portMAX_DELAY)
 waits for any notification matching the given mask.
 

Private Attributes

PicoModel pico
 

Additional Inherited Members

- Protected Member Functions inherited from FrameworkController
virtual TickType_t getPollIntervalTicks ()
 Returns the polling interval in ticks used in run().
 
void runEvery (uint32_t intervalMs, const std::function< void()> &fn, const char *id)
 Run a function periodically with millisecond resolution.
 
- Protected Member Functions inherited from FrameworkTask
uint32_t waitFor (TickType_t timeout=portMAX_DELAY)
 Wait for any notification (default index).
 
bool createQueue (size_t itemSize, size_t length)
 Creates an internal FreeRTOS queue.
 
bool sendToQueue (const void *item, TickType_t timeout=0)
 Sends an item to the internal queue.
 
bool receiveFromQueue (void *item, TickType_t timeout=portMAX_DELAY)
 Receives an item from the internal queue.
 
- Protected Attributes inherited from FrameworkApp
Router router
 Router instance for handling HTTP routes.
 
HttpServer server
 Embedded HTTP server instance.
 
FrameworkManager manager
 Responsible for launching system services and networking.
 
- Protected Attributes inherited from FrameworkController
Routerrouter
 Handles path-to-handler mapping - reference to shared Router instance.
 
- Protected Attributes inherited from FrameworkTask
const char * _name
 
uint16_t _stackSize
 
UBaseType_t _priority
 
TaskHandle_t _handle = nullptr
 
QueueHandle_t _queue = nullptr
 

Detailed Description

Definition at line 22 of file app.h.

Member Enumeration Documentation

◆ UserNotification

enum class App::UserNotification : uint8_t
strong
Enumerator
Heartbeat 

Definition at line 33 of file app.h.

33 : uint8_t { // user-defined notifications
34 Heartbeat = 0
35 };

Constructor & Destructor Documentation

◆ App()

App::App ( int  port)

Definition at line 27 of file app.cpp.

27 : FrameworkApp(port, "AppTask", 1024, 3)
28{
29
30
31}
Base class for applications using the framework.

Member Function Documentation

◆ initRoutes()

void App::initRoutes ( )
overridevirtual

You must implement this method in your subclass. Define your routes here using router.addRoute(...). This centralizes route logic and ensures all endpoints are registered before the server runs.

Example:

router.addRoute("GET", "/", [](HttpRequest& req, HttpResponse& res, const std::vector<std::string>&) {
res.send("Hello from root!");
});
Router router
Router instance for handling HTTP routes.
Forward declaration for potential routing needs.
Definition HttpRequest.h:32
Represents an HTTP response object.
void send(const std::string &body)
Send a full response including headers and body.
void addRoute(const std::string &method, const std::string &path, RouteHandler handler, std::vector< Middleware > middleware={})
Register a route with optional middleware.
Definition Router.cpp:144

Or bind member functions:

router.addRoute("GET", "/status",
std::bind(&MyApp::handleStatus, this, _1, _2, _3));

Reimplemented from FrameworkApp.

Definition at line 33 of file app.cpp.

34{
35 // This method is called by the base class to initialize HTTP routes.
36 // You can add your application's routes here.
37 // All FrameWorkController instances will have their initRoutes called
38 // when the application starts, so you can add routes in your controllers.
39 // See the GpioController and DashboardController classes for examples.
40 // Add a simple route for testing
41 router.addRoute("GET", "/", [](HttpRequest &req, HttpResponse &res, const auto &)
42 { res.send(DashboardView()); });
43 router.addRoute("GET", "/hello", [](HttpRequest &req, HttpResponse &res, const auto &)
44 { res.send("Welcome to PicoFramework!"); });
45 // Return the contents of the directory
46 router.addRoute("GET", "/ls(.*)", [](HttpRequest &req, HttpResponse &res, const auto &match) {
47 std::vector<FileInfo> files;
48 AppContext::get<StorageManager>()->listDirectory(match.ordered[0], files);
49 res.json(files);
50 });
51}
static constexpr std::uintptr_t getTypeKey()
Definition AppContext.h:91
HttpResponse & json(const std::string &jsonString)
Send a JSON string/object with correct content type.

References Router::addRoute(), AppContext::getTypeKey(), HttpResponse::json(), FrameworkApp::router, and HttpResponse::send().

+ Here is the call graph for this function:

◆ onEvent()

void App::onEvent ( const Event event)
overridevirtual

Called when an event is dispatched to this controller.

Override to implement your event-driven logic.

Override to implement your event-driven logic.

Reimplemented from FrameworkController.

Definition at line 108 of file app.cpp.

109{
110 // This method is called when an event is posted to the App's event queue.
111 // It is called by the FrameworkController base class when an event is received.
112 // You can handle different types of events here based on the notification kind.
113 // For example, you can handle GPIO change events or user-defined events.
114 // You subscribe for events in the onStart() method (for example), so this will be called
115 // when an event is posted to the App's event queue. The Eventmanager operates as a true
116 // publish-subscribe system, so you can post events from anywhere in the application
117 // and they will be delivered to ALL subscribers that have registered for that event type.
118
119 if (e.notification.kind == NotificationKind::System)
120 {
121 switch (e.notification.system)
122 {
124 {
125 printf("[App] GpioChange received\n");
126 printf("[App] Pin = %u, Edge = 0x%X\n", e.gpioEvent.pin, e.gpioEvent.edge);
127
128 const GpioEvent &data = e.gpioEvent;
129 printf("[App] GPIO changed - pin %u: %s\n",
130 data.pin,
131 (data.edge & GPIO_IRQ_EDGE_RISE) ? "rising" : (data.edge & GPIO_IRQ_EDGE_FALL) ? "falling" : "unknown");
132 break;
133 }
134
136 std::cout << "[App] Network ready. Starting services..." << std::endl;
137 pico.onNetworkReady(); // Notify the PicoModel that the network is ready
138 printf("[App] Network ready. Starting HTTP server...\n");
139 server.start();
140 break;
141
143 std::cout << "[App] Time is valid." << std::endl;
144 // at this point local time may equal UTC time or it may be the local time zone
145 // depending on whether the local timezone has been acquired (async)
146 // This example turns on that example, it is off by default
147 std::string localTime = AppContext::get<TimeManager>()->formatTimeWithZone();
148 printf("[App] UTC time: %s\n", localTime.c_str());
149 break;
150 }
151
153 // This event is sent when the local time zone has been acquired
154 // It will not occur if the DETECT_LOCAL_TIMEZONE flag is not set
155 // in framework_user_config.h
156 std::cout << "[App] Local Time is valid." << std::endl;
157 std::string localTime = AppContext::get<TimeManager>()->formatTimeWithZone();
158 printf("[App] Local time: %s\n", localTime.c_str());
159 break;
160 }
161
163 std::cout << "[App] SNTP Time Sync event." << std::endl;
164 // No need to do anything here, the time is valid - these occur every hour
165 // SNTP time sync events are sent every hour by default
166 // You can change the interval in framework_user_config.h
167 // by setting the SNTP_SYNC_INTERVAL to a different value
168 break;
169
171 std::cout << "[App] Time is invalid. Running in degraded mode." << std::endl;
172 // handle degraded state if needed
173 break;
174
175 default:
176 break;
177 }
178 }
179
180 if (e.notification.kind == NotificationKind::User &&
181 e.notification.user_code == static_cast<uint8_t>(UserNotification::Heartbeat))
182 {
183 printf("[App] Heartbeat user event received\n");
184 }
185}
PicoModel pico
Definition app.h:38
HttpServer server
Embedded HTTP server instance.
bool start()
Start the HTTP server as a FreeRTOS task.
void onNetworkReady()
Definition PicoModel.cpp:86
Structure representing a GPIO event.
Definition GpioEvent.h:11
uint16_t pin
Definition GpioEvent.h:12
uint16_t edge
Definition GpioEvent.h:13

References GpioEvent::edge, AppContext::getTypeKey(), GpioChange, Event::gpioEvent, Heartbeat, Notification::kind, LocalTimeValid, NetworkReady, Event::notification, PicoModel::onNetworkReady(), pico, GpioEvent::pin, FrameworkApp::server, HttpServer::start(), System, Notification::system, TimeInvalid, TimeSync, TimeValid, User, and Notification::user_code.

+ Here is the call graph for this function:

◆ onStart()

void App::onStart ( )
overridevirtual

Called once at task start before entering the main loop.

Override this to initialize controller state.

Override this to initialize controller state.

Reimplemented from FrameworkController.

Definition at line 53 of file app.cpp.

54{
55 // Call the base class to ensure the framework starts correctly.
57
58 pico.onStart(); // Initialize the PicoModel, which handles GPIO and other hardware interactions
59
60 // These are two controllers derived from FrameworkController that add event support to the FrameworkTask base class.
61 // They are started here to ensure they are ready to handle events and HTTP requests.
62 std::cout << "[App] Initializing application..." << std::endl;
63
64 static GpioController gpioController(router, pico);
65 gpioController.start();
66 static DashboardController dashboardController(router, pico);
67 dashboardController.start();
68
69 // Here we are setting up event handlers - we get the EventManager and GpioEventManager from the AppContext.
72
73 // Subscribe to GPIO change events
74 // This will call onEvent() in this App class when a GPIO change event occurs.
75 // Note: The GpioEventManager will call the gpio_event_handler() function when a GPIO interrupt occurs.
76 // The gpio_event_handler() will then post an Event to the EventManager, which posts to the FRameworkController event queue.
77 // FrameworkController has a waitAndDispatch function that polls the queue and will call onEvent() in this App class.
78 // Events can be SystemNotification or UserNotification types, which are defined in enum class UserNotification (see the App.h file).
80 gpioEventManager->enableInterrupt(16, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
81 gpioEventManager->enableInterrupt(17, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
82
84
85 std::cout << "[App] Waiting for network..." << std::endl;
86 // Wait for the network to be ready before starting services
87 // This is a blocking call that waits for the NetworkReady notification
88 // You could use a non-blocking wait if you want to do other work in the meantime
89 // waitfor is provided by the FrameworkTask base class and has a timeout parameter, unused here
90 // The underlying imlementation uses FreeRTOS notifications
91 //waitFor(SystemNotification::NetworkReady);
92
93 //std::cout << "[App] Network ready. Starting services..." << std::endl;
94 // Now that the network is ready, we can start services that depend on it
95 // For example, you might want to start an HTTP server or other network services here
96 //server.start();
97 eventManager->subscribe(
104 ),
105 this);
106}
constexpr uint32_t eventMask(Enum e)
Helper function to create an event mask from an enum value.
Manages the system-wide event queue and subscriptions.
void subscribe(uint32_t eventMask, FrameworkController *controller)
Subscribe a task to specific event types.
void onStart() override
Starts the Framework Manager.
@fileGpioController.cpp
GpioEventManager registers interrupts and posts GpioChange events to multiple listeners per pin.
void enableInterrupt(uint pin, uint32_t edgeMask)
Enable GPIO interrupts for a specific pin and edge mask.
void onStart()
Definition PicoModel.cpp:18

References GpioEventManager::enableInterrupt(), eventMask(), AppContext::getTypeKey(), GpioChange, Heartbeat, LocalTimeValid, NetworkReady, PicoModel::onStart(), FrameworkApp::onStart(), pico, FrameworkApp::router, FrameworkTask::start(), EventManager::subscribe(), TimeInvalid, TimeSync, and TimeValid.

+ Here is the call graph for this function:

◆ poll()

void App::poll ( )
overridevirtual

Called during every loop iteration for non-blocking background logic.

Runs after waitAndDispatch() — useful for polling sensors or internal FSMs.

Runs after waitAndDispatch() — useful for polling sensors or internal FSMs.

Reimplemented from FrameworkController.

Definition at line 188 of file app.cpp.

189{
190 static int count = 0;
191 if (count == 0) {
192 printf("[App] Starting main polling loop...\n");
193 }
194 count++;
195 vTaskDelay(pdMS_TO_TICKS(100)); // Yield to other tasks
196 // This function is called continuously (non-blocking) from the App task.
197 // Use RUN_EVERY to do periodic background work:
198
199 runEvery(15000, [&]()
200 {
201 printf("[App] Running main polling loop...\n");
202 Event userEvt(static_cast<uint8_t>(UserNotification::Heartbeat));
203 AppContext::get<EventManager>()->postEvent(userEvt);
204 // this yield is not essential, but without yielding you can miss events
205 vTaskDelay(pdMS_TO_TICKS(1)); }, "logLoop"); // <-- Unique ID for this timer (enables it to be cancelled)
206}
void runEvery(uint32_t intervalMs, const std::function< void()> &fn, const char *id)
Run a function periodically with millisecond resolution.
Represents a framework event, optionally carrying payload data.
Definition Event.h:24

References AppContext::getTypeKey(), Heartbeat, and FrameworkController::runEvery().

+ Here is the call graph for this function:

Member Data Documentation

◆ pico

PicoModel App::pico
private

Definition at line 38 of file app.h.

Referenced by onEvent(), and onStart().


The documentation for this class was generated from the following files: