]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blobdiff - rpp/src/rpp/fr.c
Make the RPP layer thread safe
[pes-rpp/rpp-lib.git] / rpp / src / rpp / fr.c
index 74390d8c9c9408efb0ba1e8e569d1a7a3d2ebeec..728ee8053facfc58673bfb975b5c1f92954d6274 100644 (file)
@@ -1,21 +1,13 @@
-/* Copyright (C) 2013 Czech Technical University in Prague
+/* Copyright (C) 2013, 2015 Czech Technical University in Prague
  *
  * Authors:
  *     - Carlos Jenkins <carlos@jenkins.co.cr>
  *     - Michal Horn <hornmich@fel.cvut.cz>
  *
- * 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 2 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/>.
+ * This document contains proprietary information belonging to Czech
+ * Technical University in Prague. Passing on and copying of this
+ * document, and communication of its contents is not permitted
+ * without prior written authorization.
  *
  * File : fr.c
  * Abstract:
 
 
 #include "rpp/rpp.h"
-#include "stdio.h"
-#include "string.h"
-
-#if rppCONFIG_INCLUDE_FR == 1
-
-#define RPP_FR_MAX_STATIC_BUF_CNT      32
-#define RPP_FR_MAX_DYNAMIC_BUF_CNT     32
-#define RPP_FR_MAX_FIFO_BUF_DEPTH      32
-
-#define RPP_FR_USER_CONFIG_NOT_DONE            0x0
-#define RPP_FR_USER_CONFIG_CLUSTER             0x1
-#define RPP_FR_USER_CONFIG_NODE                        0x2
-#define RPP_FR_USER_CONFIG_STATIC_BUF  0x4
-
-static rpp_fr_state_t rpp_fr_state = RPP_FR_NOT_INITIALIZED;   /**< Stores the actual state of the FlexRay module */
-static Fr_TMS570LS_ClusterConfigType rpp_fr_cluster_config;
-static Fr_TMS570LS_NodeConfigType rpp_fr_node_config;
-static Fr_TMS570LS_MsgRAMConfig rpp_fr_msg_ram_config;
-static Fr_TMS570LS_BufferConfigType rpp_fr_static_buffer_config[RPP_FR_MAX_STATIC_BUF_CNT];
-static Fr_TMS570LS_BufferConfigType rpp_fr_dynamic_buffer_config[RPP_FR_MAX_DYNAMIC_BUF_CNT];
-static Fr_TMS570LS_BufferConfigType rpp_fr_fifo_buffer_config[RPP_FR_MAX_FIFO_BUF_DEPTH];
-static Fr_ConfigType rpp_fr_configuration;
-static uint8_t rpp_fr_static_buffer_index;
-static uint8_t rpp_fr_dynamic_buffer_index;
-static uint8_t rpp_fr_fifo_buffer_depth = 0;
-static uint8_t rpp_fr_user_configuration_state = RPP_FR_USER_CONFIG_NOT_DONE;
-
-
-#define RPP_FR_MAX_PARAM_STR_LEN       256
-
-/**
- * Split string into numbers
- *
- * The function takes a string with hexadecimal numbers,
- * separated by spaces, and converts it into an array of numbers.
- *
- * For example "0x2 0xA 0XDD 0xABCD" -> {0x2, 0xA, 0XDD, 0xABCD}
- *
- * @param [in] params Address of the string which will be converted
- * @param [in] params_cnt A number of parameters, which should be found and converted from the string params
- * @param [out] tmp_params Address, where converted array of numbers will be stored
- *
- * @return SUCCESS when all parameters were converted to the array of numbers,
- *         FAILURE when the string was too short, too long or some other error occurred.
- */
-static int8_t rpp_fr_parse_params(const char* params, uint32_t params_cnt, uint32_t* tmp_params) {
-       char cpy_params[RPP_FR_MAX_PARAM_STR_LEN];
-       char* token;
-       int i;
-
-       if (params == NULL || tmp_params == NULL) {
-               return FAILURE;
-       }
-       strncpy(cpy_params, params, RPP_FR_MAX_PARAM_STR_LEN);
-       token = strtok(cpy_params, " ");
-       if (token == NULL) {
-               return FAILURE;
-       }
-       for (i = 0; i < params_cnt; i++) {
-               if (sscanf(token, "%x", &tmp_params[i]) == EOF) {       // No number found
-                       return FAILURE;
-               }
-               if ((token = strtok(NULL, " ")) == NULL && i < params_cnt-1) {  // Not enough parameters in the string
-                       return FAILURE;
-               }
-       }
-       return SUCCESS;
-}
-
-int8_t rpp_fr_config_cluster_params(const char* params) {
-       uint32_t tmp_params[FR_CLUSTER_PARAMS_CNT];
-
-       if (rpp_fr_parse_params(params, FR_CLUSTER_PARAMS_CNT, tmp_params) == FAILURE) {
-               return FAILURE;
-       }
-
-       rpp_fr_cluster_config.gColdStartAttempts = tmp_params[0];
-       rpp_fr_cluster_config.gListenNoise = tmp_params[1];
-       rpp_fr_cluster_config.gMacroPerCycle = tmp_params[2];
-       rpp_fr_cluster_config.gMaxWithoutClockCorrectionFatal = tmp_params[3];
-       rpp_fr_cluster_config.gMaxWithoutClockCorrectionPassive = tmp_params[4];
-       rpp_fr_cluster_config.gNetworkManagementVectorLength = tmp_params[5];
-       rpp_fr_cluster_config.gNumberOfMinislots = tmp_params[6];
-       rpp_fr_cluster_config.gNumberOfStaticSlots = tmp_params[7];
-       rpp_fr_cluster_config.gOffsetCorrectionStart = tmp_params[8];
-       rpp_fr_cluster_config.gPayloadLengthStatic = tmp_params[9];
-       rpp_fr_cluster_config.gSyncNodeMax = tmp_params[10];
-       rpp_fr_cluster_config.gdActionPointOffset = tmp_params[11];
-       rpp_fr_cluster_config.gdCASRxLowMax = tmp_params[12];
-       rpp_fr_cluster_config.gdDynamicSlotIdlePhase = tmp_params[13];
-       rpp_fr_cluster_config.gdMinislot = tmp_params[14];
-       rpp_fr_cluster_config.gdMinislotActionPointOffset = tmp_params[15];
-       rpp_fr_cluster_config.gdNIT = tmp_params[16];
-       rpp_fr_cluster_config.gdSampleClockPeriod = tmp_params[17];
-       rpp_fr_cluster_config.gdStaticSlot = tmp_params[18];
-       rpp_fr_cluster_config.gdTSSTransmitter = tmp_params[19];
-       rpp_fr_cluster_config.gdWakeupSymbolRxIdle = tmp_params[20];
-       rpp_fr_cluster_config.gdWakeupSymbolRxLow = tmp_params[21];
-       rpp_fr_cluster_config.gdWakeupSymbolRxWindow = tmp_params[22];
-       rpp_fr_cluster_config.gdWakeupSymbolTxIdle = tmp_params[23];
-       rpp_fr_cluster_config.gdWakeupSymbolTxLow = tmp_params[24];
-
-       rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_CLUSTER;
-       return SUCCESS;
-}
-
-int8_t rpp_fr_config_node_params(const char* params) {
-       uint32_t tmp_params[FR_NODE_PARAMS_CNT+2];      // +2 because two more parameters from message RAM structure are expected in the string.
-       Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
-       Fr_TMS570LS_SecureBuffersType secure[4] = {FR_SB_RECONFIG_ENABLED, FR_SB_STAT_REC_DISABLED_STAT_TR_DISABLED, FR_SB_ALL_REC_DISABLED, FR_SB_ALL_REC_DISABLED_STAT_TR_DISABLED};
-
-       if (rpp_fr_parse_params(params, FR_NODE_PARAMS_CNT+2, tmp_params) == FAILURE) {
-               return FAILURE;
-       }
-
-       rpp_fr_node_config.pAllowHaltDueToClock = tmp_params[0];
-       rpp_fr_node_config.pAllowPassiveToActive = tmp_params[1];
-       if (tmp_params[2] > 2) return FAILURE;
-       rpp_fr_node_config.pChannels = channels[ tmp_params[2] ];
-       rpp_fr_node_config.pClusterDriftDamping = tmp_params[3];
-       rpp_fr_node_config.pDelayCompensationA = tmp_params[4];
-       rpp_fr_node_config.pDelayCompensationB = tmp_params[5];
-       rpp_fr_node_config.pExternOffsetCorrection = tmp_params[6];
-       rpp_fr_node_config.pExternRateCorrection = tmp_params[7];
-       rpp_fr_node_config.pKeySlotUsedForStartup = tmp_params[8];
-       rpp_fr_node_config.pKeySlotUsedForSync = tmp_params[9];
-       rpp_fr_node_config.pLatestTx = tmp_params[10];
-       rpp_fr_node_config.pMacroInitialOffsetA = tmp_params[11];
-       rpp_fr_node_config.pMacroInitialOffsetB = tmp_params[12];
-       rpp_fr_node_config.pMicroInitialOffsetA = tmp_params[13];
-       rpp_fr_node_config.pMicroInitialOffsetB = tmp_params[14];
-       rpp_fr_node_config.pMicroPerCycle = tmp_params[15];
-       rpp_fr_node_config.pRateCorrectionOut = tmp_params[16];
-       rpp_fr_node_config.pOffsetCorrectionOut = tmp_params[17];
-       rpp_fr_node_config.pSamplesPerMicrotick = tmp_params[18];
-       rpp_fr_node_config.pSingleSlotEnabled = tmp_params[19];
-       if (tmp_params[20] > 1) return FAILURE;
-       rpp_fr_node_config.pWakeupChannel = channels[ tmp_params[20] ];
-       rpp_fr_node_config.pWakeupPattern = tmp_params[21];
-       rpp_fr_node_config.pdAcceptedStartupRange = tmp_params[22];
-       rpp_fr_node_config.pdListenTimeout = tmp_params[23];
-       rpp_fr_node_config.pdMaxDrift = tmp_params[24];
-       rpp_fr_node_config.pDecodingCorrection = tmp_params[25];
-       rpp_fr_msg_ram_config.syncFramePayloadMultiplexEnabled = tmp_params[26];
-       if (tmp_params[27] > 3) return FAILURE;
-       rpp_fr_msg_ram_config.secureBuffers = secure[ tmp_params[27] ];
-
-       rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_NODE;
-       return SUCCESS;
-}
 
