LCOV - code coverage report
Current view: top level - libs/bsp/bspDynamicClient/include/io - DynamicClientCfg.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.0 % 25 22
Test Date: 2026-06-18 08:29:03 Functions: 100.0 % 3 3

            Line data    Source code
       1              : /********************************************************************************
       2              :  * Copyright (c) 2024 Accenture
       3              :  *
       4              :  * This program and the accompanying materials are made available under the
       5              :  * terms of the Apache License Version 2.0 which is available at
       6              :  * https://www.apache.org/licenses/LICENSE-2.0
       7              :  *
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  ********************************************************************************/
      10              : 
      11              : #pragma once
      12              : 
      13              : #include "platform/estdint.h"
      14              : 
      15              : /**
      16              :  * This data type provides an abstract runtime mapping between a common shared I/O and
      17              :  * higher-level instances that can use this I/O.
      18              :  *
      19              :  * Usage: create an instance of dynamic client inside the class responsible for distribution of the
      20              :  * I/O channels that have to be dynamic, and provide public methods for adding and removing the
      21              :  * dynamic client.
      22              :  *
      23              :  * @tparam T - type that contains client's index + index of a channel inside a client.
      24              :  * @tparam IDynamicClient - type of an object that should be registered as a dynamic client
      25              :  * @tparam Size - bit width for count of clients, number of clients then is 2^Size
      26              :  * @tparam dynamicChannelsCount - number of dynamic channels that can be stored in this structure
      27              :  * @tparam dynamicClientsCount - number of dynamic clients that use this proxy.
      28              :  */
      29              : template<
      30              :     typename T,
      31              :     typename IDynamicClient,
      32              :     int32_t Size,
      33              :     int32_t dynamicChannelsCount,
      34              :     int32_t dynamicClientsCount = 0>
      35              : struct dynamicClient
      36              : {
      37              :     //[Enum_start]
      38              : 
      39              :     enum
      40              :     {
      41              :         bitWidthDynamicClientCount         = Size,
      42              :         bitWidthDynamicClientsChannelCount = ((sizeof(T) * 8) - bitWidthDynamicClientCount),
      43              :         maxDynamicClientCount              = (0x01U << bitWidthDynamicClientCount),
      44              :         channelInvalid                     = (0x01U << bitWidthDynamicClientsChannelCount) - 1U,
      45              :         dynamicClientInvalid               = (0x01U << bitWidthDynamicClientCount) - 1U,
      46              :         dynamicChannels                    = dynamicChannelsCount
      47              :     };
      48              : 
      49              :     //[Enum_end]
      50              : 
      51              :     /**
      52              :      * If dynamicClientsCount is not explicitly specified, maximum possible dynamicClientsCount is
      53              :      * selected.
      54              :      */
      55              :     static T const dynamicClientCountCfg
      56              :         = (dynamicClientsCount == 0 ? static_cast<int32_t>(maxDynamicClientCount)
      57              :                                     : dynamicClientsCount);
      58              : 
      59              :     /**
      60              :      * This structure is responsible for distributing number of clients and number of
      61              :      * instances per client.
      62              :      * If T is 8 bit, then dynamicClient can devote N bits to instances' indexing and (8-N) bits to
      63              :      * indexing inside a single client.
      64              :      * Example:
      65              :      * T = uint8_t, Size = 2 --> instanceNumber is in [0..3], numberInsideClient is in [0..31]
      66              :      */
      67              :     using tDynamicClientCfg = struct
      68              :     {
      69              :         T numberInsideClient : bitWidthDynamicClientsChannelCount;
      70              :         T instanceNumber : bitWidthDynamicClientCount;
      71              :     };
      72              : 
      73              :     // METHOD_START
      74              :     /**
      75              :      * Clean all Clients
      76              :      */
      77              :     static void cleanDynamicClients();
      78              : 
      79              :     /**
      80              :      * Check Valid Channel
      81              :      * @param : number of channel
      82              :      * @ret   : true is valid ,false - not valid
      83              :      */
      84              :     static bool getClientValid(T channel);
      85              : 
      86              :     /**
      87              :      * setDynamicClient
      88              :      * @param : channel number ,
      89              :      * @param : numberInsideClient , channel number inside the Client
      90              :      * @param : IDynamicClient* client
      91              :      * @ret   : true , false
      92              :      */
      93              :     bool setDynamicClient(T channel, T numberInsideClient, IDynamicClient* client);
      94              : 
      95              :     /**
      96              :      * clearDynamicClient
      97              :      * @param : channel number ,
      98              :      * @ret   : true , false
      99              :      */
     100              :     bool clearDynamicClient(T channel);
     101              : 
     102              :     /**
     103              :      * getClientInstance, channel has to be first checked using `getClientValid()` method
     104              :      * @param : number of channel
     105              :      * @ret   : IDynamicClient*
     106              :      */
     107            3 :     static inline IDynamicClient* getClientInstance(T channel)
     108              :     {
     109            3 :         return (fpDynamicClient[fDynamicChannelCfg[channel].instanceNumber]);
     110              :     }
     111              : 
     112            3 :     static inline T getChannelInsideClient(T channel)
     113              :     {
     114            3 :         return (fDynamicChannelCfg[channel].numberInsideClient);
     115              :     }
     116              : 
     117              :     static tDynamicClientCfg fDynamicChannelCfg[dynamicChannels];
     118              :     static IDynamicClient* fpDynamicClient[dynamicClientCountCfg];
     119              : 
     120              :     // METHOD_END
     121              : };
     122              : 
     123              : template<
     124              :     typename T,
     125              :     typename IDynamicClient,
     126              :     int32_t Size,
     127              :     int32_t dynamicChannelsCount,
     128              :     int32_t dynamicClientCount>
     129              : typename dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     130              :     tDynamicClientCfg
     131              :         dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     132              :             fDynamicChannelCfg[dynamicChannels];
     133              : 
     134              : template<
     135              :     typename T,
     136              :     typename IDynamicClient,
     137              :     int32_t Size,
     138              :     int32_t dynamicChannels,
     139              :     int32_t dynamicClientCount>
     140              : IDynamicClient* dynamicClient<T, IDynamicClient, Size, dynamicChannels, dynamicClientCount>::
     141              :     fpDynamicClient[dynamicClientCountCfg];
     142              : 
     143              : template<
     144              :     typename T,
     145              :     typename IDynamicClient,
     146              :     int32_t Size,
     147              :     int32_t dynamicChannelsCount,
     148              :     int32_t dynamicClientCount>
     149              : void dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     150              :     cleanDynamicClients()
     151              : {
     152              :     for (int32_t i = 0; i < (dynamicClientCountCfg); i++)
     153              :     {
     154              :         fpDynamicClient[i] = nullptr;
     155              :     }
     156              :     for (int32_t i = 0; i < (dynamicChannels); i++)
     157              :     {
     158              :         fDynamicChannelCfg[i].numberInsideClient = channelInvalid;
     159              :         fDynamicChannelCfg[i].instanceNumber     = dynamicClientInvalid;
     160              :     }
     161              : }
     162              : 
     163              : template<
     164              :     typename T,
     165              :     typename IDynamicClient,
     166              :     int32_t Size,
     167              :     int32_t dynamicChannelsCount,
     168              :     int32_t dynamicClientCount>
     169              : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     170              :     getClientValid(T channel)
     171              : {
     172              :     bool ret = false;
     173              :     if (channel < dynamicChannels)
     174              :     {
     175              :         T instanceNumber = fDynamicChannelCfg[channel].instanceNumber;
     176              :         if (instanceNumber < dynamicClientCountCfg)
     177              :         {
     178              :             if ((instanceNumber < dynamicClientInvalid)
     179              :                 && (fDynamicChannelCfg[channel].numberInsideClient < channelInvalid)
     180              :                 && (fpDynamicClient[instanceNumber] != nullptr))
     181              :             {
     182              :                 ret = true;
     183              :             }
     184              :         }
     185              :     }
     186              : 
     187              :     return ret;
     188              : }
     189              : 
     190              : template<
     191              :     typename T,
     192              :     typename IDynamicClient,
     193              :     int32_t Size,
     194              :     int32_t dynamicChannelsCount,
     195              :     int32_t dynamicClientCount>
     196            3 : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     197              :     setDynamicClient(T channel, T numberInsideClient, IDynamicClient* client)
     198              : {
     199              :     // range of outputNumber check
     200            3 :     if (numberInsideClient >= channelInvalid)
     201              :     {
     202            0 :         return false;
     203              :     }
     204              : 
     205            3 :     if (channel < dynamicChannels) // number is out of range
     206              :     {
     207            3 :         uint8_t mySlot          = 0xFFU;
     208            3 :         uint8_t availableClient = 0xFFU;
     209           20 :         for (T i = 0; (i < dynamicClientCountCfg) && (availableClient == 0xFFU); i++)
     210              :         {
     211           17 :             if (client == fpDynamicClient[i])
     212              :             {
     213            1 :                 availableClient = static_cast<uint8_t>(i);
     214              :             }
     215           17 :             if (fpDynamicClient[i] == nullptr)
     216              :             {
     217           15 :                 if (mySlot == 0xFFU)
     218              :                 {
     219            2 :                     mySlot = static_cast<uint8_t>(i);
     220              :                 }
     221              :             }
     222              :         }
     223              :         // Occupy slot for client
     224            3 :         if (availableClient == 0xFFU) // not in Map yet
     225              :         {
     226            2 :             if (mySlot != 0xFFU) // placed
     227              :             {
     228            2 :                 fpDynamicClient[mySlot] = client;
     229              :             }
     230              :             else // no free place
     231              :             {
     232            0 :                 return false;
     233              :             }
     234              :         }
     235              :         else
     236              :         {
     237            1 :             mySlot = availableClient;
     238              :         }
     239              : 
     240            3 :         fDynamicChannelCfg[channel].numberInsideClient = numberInsideClient;
     241            3 :         fDynamicChannelCfg[channel].instanceNumber     = mySlot;
     242            3 :         return true;
     243              :     }
     244              :     else
     245              :     {
     246            0 :         return false;
     247              :     }
     248              : }
     249              : 
     250              : template<
     251              :     typename T,
     252              :     typename IDynamicClient,
     253              :     int32_t Size,
     254              :     int32_t dynamicChannelsCount,
     255              :     int32_t dynamicClientCount>
     256              : bool dynamicClient<T, IDynamicClient, Size, dynamicChannelsCount, dynamicClientCount>::
     257              :     clearDynamicClient(T channel)
     258              : {
     259              :     if (channel < dynamicChannels) // number is out of range
     260              :     {
     261              :         T instanceNumber       = fDynamicChannelCfg[channel].instanceNumber;
     262              :         IDynamicClient* client = fpDynamicClient[instanceNumber];
     263              : 
     264              :         fDynamicChannelCfg[channel].numberInsideClient = channelInvalid;
     265              :         fDynamicChannelCfg[channel].instanceNumber     = dynamicClientInvalid;
     266              :         // look for other outputs
     267              : 
     268              :         if ((client == nullptr) || (instanceNumber >= dynamicClientCountCfg))
     269              :         {
     270              :             return true;
     271              :         }
     272              : 
     273              :         uint8_t availableClient = 0xFFU;
     274              :         for (T i = 0; i < dynamicClientCountCfg; i++)
     275              :         {
     276              :             if (client == fpDynamicClient[i])
     277              :             {
     278              :                 availableClient = i; // Found a client
     279              :                 break;
     280              :             }
     281              :         }
     282              :         if (availableClient != 0xFFU)
     283              :         {
     284              :             bool found = false;
     285              :             for (T i = 0; i < dynamicChannels; i++)
     286              :             {
     287              :                 if (fDynamicChannelCfg[i].instanceNumber == availableClient)
     288              :                 {
     289              :                     found = true;
     290              :                     break;
     291              :                 }
     292              :             }
     293              :             if (!found)
     294              :             {
     295              :                 // No client was found, the link can be deleted.
     296              :                 fpDynamicClient[availableClient] = nullptr;
     297              :             }
     298              :         }
     299              : 
     300              :         return true;
     301              :     }
     302              :     else
     303              :     {
     304              :         return false;
     305              :     }
     306              : }
        

Generated by: LCOV version 2.0-1