CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Using a pointer to a pointer

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Heath



Joined: 21 Dec 2007
Posts: 41

View user's profile Send private message

Using a pointer to a pointer
PostPosted: Wed May 14, 2008 7:59 am     Reply with quote

Hi folks,

I wanted to use a pointer to a pointer in my application but I ran into some compiler errors when I declared the variable.

For instance, it will not let me compile
Code:
int8 **x;
It tells me that it expects a comma or semi-colon.

I would like to use a pointer to a pointer because I am developing a MODBUS gateway device and the number of MODBUS devices connected to the gateway is unknown at compile time. Therefore, my idea was to just malloc the data later when the number was known and the pointer to a pointer would essentially become an array of pointers. (a pointer to a structure I made)

The compiler does allow me to create an array of pointers but not a pointer to a pointer. I don't think I am doing anything wrong - I think it is just a caveat of the compiler that it wants to know certain information at compile time and I violated that. Is that correct?

I am using the 4.064 Compiler and a PIC18F6527.
Heath



Joined: 21 Dec 2007
Posts: 41

View user's profile Send private message

PostPosted: Wed May 14, 2008 8:19 am     Reply with quote

Hrm, it lets me declare it like this:

Code:
struct MODBUS_GATEWAY_MAP
{
  int8 SlaveType;
  int8 Len;                                // number of bytes in the message received
  MODBUS_FUNCTION_CODES Func;              // the function of the message received
  MODBUS_EXCEPTION_CODES Error;            // error recieved, if any
   int16 *Coils;
   int16 *DiscretesInput;
   int16 *InputRegisters;
   int16 *HoldingRegisters;
} *MODBUS_UNIT_ARRAY[];


and here's the code that sets up the memory map:
Code:
// Purpose:    This function will set up the memory map that MODBUS will interface with.
// Inputs:     None
// Outputs:    A complete memory map.
void MODBUS_SetupMemoryMap()
{
  int8 i, MAX_NODES;
  struct MODBUS_GATEWAY_MAP MODBUS_slave;
 
  // Calculate the number of MODBUS slaves that are under this Gateway. If more devices
  // are added simply add their 'count' variable to the following line.
  MAX_NODES = MaxControllerNum;
 
  // Now that we know how many nodes are connected we can set up our memory map
 
  // Start by allocating memory for our array.
  MODBUS_UNIT_ARRAY = calloc(MAX_NODES, sizeof(MODBUS_slave));
 
  for (i=0; i<MaxControllerNum; i++)
  {
     MODBUS_UNIT_ARRAY[i].InputRegisters   = (int16 *)MB_CTRL_ARRAY[i]->Setpoints;     
    MODBUS_UNIT_ARRAY[i].SlaveType          = 0;
  }
}
Matro
Guest







PostPosted: Wed May 14, 2008 8:50 am     Reply with quote

You can use the following way :
Code:

typedef int8* pint8;
pint8 * var1;
pint8 * var2;


Matro
Heath



Joined: 21 Dec 2007
Posts: 41

View user's profile Send private message

PostPosted: Wed May 14, 2008 9:25 am     Reply with quote

That's a good idea.

Given that I changed my struct defintion to the following:
Code:
struct _MODBUS_GATEWAY_MAP
{
  int8 SlaveType;
  int8 Len;                                // number of bytes in the message received
  MODBUS_FUNCTION_CODES Func;              // the function of the message received
  MODBUS_EXCEPTION_CODES Error;            // error recieved, if any
   int16 *Coils;
   int16 *DiscretesInput;
   int16 *InputRegisters;
   int16 *HoldingRegisters;
} ;

typedef _MODBUS_GATEWAY_MAP* MODBUS_GATEWAY_MAP;
struct MODBUS_GATEWAY_MAP *MODBUS_UNIT_ARRAY;


I'm having a little trouble accessing the members though. I would think that I could just do
Code:
MODBUS_UNIT_ARRAY[i]->something
so access the members but the compiler gives me:
Quote:
Previous identifier must be a pointer

A -> may only be used after a pointer to a structure. It cannot be used on a structure itself or other kind of variable.


I guess it doesn't see it as a struct and is giving that error.
Heath



Joined: 21 Dec 2007
Posts: 41

View user's profile Send private message

PostPosted: Tue Jun 03, 2008 8:06 am     Reply with quote

Has anyone successfully made an array of pointers and filled it via [m|c]alloc?

I read a few posts about how malloc will fragment the memory and should not be used on an embedded device.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Jun 05, 2008 4:15 am     Reply with quote

Heath wrote:
Has anyone successfully made an array of pointers and filled it via [m|c]alloc?

I read a few posts about how malloc will fragment the memory and should not be used on an embedded device.


I would think everything would work/compile better and be less likely to be buggy if you declared a structure array of a fixed size and then only use as much as you actually need. Use a variable to keep track of how many elements are in use and ignore the extras.

I think I would actually store the data for each slave device in the structure instead of using a pointer to another location. If all of the slaves are the same kind of device this will work out better and fit in the 4K RAM on the chip.

If all of your slaves are going to be different kinds of devices with different data maps you probably need to go with external RAM if you need to do it with a PIC. You could have a poll sequence for each device. Something like this would work better on a PC and would benefit a lot from Malloc.

Another approach would be to create a poll array where each poll would get some data and place it into an Master_Data array at a location in the Master_Data array defined by the poll. This would allow multiple polls per device, you could skip addresses and device type would not really matter. This would make a good approach for a data concentrator (gateway device). This would allow a smaller array for the polls and a bigger array for slave data.

Address , Function , Start , Count
Heath



Joined: 21 Dec 2007
Posts: 41

View user's profile Send private message

PostPosted: Thu Jun 05, 2008 9:36 am     Reply with quote

I just actually finished building a gateway device. I declared an array of my max amount.

The pic I am using has two euarts so I put one on the MODBUS side and the other on the controller side. I had a little trouble with the timings and I think I had some race conditions but I think that is all over with now. I am using the MODBUS poll program from www.modbustools.com and I have gotten a few time outs when I let it run over night but I think that is related to windows and not to my PIC.

I am going to set the process as a 'realtime' process in windows and see if the timeouts still happen. I think I will also relax my t1.5 and t3.5 times.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group