-int8_t rpp_fr_config_static_buffer(const char* params) {
-       uint32_t tmp_params[FR_STATIC_BUF_PARAMS_CNT];
-       Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+#ifndef FREERTOS_POSIX
 
-       if (rpp_fr_static_buffer_index >= RPP_FR_MAX_STATIC_BUF_CNT) {
-               return FAILURE;
-       }
+#include "stdio.h"
+#include "string.h"
+#include "drv/drv.h"
+#include "drv/spi_tms570.h"
+#include "rpp/mutex.h"
 
-       if (rpp_fr_parse_params(params, FR_STATIC_BUF_PARAMS_CNT, tmp_params) == FAILURE) {
-               return FAILURE;
-       }
+RPP_MUTEX_DEFINE(mutex_fr);
 
-       if (tmp_params[0] > 2) return FAILURE;
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].channel =  channels[ tmp_params[0] ];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].cycleCounterFiltering = tmp_params[1];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].isTx = tmp_params[2];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].maxPayload = tmp_params[3];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].msgBufferInterrupt = tmp_params[4];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].payloadPreambleIndicatorTr = tmp_params[5];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].singleTransmit = tmp_params[6];
-       rpp_fr_static_buffer_config[rpp_fr_static_buffer_index].slotId = tmp_params[7];
-       rpp_fr_static_buffer_index++;
-
-       rpp_fr_user_configuration_state |= RPP_FR_USER_CONFIG_STATIC_BUF;
-       return SUCCESS;
-}
+static rpp_fr_state_t rpp_fr_state = RPP_FR_NOT_INITIALIZED;    /**< Stores the actual state of the FlexRay module */
 
