LCOV - code coverage report
Current view: top level - workspace/libs/bsp/bspDynamicClient/include/io - DynamicClientCfg.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 19 19 100.0 %
Date: 2025-01-20 13:53:09 Functions: 1 1 100.0 %

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

Generated by: LCOV version 1.14