Skip to content

Commit

Permalink
Added User Functions thread
Browse files Browse the repository at this point in the history
This thread handles a set of user functions. 
Those user functions can be either periodic (with a frequency of 1Hz, 10Hz, 20Hz, 50Hz, 100Hz or 1kHhz) or aperiodic (asynchronous). 
Periodic functions will be called periodically depending on their scheduling. Async functions need to be triggered usign user_functions_trigger(id).

The maximum amount of user functions that can be handled have to be defined in hwconfig.h using the macro CONFIG_USER_FUNCTIONS. If this macro is not defined, the user functions thread will not be created.
  • Loading branch information
mdiepart committed Feb 18, 2024
1 parent b71509e commit 98e83dd
Show file tree
Hide file tree
Showing 5 changed files with 419 additions and 0 deletions.
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ openrtx_src = ['openrtx/src/core/state.c',
'openrtx/src/core/voicePromptUtils.c',
'openrtx/src/core/voicePromptData.S',
'openrtx/src/core/nvmem_access.c',
'openrtx/src/core/user_functions.c',
'openrtx/src/rtx/rtx.cpp',
'openrtx/src/rtx/OpMode_FM.cpp',
'openrtx/src/rtx/OpMode_M17.cpp',
Expand Down
7 changes: 7 additions & 0 deletions openrtx/include/core/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,11 @@ void create_threads();
*/
#define CODEC2_TASK_STKSIZE 16384

/**
* Stack size for user functions task, in bytes
*/
#ifdef CONFIG_USER_FUNCTIONS
#define USER_FUNCTIONS_STKSIZE 512 + 128*CONFIG_USER_FUNCTIONS
#endif

#endif /* THREADS_H */
135 changes: 135 additions & 0 deletions openrtx/include/core/user_functions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/***************************************************************************
* Copyright (C) 2020 - 2024 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN, *
* Silvano Seva IU2KWO *
* Morgan Diepart ON4MOD *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/

#ifndef USER_FUNCTIONS_H
#define USER_FUNCTIONS_H

#include <hwconfig.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>

/**
* @file
* @brief Defines user functions. User functions will be called by a specific thread either periodically or when triggered.
*
* The user functions module will allow user to register functions to be called periodically or when triggered.
* User must first define the CONFIG_USER_FUNCTIONS macro with the number of user functions expected to be used
* in the code. In subsequent calls to user_functions_* functions the id to be provided is limited to CONFIG_USER_FUNCTIONS-1.
*/

#if defined(CONFIG_USER_FUNCTIONS) && (CONFIG_USER_FUNCTIONS > 0)

#ifdef __cplusplus
extern "C" {
#endif

/**
* @enum Defines the possible schedulings for user functions
*/
typedef enum {
USER_FUNCTION_ASYNC = 0, /**enum Functions will only be executed when triggered */
USER_FUNCTION_100HZ = 10, /**enum Function will be executed at a 100 Hz frequency */
USER_FUNCTION_50HZ = 20, /**enum Function will be executed at a 50 Hz frequency */
USER_FUNCTION_20HZ = 50, /**enum Function will be executed at a 20 Hz frequency */
USER_FUNCTION_10HZ = 100, /**enum Function will be executed at a 10 Hz frequency */
USER_FUNCTION_1HZ = 1000, /**enum Function will be executed at a 1 Hz frequency */
} user_functions_sched_t;

/**
* Initializes user_functions module.
*/
void user_functions_init();

/**
* Clean up and terminates the user_functions module.
*/
void user_functions_terminate();

/**
* Core function of the user_functions module. Must be called as the core of the user_functions thread.
*/
void user_functions_task();

/**
* Add a user function to the user_functions module.
* The function will be added and disabled by default.
*
* @param id: ID associated with the user function
* @param f: function to be called
* @param arg: void pointer that will be passed as argument when calling f
* @param scheduling: scheduling for the associated user function
*
* @return EINVAL if id is above the max id defined by CONFIG_USER_FUNCTIONS
* @return EADDRINUSE if id is already in use
* @return 0 if no error
*/
error_t user_functions_add(uint8_t id, void (*f)(), void *arg, user_functions_sched_t scheduling);

/**
* Unregisters a function from the user_functions module.
*
* @param id: ID associated with the user function to remove
*
* @return EINVAL if id is above the max id defined by CONFIG_USER_FUNCTIONS
* @return 0 if no error
*/
error_t user_functions_remove(uint8_t id);

/**
* Triggers an async user function to be executed
*
* @param id: ID of the function to trigger
*
* @return EINVAL if id is above the max id defined by CONFIG_USER_FUNCTIONS
* @return 0 if no error
*/
error_t user_functions_trigger(uint8_t id);

/**
* Enable a user function.
* A user function can not be executed unless it is enabled.
*
* @param id: ID of the function to enable
*
* @return EINVAL if id is above the max id defined by CONFIG_USER_FUNCTIONS
* @return 0 if no error
*/
error_t user_functions_enable(uint8_t id);

/**
* Disable a user function
* A disabled user function is not unregistered but won't be executed until it
* is enabled again.
*
* @param id: ID of the function to disable
*
* @return EINVAL if id is above the max id defined by CONFIG_USER_FUNCTIONS
* @return 0 if no error
*/
error_t user_functions_disable(uint8_t id);

#ifdef __cplusplus
}
#endif

#endif /* CONFIG_USER_FUNCTIONS */

#endif /* USER_FUNCTIONS_H */
38 changes: 38 additions & 0 deletions openrtx/src/core/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,27 @@ void *rtx_threadFunc(void *arg)
return NULL;
}

#ifdef CONFIG_USER_FUNCTIONS
/**
* \internal Thread for the user functions management.
*/
void *user_functions_threadFunc(void *arg)
{
(void) arg;

user_functions_init();

while(state.devStatus == RUNNING)
{
user_functions_task();
}

user_functions_terminate();

return NULL;
}
#endif

/**
* \internal This function creates all the system tasks and mutexes.
*/
Expand Down Expand Up @@ -234,4 +255,21 @@ void create_threads()

pthread_t ui_thread;
pthread_create(&ui_thread, &ui_attr, ui_threadFunc, NULL);

// Create user functions thread
#ifdef CONFIG_USER_FUNCTIONS
pthread_attr_t user_functions_attr;
pthread_attr_init(&user_functions_attr);

#ifndef __ZEPHYR__
pthread_attr_setstacksize(&user_functions_attr, USER_FUNCTIONS_STKSIZE);
#else
void *user_functions_thread_stack = malloc(USER_FUNCTIONS_STKSIZE * sizeof(uint8_t));
pthread_attr_setstack(&user_functions_attr, user_functions_thread_stack, USER_FUNCTIONS_STKSIZE);
#endif /* __ZEPHYR__ */

pthread_t user_functions_thread;
pthread_create(&user_functions_thread, &user_functions_attr, user_functions_threadFunc, NULL);

#endif /* CONFIG_USER_FUNCTIONS */
}
Loading

0 comments on commit 98e83dd

Please sign in to comment.