-int8_t rpp_fr_config_dynamic_buffer(const char* params) {
-       uint32_t tmp_params[FR_DYNAMIC_BUF_PARAMS_CNT];
-       Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
+/* AUTOSAR-like API */
 
-       if (rpp_fr_dynamic_buffer_index >= RPP_FR_MAX_DYNAMIC_BUF_CNT) {
+int8_t rpp_fr_init_driver(const Fr_ConfigType *config_ptr, uint32_t *error)
+{
+       if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED)
                return FAILURE;
-       }
-
-       if (rpp_fr_parse_params(params, FR_DYNAMIC_BUF_PARAMS_CNT, tmp_params) == FAILURE) {
+#ifndef FREERTOS_POSIX
+       spi_tms570_init();
+#endif
+       if (!RPP_MUTEX_INIT(mutex_fr))
                return FAILURE;
-       }
-
-       if (tmp_params[0] > 1) return FAILURE;
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].channel =  channels[ tmp_params[0] ];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].cycleCounterFiltering = tmp_params[1];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].isTx = tmp_params[2];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].maxPayload = tmp_params[3];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].msgBufferInterrupt = tmp_params[4];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].singleTransmit = tmp_params[5];
-       rpp_fr_dynamic_buffer_config[rpp_fr_dynamic_buffer_index].slotId = tmp_params[6];
-       rpp_fr_dynamic_buffer_index++;
-
+       Fr_Init(config_ptr);
+       rpp_fr_state = RPP_FR_DRV_INITIALIZED;
        return SUCCESS;
 }
 
