diff options
Diffstat (limited to 'misc/regulator/regulator_example.c')
-rw-r--r-- | misc/regulator/regulator_example.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/misc/regulator/regulator_example.c b/misc/regulator/regulator_example.c new file mode 100644 index 0000000..51d0c27 --- /dev/null +++ b/misc/regulator/regulator_example.c @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @defgroup RegulatorExamples Regulator Use Examples + * + * @brief User Examples for the Regulator + * + * This is a set of user examples for the regulator. + */ + +/** + * @ingroup RegulatorExamples + * + * @file + * + * @brief Example 1 for Regulator Library + */ + +/* + * Copyright (C) 2022 On-Line Applications Research Corporation (OAR) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <rtems.h> +#include <rtems/inttypes.h> + +#include <rtems/regulator.h> + +/** + * @brief Regulator instance for example visible to entire file. + */ +static rtems_regulator_instance *regulator; + +/** + * @brief Count of Delivered Messages + */ +static int delivered = 1; + +/** + * @ingroup RegulatorExamples + * @brief Deliver Method Which Prints + * + * This deliverer method implementation prints the message with the + * receipt time. The following behavioral warnings should be noted + * as this is not necessarily representative of whata real application + * may do: + * + * - The printing may skew the delivery time. + * - The message must be in ASCII and NUL terminated. + */ +static bool example_deliverer( + void *context, + void *message, + size_t length +) +{ + (void) context; + (void) length; + + int rc; + struct timespec current; + + rc = clock_gettime(CLOCK_REALTIME, ¤t); + assert(rc == 0); + + fprintf( + stderr, + "%" PRIdtime_t ":%9ld %s\n", + current.tv_sec, + current.tv_nsec, + (char *)message + ); + delivered += 1; + + /* + * When we printed the message, we completed processing it. Because of this, + * the message buffer can now be released. We have the option of explicitly + * doing it here and returning false or telling the Delivery Thread to release + * the buffer by returning true. + */ + return true; +} + +/** + * @ingroup RegulatorTests + * @brief Verify rtems_regulator_send and output thread delivers message + * + * This example shows that when the regulator is successfully initialized + * and used as expected, a message sent via rtems_regulator_send() is delivered as + * expected. + */ +static void example_send_messages(void) +{ + #define MAXIMUM_MESSAGE_LENGTH 32 + + rtems_status_code sc; + char message[MAXIMUM_MESSAGE_LENGTH]; + void *buffer; + size_t length; + int msg; + int i; + int burst; + + rtems_regulator_attributes attributes = { + .deliverer = example_deliverer, + .deliverer_context = NULL, + .maximum_message_size = MAXIMUM_MESSAGE_LENGTH, + .maximum_messages = 10, + .output_thread_priority = 16, + .output_thread_stack_size = 0, + .output_thread_period = RTEMS_MILLISECONDS_TO_TICKS(1000), + .maximum_to_dequeue_per_period = 3 + }; + + sc = rtems_regulator_create(&attributes, ®ulator); + assert(sc == RTEMS_SUCCESSFUL); + assert(regulator != NULL); + + /** + * Send messages as a burst which will need to be smoothly sent at + * the configured rate. + */ + msg = 0; + for (burst=0 ; burst < 2 ; burst++ ) { + fprintf( + stderr, + "Sending Burst %d of 7 messages with 3 delivered per second\n", + burst + ); + for (i=1; i <= 7 ; i++, msg++) { + sc = rtems_regulator_obtain_buffer(regulator, &buffer); + assert(sc == RTEMS_SUCCESSFUL); + assert(buffer != NULL); + + length = snprintf(message, MAXIMUM_MESSAGE_LENGTH, "message %d", msg); + strcpy(buffer, message); + + sc = rtems_regulator_send(regulator, buffer, length); + assert(sc == RTEMS_SUCCESSFUL); + } + sleep(5); + } + + /* Will not exit above loop */ + #undef MAXIMUM_MESSAGE_LENGTH +} + +/* Necessary prototype */ +rtems_task test_regulator(rtems_task_argument); + +/** + * @ingroup RegulatorExamples + * @brief Entry task which invokes the example helper + */ +rtems_task test_regulator(rtems_task_argument arg) +{ + (void) arg; + + puts("*** START OF REGULATOR EXAMPLE 01 ***"); + + example_send_messages(); + + rtems_regulator_statistics stats; + rtems_status_code sc; + + sc = rtems_regulator_get_statistics(regulator, &stats); + assert(sc == RTEMS_SUCCESSFUL); + fprintf( + stderr, + "\n\n*** Regulator Statistics ***\n" + "obtained/released/delivered: %lld/%lld/%lld\n" + "periods count/missed: %lld/%lld\n", + (long long) stats.obtained, + (long long) stats.released, + (long long) stats.delivered, + (long long) stats.period_statistics.count, + (long long) stats.period_statistics.missed_count + ); + + puts("*** END OF EXAMPLE REGULATOR 01 ***"); + exit(0); +} |