R1 code for micro:bit based train controller code, requires second micro:bit running rx code to operate - see https://meanderingpi.wordpress.com/ for more information

Fork of nrf51-sdk by Lancaster University

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers app_scheduler.h Source File

app_scheduler.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) Nordic Semiconductor ASA
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without modification,
00006  * are permitted provided that the following conditions are met:
00007  *
00008  *   1. Redistributions of source code must retain the above copyright notice, this
00009  *   list of conditions and the following disclaimer.
00010  *
00011  *   2. Redistributions in binary form must reproduce the above copyright notice, this
00012  *   list of conditions and the following disclaimer in the documentation and/or
00013  *   other materials provided with the distribution.
00014  *
00015  *   3. Neither the name of Nordic Semiconductor ASA nor the names of other
00016  *   contributors to this software may be used to endorse or promote products
00017  *   derived from this software without specific prior written permission.
00018  *
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00021  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00022  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00023  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
00024  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00025  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00026  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00027  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00028  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  */
00032 
00033 /** @file
00034  *
00035  * @defgroup app_scheduler Scheduler
00036  * @{
00037  * @ingroup app_common
00038  *
00039  * @brief The scheduler is used for transferring execution from the interrupt context to the main
00040  *        context.
00041  *
00042  * @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
00043  *          when using the Scheduler.
00044  *
00045  * @section app_scheduler_req Requirements:
00046  *
00047  * @subsection main_context_logic Logic in main context:
00048  *
00049  *   - Define an event handler for each type of event expected.
00050  *   - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
00051  *     application main loop.
00052  *   - Call app_sched_execute() from the main loop each time the application wakes up because of an
00053  *     event (typically when sd_app_evt_wait() returns).
00054  *
00055  * @subsection int_context_logic Logic in interrupt context:
00056  *
00057  *   - In the interrupt handler, call app_sched_event_put()
00058  *     with the appropriate data and event handler. This will insert an event into the
00059  *     scheduler's queue. The app_sched_execute() function will pull this event and call its
00060  *     handler in the main context.
00061  *
00062  * @if (PERIPHERAL)
00063  * For an example usage of the scheduler, see the implementations of
00064  * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
00065  * @endif
00066  *
00067  * @image html scheduler_working.jpg The high level design of the scheduler
00068  */
00069 
00070 #ifndef APP_SCHEDULER_H__
00071 #define APP_SCHEDULER_H__
00072 
00073 #include <stdint.h>
00074 #include "app_error.h "
00075 #include "app_util.h "
00076 
00077 #define APP_SCHED_EVENT_HEADER_SIZE 8       /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
00078 
00079 /**@brief Compute number of bytes required to hold the scheduler buffer.
00080  *
00081  * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
00082  * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
00083  *                         that can be scheduled for execution).
00084  *
00085  * @return    Required scheduler buffer size (in bytes).
00086  */
00087 #define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE)                                                 \
00088             (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
00089             
00090 /**@brief Scheduler event handler type. */
00091 typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
00092 
00093 /**@brief Macro for initializing the event scheduler.
00094  *
00095  * @details It will also handle dimensioning and allocation of the memory buffer required by the
00096  *          scheduler, making sure the buffer is correctly aligned.
00097  *
00098  * @param[in] EVENT_SIZE   Maximum size of events to be passed through the scheduler.
00099  * @param[in] QUEUE_SIZE   Number of entries in scheduler queue (i.e. the maximum number of events
00100  *                         that can be scheduled for execution).
00101  *
00102  * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
00103  *       several times as long as it is from the same location, e.g. to do a reinitialization).
00104  */
00105 #define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE)                                                     \
00106     do                                                                                             \
00107     {                                                                                              \
00108         static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)),     \
00109                                                sizeof(uint32_t))];                                 \
00110         uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF);             \
00111         APP_ERROR_CHECK(ERR_CODE);                                                                 \
00112     } while (0)
00113 
00114 /**@brief Function for initializing the Scheduler.
00115  *
00116  * @details It must be called before entering the main loop.
00117  *
00118  * @param[in]   max_event_size   Maximum size of events to be passed through the scheduler.
00119  * @param[in]   queue_size       Number of entries in scheduler queue (i.e. the maximum number of
00120  *                               events that can be scheduled for execution).
00121  * @param[in]   p_evt_buffer   Pointer to memory buffer for holding the scheduler queue. It must
00122  *                               be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
00123  *                               must be aligned to a 4 byte boundary.
00124  *
00125  * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
00126  *       allocate the scheduler buffer, and also align the buffer correctly.
00127  *
00128  * @retval      NRF_SUCCESS               Successful initialization.
00129  * @retval      NRF_ERROR_INVALID_PARAM   Invalid parameter (buffer not aligned to a 4 byte
00130  *                                        boundary).
00131  */
00132 uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
00133 
00134 /**@brief Function for executing all scheduled events.
00135  *
00136  * @details This function must be called from within the main loop. It will execute all events
00137  *          scheduled since the last time it was called.
00138  */
00139 void app_sched_execute(void);
00140 
00141 /**@brief Function for scheduling an event.
00142  *
00143  * @details Puts an event into the event queue.
00144  *
00145  * @param[in]   p_event_data   Pointer to event data to be scheduled.
00146  * @param[in]   event_size   Size of event data to be scheduled.
00147  * @param[in]   handler        Event handler to receive the event.
00148  *
00149  * @return      NRF_SUCCESS on success, otherwise an error code.
00150  */
00151 uint32_t app_sched_event_put(void *                    p_event_data,
00152                              uint16_t                  event_size,
00153                              app_sched_event_handler_t handler);
00154 
00155 #ifdef APP_SCHEDULER_WITH_PAUSE
00156 /**@brief A function to pause the scheduler.
00157  *
00158  * @details When the scheduler is paused events are not pulled from the scheduler queue for
00159  *          processing. The function can be called multiple times. To unblock the scheduler the
00160  *          function @ref app_sched_resume has to be called the same number of times.
00161  */
00162 void app_sched_pause(void);
00163 
00164 /**@brief A function to resume a scheduler.
00165  *
00166  * @details To unblock the scheduler this function has to be called the same number of times as
00167  *          @ref app_sched_pause function.
00168  */
00169 void app_sched_resume(void);
00170 #endif
00171 #endif // APP_SCHEDULER_H__
00172 
00173 /** @} */