View previous topic :: View next topic |
Author |
Message |
Heath
Joined: 21 Dec 2007 Posts: 41
|
Using a pointer to a pointer |
Posted: Wed May 14, 2008 7:59 am |
|
|
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 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
|
|
Posted: Wed May 14, 2008 8:19 am |
|
|
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
|
|
Posted: Wed May 14, 2008 8:50 am |
|
|
You can use the following way :
Code: |
typedef int8* pint8;
pint8 * var1;
pint8 * var2;
|
Matro |
|
|
Heath
Joined: 21 Dec 2007 Posts: 41
|
|
Posted: Wed May 14, 2008 9:25 am |
|
|
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
|
|
Posted: Tue Jun 03, 2008 8:06 am |
|
|
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
|
|
Posted: Thu Jun 05, 2008 4:15 am |
|
|
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
|
|
Posted: Thu Jun 05, 2008 9:36 am |
|
|
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. |
|
|
|