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 support@ccsinfo.com

Getting the Data Type for a RAM Location

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



Joined: 20 Sep 2005
Posts: 3

View user's profile Send private message Visit poster's website

Getting the Data Type for a RAM Location
PostPosted: Wed Nov 15, 2017 8:34 am     Reply with quote

Has anyone figured out a way to tell what the data type of a RAM location is ? I am working on a Modbus to RAM converter that can get the sizeof and just wondering if there is a why tell if it is an Int32 or a float for example. Part 2: is there a way to tell if it is signed or unsigned ?
Ttelmah



Joined: 11 Mar 2010
Posts: 12505

View user's profile Send private message

PostPosted: Wed Nov 15, 2017 8:45 am     Reply with quote

A RAM location doesn't have a 'type'. Variables have types. All the type defines is 'how' the ram is to be looked at. You can even take a variable that is (for instance) a unsigned int16, put 65535 in it, and then print it with %Ld, and have it be displayed as -1.....
This is also why if you pass a pointer to a routine, and want the routine to deal with this as holding data of a particular size, you have to use sizeof, and pass the size to the routine as another variable.
Then something like a union, allows multiple variables of different types, to be sharing the same memory location. Even worse, if a variable is 'local' (not global), the same RAM will often be re-used by other variables that are completely different sizes.
If you want your code to know what s stored, you are going to have to work out a way of telling your routine what it is dealing with....
David Pouzar



Joined: 20 Sep 2005
Posts: 3

View user's profile Send private message Visit poster's website

Modbus to RAM
PostPosted: Wed Nov 15, 2017 8:57 am     Reply with quote

What I am doing is taking a modbus address and mapping to a Global Ram location. I wrote a function that knows when the user is requesting modbus address 7100 it is a float at pointer 178. Here is an example below. I was hoping I could get if it a float, int32, signed int32 instead of manually identifying it by it modbus address. Ideas? thank you for your quick reply..

Code:
float read_modbus2ram(int16 modbusAddress) //takes the modbus address return a float
{
    //pointers]
    float *ptr_f;
    unsigned int32 *ptr_uint32;
    signed int32 *ptr_sint32;
    unsigned int16 *ptr_uint16;
    signed int16 *ptr_sint16;
   
   
    float temp_float;
    signed int32 temp_sint32;
    unsigned int32 temp_uint32;
    signed int16 temp_sint16;
    unsigned int16 temp_uint16;
//    int8 temp_byte[4];
    dataM.field_length=sizeof(sysTotalRunTime); //DCP Testing
    //
    int16 temp_address;
    temp_float=0;
    modbus2ram(modbusAddress); //convert Modbus Address to RAM Address
    switch(dataM.data_type) //what is the datatype this is manually assigned in the modbus2ram function
    {
        case flag:
        {
            temp_float=(float)(bit_test(*dataM.ram_address,dataM.bit_loc));
            break;
        }
        case sint16: //1- signed integer 16bit
        {
            temp_address=dataM.ram_address; //get the ram address
            ptr_sint16 = temp_address; //assign it to the pointer
            temp_sint16 =*ptr_sint16; //get the value of the pointer
            temp_float=(float)temp_sint16; //convert to float
            break;
        }
        case uint16:  //2 - unsigned integer 16bit
        {
            temp_address=dataM.ram_address; //get the ram address
            ptr_uint16 = temp_address; //assign it to the pointer
            temp_uint16 = *ptr_uint16; //get the value of the pointer
            temp_float=(float)temp_uint16; //convert to float
            break;
        }
        case sint32:  //3 - signed integer 32bit
        {
//            temp_address=dataM.ram_address
            temp_address=dataM.ram_address; //get the ram address
            ptr_sint32 = temp_address; //assign it to the pointer
            temp_sint32 = *ptr_sint32; //get the value of the pointer
            temp_float=(float)temp_sint32; //convert to float
            break;
        }
        case uint32: //4 - unsigned integer 32bit
        {
            temp_address=dataM.ram_address; //get the ram address
            ptr_uint32 = temp_address; //assign it to the pointer
            temp_uint32 = *ptr_uint32; //get the value of the pointer
            temp_float=(float)temp_uint32; //convert to float
            break;
        }
        case sFloat: //5 - float 32bit
        {
            temp_address=dataM.ram_address; //get the ram address
            ptr_f = temp_address; //assign it to the pointer
            temp_float = *ptr_f; //get the value of the pointer
            //temp_float=(float)temp_int32; //convert to float
           
            break;

    }
    return(temp_float);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 12505

View user's profile Send private message

PostPosted: Wed Nov 15, 2017 9:31 am     Reply with quote

It won't care.....

Just transfer 4 bytes. All of the types are the same size, so just send that amount of data from the location. It doesn't matter at all 'what' is actually stored there.
RF_Developer



Joined: 07 Feb 2011
Posts: 809

View user's profile Send private message

PostPosted: Wed Nov 15, 2017 10:27 am     Reply with quote

Even four bytes won't work as all Modbus registers are sixteen bit, i.e. two bytes. Coils are single bits.

As Modbus predates modern datatyping, there is no inherent data type associated with Modbus registers, they can mean whatever you want them to mean. Personally I try to keep clear of floats, using scaled 16 bit integers instead, e.g. voltage in integer millivolts rather than float volts. If you want to transfer 32 bit quantities, set up your registers in pairs, one with the high 16 bits and one with the lower. There is no inherent endianness implied by Modbus: registers are independant and have no assumed relationship to each other. So you can use whatever endianness you like, but its clearly sensible to adopt a standard and stick to it.

It is also possible, and practical to transfer groups of registers, and to implement memory-style interfaces through registers, just as the PIC hardware does for program memory and built-in EEPROM.
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