Hi Peter,

Peter Mueller wrote:
Hello,

I develop a small function block based application. Each function block input and output is associated with a bit in a bitfield. Function blocks can be simple logic, timers, ... By "wiring" these function blocks I get a kind of very simple PLC.

My first try is to allocate a byte arrary. In addition there is a get and set function that gets the bit number I want to read or write. Internally I have to do some calculation to find the right bit in the byte array. The attached file shows how it is implemented.

The function blocks uses these get and set functions for accessing their input and output ports. I wonder if there is a better method to implement such a functionality.

- Is it possible to get rid of the function calls (get/set) in the function blocks? Or make these calls as efficient as possible?

You can get rid of your function calls (and their local variables) by defining macros like in the attached example files. This makes certain what you can also reach with your functions using most compilers' optimization capabilities: remove automatic stack variables using registers and inline function code to avoid function call overhead. However macros force "code inlining" while using functions with optimization is tool dependent and always restricted to their very source file.

- Is there a more efficient way to implement my data store? E.g. does it make sense to use bitfields?

Why? Your bit array uses eight bytes for 64 independent two-state information. What more can any other implementation do to reduce this (use some futuristic tri-state-logic computers ;-). Bitfields sometimes have the slight disadvantage of special member names: You can loop through members of a bit array (as your implementation allows for) but not so for bit fields. I don't know if this is needed by your current application.

- Any other ideas - maybe someone has developed something similar?

See attached files.
Regards

Arnd-Hendrik


Thanks,
Peter

P.S: I'm also looking for a windows tool to "wire" my blocks. Do anyone knows a tool that can do that and is open for my own extension such as downloading the "wires" to the uC.

Thanks a lot,
Peter

--
Peter Mueller
[email protected]


------------------------------------------------------------------------

#include "sps_types.h"

#ifdef WIN32
#include <assert.h>
#endif

/**
  * The datastore holds all inputs and outpus of all functionblocks that can
  * can exist in an application.
* * The memory layout is the following:
  *
  * Byte[0               | 1                      | ...
  * Bit#[0,1,2,3,4,5,6,7 | 8,9,10,11,12,13,14,16, | ...
  *
  */

#define LEN_DATA_STORE 8
#define MAX_POS_DATA_STORE (LEN_DATA_STORE*8)

static unsigned char data_store[LEN_DATA_STORE];

static const unsigned char mappingtable[8] = {128,64,32,16,8,4,2,1};

TBOOL ds_get_bool(TUSIGN8 pos){


        unsigned int isInByte, rest;
        
#ifdef WIN32
        assert(pos <= MAX_POS_DATA_STORE);
#endif

        isInByte = pos/8;
        rest = pos%8; // Bsp.: 9 mod 8 = 1

if((data_store[isInByte]) & mappingtable[rest]) return TRUE;
        else
                return FALSE;

}


TUSIGN8 ds_set_bool(TUSIGN8 pos, TBOOL val){

        unsigned char isInByte, rest;

#ifdef WIN32
        assert(pos <= MAX_POS_DATA_STORE);
#endif

        isInByte = pos/8;
        rest = pos%8;

        if(val==1)
                data_store[isInByte] |= mappingtable[rest];
        else
                data_store[isInByte] &= ~(mappingtable[rest]);

        return 0;
        
}

#ifndef BIT_ARRAY_H
#define BIT_ARRAY_H

#define BIT_ARRAY_BIS(a,b)  { a [ b / 8 ] |=   ( 1 << ( b % 8 ) ); }
#define BIT_ARRAY_BIC(a,b)  { a [ b / 8 ] &= ~ ( 1 << ( b % 8 ) ); }
#define BIT_ARRAY_BIT(a,b)  ( ( a [ b / 8 ] >> ( b % 8 ) ) & 1 )
#define BIT_ARRAY_TEST(a,b) ( BIT_ARRAY_BIT ( a, b ) == 1 )

#endif /* BIT_ARRAY_H */
#include <stdio.h>
#include "bitarray.h"

#define NR_OF_PINS 100

static unsigned char ports [ ( NR_OF_PINS +7 ) / 8 ];

static void printPorts ( void )
{
   int i;

   printf ( "  ports = [" );
   for ( i = 0; i < sizeof ( ports ); ++i )
   {
      printf ( "%c 0x%X", ( i != 0 ) ? ',' : ' ', ports [ i ] );
   }
   printf ( " ];\n" );
   return;
}

static void testPort ( int pin )
{
   BIT_ARRAY_BIC ( ports, pin );

   if ( ! BIT_ARRAY_TEST ( ports, pin ) )
   {
      printf ( "Test success: pin %d is cleared.\n", pin );
      printPorts ();
   }
   else
   {
      printf ( "Test failed : pin %d is still set.\n", pin );
      printPorts ();
   }

   BIT_ARRAY_BIS ( ports, pin );

   if ( BIT_ARRAY_TEST ( ports, pin ) )
   {
      printf ( "Test success: pin %d is set.\n", pin );
      printPorts ();
   }
   else
   {
      printf ( "Test failed : pin %d is still cleared.\n", pin );
      printPorts ();
   }

   BIT_ARRAY_BIC ( ports, pin );

   if ( ! BIT_ARRAY_TEST ( ports, pin ) )
   {
      printf ( "Test success: pin %d is cleared.\n", pin );
      printPorts ();
   }
   else
   {
      printf ( "Test failed : pin %d is still set.\n", pin );
      printPorts ();
   }

   return;
}

int main ( int argc, char** argv )
{
   int i;

   for ( i = 0; i < NR_OF_PINS; ++i )
   {
      testPort ( i );
   }

   return 0;
}

Reply via email to