UppSense17- Open Source sensor for chemical analysis based on fuoresence.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

35 lines
3.7 KiB

To make the previously discussed layering possible with communication, a small operating system has been developed with a minimum subset of functions. This subset is divided in two parts, Events and Modules.
\subsection{Module}
The modular system is realized by a struct. Every module contains a name, a usage counter, initialize and deinitialize functions, and dependencies. A module can be initialized by the "module\_init" function. This function will check for all the dependencies, whether they are already initialized. If this is not the case, it will be initialized including all the dependencies of the dependency. The "module\_init" function will also call the initialize function, which can be used for a module to set up registers for example. Once a module is not needed anymore, it can be deinitialized with the "module\_deinit" function. This function will decrease the usage counter for every dependency, and once a dependency is not used anymore it will also be deinitialized. This function also calls the deinitialize function of the given module.
\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C}
#define MODULE_DEFINE(VAR, DESC, INIT, DEINIT, ...) \
Module VAR = { \
.init = INIT, \
.deinit = DEINIT, \
.cnt = 0, \
.name = DESC, \
.deps = { __VA_ARGS__ } \
}
MODULE_DEFINE(CORE, "Central core", init, deinit, &TIME, &COMMAND, &ESP8266);
\end{minted}
In the code above a simplified usage example can be seen of this modular system
\subsection{Event}
For communication between modules an event based system has been realized. The developed system does not have any kind of priority for events, and events can be ignored if the event buffer is full because of a too heavy event. Every event contains a counter for debugging purposes, a pointer to data that can be given along with the event, and a description. An event can be created by use of the following code:
\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C}
#define EVENT_REGISTER(eventName, desc)\
Event eventName = \
{.eventId = __COUNTER__, .data = 0, .description = desc, .descLen = sizeof(desc) }
EVENT_REGISTER(EVENT_UART_DELIMITER, "Got UART delimiter");
\end{minted}
Events alone do not serve any purpose without listeners. Thus it's possible to register listeners in the event system. With the "event\_addListener" function a module can listen to a certain event and provide a function to be called upon the reception of such an event. This can be seen in the code below:
\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C}
event_addListener(&EVENT_UART_DELIMITER, callback);
\end{minted}
The listeners can be removed with the "event\_removeListener" function. The adding listeners is usually done in the initialization function, as the modules require these events during the period that they are active. In order to fire an event to all the listeners the following example can be used:
\begin{minted}[baselinestretch=1, fontsize=\small, linenos,frame=single,framesep=5pt]{C}
event_fire(&EVENT_UART_DELIMITER, SYSTEM_ADDRESS_CAST (&delimiters[USART_ID][i]));
\end{minted}
This line of code will fire a EVENT\_UART\_DELIMITER event, and adds some information to go with it.\newpar
In order for these events to be processed the "event\_process" has to be called. This should be the only function called in the infinite while loop of the system. A way to save energy is to pass functions to the event system if the system is capable of a sleeping functionality. Now the system will sleep whenever there are no more events to process, or wake up when an interrupt occurs.