-int8_t rpp_fr_config_fifo_buffer(const char* params) {
-       uint32_t tmp_params[FR_FIFO_BUF_PARAMS_CNT+1];  // +1 because the first parameter in the string means the depth of the buffer, and the constant means the number of items in the configuration structure.
-       Fr_ChannelType channels[3] = {FR_CHANNEL_A, FR_CHANNEL_B, FR_CHANNEL_AB};
-       Fr_TMS570LS_BufferConfigType* fifo_buffer_ptr = &rpp_fr_fifo_buffer_config[0];
-
-       if (rpp_fr_fifo_buffer_depth != 0) {
-               return FAILURE;
-       }
-
-       if (rpp_fr_parse_params(params, FR_FIFO_BUF_PARAMS_CNT+1, tmp_params) == FAILURE) {
-               return FAILURE;
-       }
-
-       if (tmp_params[0] > RPP_FR_MAX_FIFO_BUF_DEPTH) return FAILURE;
-       if (tmp_params[1] > 2) return FAILURE;
-
-       for (fifo_buffer_ptr = &rpp_fr_fifo_buffer_config[0]; fifo_buffer_ptr < &rpp_fr_fifo_buffer_config[tmp_params[0]]; fifo_buffer_ptr++) {
-               fifo_buffer_ptr->channel = channels[ tmp_params[1] ];
-               fifo_buffer_ptr->cycleCounterFiltering = tmp_params[2];
-               fifo_buffer_ptr->maxPayload = tmp_params[3];
-               fifo_buffer_ptr->rejectNullFrames = tmp_params[4];
-               fifo_buffer_ptr->rejectStaticSegment = tmp_params[5];
-               fifo_buffer_ptr->slotId = tmp_params[6];
-       }
-       rpp_fr_fifo_buffer_depth = tmp_params[0];
-
-       return SUCCESS;
-}
-
-/* AUTOSAR-like API */
-
-int8_t rpp_fr_init_driver(const Fr_ConfigType* config_ptr, uint32_t* error) {
-       if (rpp_fr_state <= RPP_FR_DRV_INITIALIZED) {
-               if (config_ptr == NULL) {       // Use user configuration created before by rpp_fr_config functions
-                       if (rpp_fr_user_configuration_state !=
-                                       (RPP_FR_USER_CONFIG_CLUSTER|
-                                       RPP_FR_USER_CONFIG_NODE|
-                                       RPP_FR_USER_CONFIG_STATIC_BUF)
-                               ) {
-                               *error = FR_INIT_ERR_BAD_PARAM;
-                               return FAILURE; // User configuration was not completed
-                       }
-                       rpp_fr_msg_ram_config.dynSegmentBufferCount = rpp_fr_dynamic_buffer_index;
-                       rpp_fr_msg_ram_config.fifoBufferCount = rpp_fr_fifo_buffer_depth;
-                       rpp_fr_msg_ram_config.statSegmentBufferCount = rpp_fr_static_buffer_index;
-
-                       rpp_fr_configuration.clusterConfiguration = &rpp_fr_cluster_config;
-                       rpp_fr_configuration.dynamicBufferConfigs = rpp_fr_dynamic_buffer_config;
-                       rpp_fr_configuration.fifoBufferConfigs = rpp_fr_fifo_buffer_config;
-                       rpp_fr_configuration.msgRAMConfig = &rpp_fr_msg_ram_config;
-                       rpp_fr_configuration.nodeConfiguration = &rpp_fr_node_config;
-                       rpp_fr_configuration.staticBufferConfigs = rpp_fr_static_buffer_config;
-                       Fr_Init(&rpp_fr_configuration);
-               }
-               else {  // Use configuration from the structure from parameter.
-                       Fr_Init(config_ptr);
-               }
-               rpp_fr_state = RPP_FR_DRV_INITIALIZED;
-               return SUCCESS;
-       }
-       return FAILURE;
-}
-
-int8_t rpp_fr_init_controller(uint8_t ctrl, uint32_t* error) {
+int8_t rpp_fr_init_controller(uint8_t ctrl, uint32_t *error)
+{
        Std_ReturnType retVal = ERR_PARAM_NO_ERROR;
-       if (rpp_fr_state == RPP_FR_DRV_INITIALIZED) {
+       RPP_MUTEX_LOCK(mutex_fr);
+       if (rpp_fr_state == RPP_FR_DRV_INITIALIZED ||
+               rpp_fr_state == RPP_FR_HALTED ||
+               rpp_fr_state == RPP_FR_ABORTED) {
                retVal = Fr_ControllerInit(ctrl);
                if (retVal & E_OK) {
                        rpp_fr_state = RPP_FR_CTR_INITIALIZED;
+                       RPP_MUTEX_UNLOCK(mutex_fr);
                        return SUCCESS;
                }
                else {
                        *error = retVal;
+                       RPP_MUTEX_UNLOCK(mutex_fr);
                        return FAILURE;
                }
        }
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_start_communication(uint8_t ctrl, uint32_t* error) {
+int8_t rpp_fr_start_communication(uint8_t ctrl, uint32_t *error)
+{
        Std_ReturnType retVal = ERR_PARAM_NO_ERROR;
+
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_CTR_INITIALIZED) {
                retVal = Fr_StartCommunication(ctrl);
                if (retVal & E_OK) {
                        rpp_fr_state = RPP_FR_RUNNING;
+                       RPP_MUTEX_UNLOCK(mutex_fr);
                        return SUCCESS;
+
                }
                else {
                        *error = retVal;
+                       RPP_MUTEX_UNLOCK(mutex_fr);
                        return FAILURE;
                }
        }
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_all_slots(uint8_t ctrl) {
-       if (rpp_fr_state == RPP_FR_RUNNING && Fr_AllSlots(ctrl) & E_OK) {
-               return SUCCESS;
-       }
-       return FAILURE;
+int8_t rpp_fr_all_slots(uint8_t ctrl)
+{
+       int8_t ret;
+
+       RPP_MUTEX_LOCK(mutex_fr);
+       ret = (rpp_fr_state == RPP_FR_RUNNING && Fr_AllSlots(ctrl) & E_OK);
+       RPP_MUTEX_UNLOCK(mutex_fr);
+
+       return ret ? SUCCESS : FAILURE;
 }
 
-int8_t rpp_fr_halt_communication(uint8_t ctrl) {
+int8_t rpp_fr_halt_communication(uint8_t ctrl)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_HaltCommunication(ctrl) & E_OK) {
                rpp_fr_state = RPP_FR_HALTED;
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
+
        }
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_abort_communication(uint8_t ctrl) {
+int8_t rpp_fr_abort_communication(uint8_t ctrl)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_AbortCommunication(ctrl) & E_OK) {
                rpp_fr_state = RPP_FR_ABORTED;
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
+
        }
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_send_wup(uint8_t ctrl) {
+int8_t rpp_fr_send_wup(uint8_t ctrl)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_CTR_INITIALIZED && Fr_SendWUP(ctrl) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_set_wu_channel(uint8_t ctrl, Fr_ChannelType channel) {
+int8_t rpp_fr_set_wu_channel(uint8_t ctrl, Fr_ChannelType channel)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_CTR_INITIALIZED && Fr_SetWakeupChannel(ctrl, channel) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_get_poc_status(uint8_t ctrl, Fr_POCStatusType* poc_status_ptr) {
+int8_t rpp_fr_get_poc_status(uint8_t ctrl, Fr_POCStatusType *poc_status_ptr)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED && Fr_GetPOCStatus(ctrl, poc_status_ptr) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
 }
 
-int8_t rpp_fr_transmit_lpdu(uint8_t ctrl, uint16_t lpdu_idx, const uint8_t* lsdu, uint8_t lsdu_length) {
+int8_t rpp_fr_transmit_lpdu(uint8_t ctrl, uint16_t lpdu_idx, const uint8_t *lsdu, uint8_t lsdu_length)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_TransmitTxLPdu(ctrl, lpdu_idx, lsdu, lsdu_length) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
+
        }
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_cancel_transmit_lpdu(uint8_t ctrl, uint16_t lpdu_idx) {
+int8_t rpp_fr_cancel_transmit_lpdu(uint8_t ctrl, uint16_t lpdu_idx)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_CancelTxLPdu(ctrl, lpdu_idx) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_receive_lpdu(uint8_t ctrl, uint16_t lpdu_idx, uint8_t* lsdu, Fr_RxLPduStatusType* lpdu_status, uint8_t* lsdu_length) {
+int8_t rpp_fr_receive_lpdu(uint8_t ctrl, uint16_t lpdu_idx, uint8_t *lsdu, Fr_RxLPduStatusType *lpdu_status, uint8_t *lsdu_length)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_ReceiveRxLPdu(ctrl, lpdu_idx, lsdu, lpdu_status, lsdu_length) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_check_tx_lpdu_status(uint8_t ctrl, uint16_t lpdu_idx, Fr_TxLPduStatusType* lpdu_status) {
+int8_t rpp_fr_check_tx_lpdu_status(uint8_t ctrl, uint16_t lpdu_idx, Fr_TxLPduStatusType *lpdu_status)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_CheckTxLPduStatus(ctrl, lpdu_idx, lpdu_status) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_disable_lpdu(uint8_t ctrl, uint16_t lpdu_idx) {
+int8_t rpp_fr_reconfigure_lpdu(uint8_t ctrl, uint16_t lpdu_idx, uint16_t frame_id, Fr_ChannelType channel, uint8_t cycle_set, uint8_t cycle_offset, uint8_t payload, uint16_t header_crc)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
+       if (rpp_fr_state >= RPP_FR_CTR_INITIALIZED && Fr_ReconfigLPdu(ctrl, lpdu_idx, frame_id, channel, cycle_set, cycle_offset, payload, header_crc) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
+               return SUCCESS;
+       }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
+       return FAILURE;
+
+}
+
+int8_t rpp_fr_disable_lpdu(uint8_t ctrl, uint16_t lpdu_idx)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_DisableLPdu(ctrl, lpdu_idx) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_global_time(uint8_t ctrl, uint8_t* cycle, uint16_t* macroticks) {
+int8_t rpp_fr_get_global_time(uint8_t ctrl, uint8_t *cycle, uint16_t *macroticks)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_CTR_INITIALIZED && Fr_GetGlobalTime(ctrl, cycle, macroticks) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_network_management_vector(uint8_t ctrl, uint8_t* nm_vector) {
+int8_t rpp_fr_get_network_management_vector(uint8_t ctrl, uint8_t *nm_vector)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_CTR_INITIALIZED && Fr_GetNmVector(ctrl, nm_vector) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_channel_status(uint8_t ctrl, uint16_t* channel_a_status, uint16_t* channel_b_status) {
+int8_t rpp_fr_get_channel_status(uint8_t ctrl, uint16_t *channel_a_status, uint16_t *channel_b_status)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_CTR_INITIALIZED && Fr_GetChannelStatus(ctrl, channel_a_status, channel_b_status) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_clock_correction(uint8_t ctrl, int16_t* rate_correction, int32_t* offset_correction) {
+int8_t rpp_fr_get_clock_correction(uint8_t ctrl, int16_t *rate_correction, int32_t *offset_correction)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_RUNNING && Fr_GetClockCorrection(ctrl, rate_correction, offset_correction) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_sync_frame_list(uint8_t ctrl, uint8_t list_size, uint16_t* channel_a_even_list, uint16_t* channel_b_even_list, uint16_t* channel_a_odd_list, uint16_t* channel_b_odd_list) {
+int8_t rpp_fr_get_sync_frame_list(uint8_t ctrl, uint8_t list_size, uint16_t *channel_a_even_list, uint16_t *channel_b_even_list, uint16_t *channel_a_odd_list, uint16_t *channel_b_odd_list)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_RUNNING && Fr_GetSyncFrameList(ctrl, list_size, channel_a_even_list, channel_b_even_list, channel_a_odd_list, channel_b_odd_list) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_wakeup_rx_status(uint8_t ctrl, uint8_t* status) {
+int8_t rpp_fr_get_wakeup_rx_status(uint8_t ctrl, uint8_t *status)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED && Fr_GetWakeupRxStatus(ctrl, status) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_set_timer(uint8_t ctrl, uint8_t timer_idx, uint8_t cycle_set, uint16_t offset_threshold) {
+int8_t rpp_fr_set_timer(uint8_t ctrl, uint8_t timer_idx, uint8_t cycle_set, uint16_t offset_threshold)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_SetAbsoluteTimer(ctrl, timer_idx, cycle_set, offset_threshold) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_cancel_timer(uint8_t ctrl, uint8_t timer_idx) {
+int8_t rpp_fr_cancel_timer(uint8_t ctrl, uint8_t timer_idx)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state == RPP_FR_RUNNING && Fr_CancelAbsoluteTimer(ctrl, timer_idx) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_clear_timer_irq(uint8_t ctrl, uint8_t timer_idx) {
+int8_t rpp_fr_clear_timer_irq(uint8_t ctrl, uint8_t timer_idx)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED && Fr_AckAbsoluteTimerIRQ(ctrl, timer_idx) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_timer_irq_status(uint8_t ctrl, uint8_t timer_idx, boolean_t* irq_pending) {
+int8_t rpp_fr_get_timer_irq_status(uint8_t ctrl, uint8_t timer_idx, boolean_t *irq_pending)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (rpp_fr_state >= RPP_FR_DRV_INITIALIZED && Fr_GetAbsoluteTimerIRQStatus(ctrl, timer_idx, irq_pending) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
+
 }
 
-int8_t rpp_fr_get_driver_version(Std_VersionInfoType* version) {
+int8_t rpp_fr_get_driver_version(Std_VersionInfoType *version)
+{
        Fr_GetVersionInfo(version);
        return SUCCESS;
 }
 
-int8_t rpp_fr_read_com_ctrl_config(uint8_t ctrl, uint8_t param_idx, uint32_t* param_value) {
+int8_t rpp_fr_read_com_ctrl_config(uint8_t ctrl, uint8_t param_idx, uint32_t *param_value)
+{
+       RPP_MUTEX_LOCK(mutex_fr);
        if (Fr_ReadCCConfig(ctrl, param_idx, param_value) & E_OK) {
+               RPP_MUTEX_UNLOCK(mutex_fr);
                return SUCCESS;
        }
+
+       RPP_MUTEX_UNLOCK(mutex_fr);
        return FAILURE;
-}
 
+}
 
-#endif /* rppCONFIG_INCLUDE_FR */
+#endif /* FREERTOS_POSIX */