Thread: Global Functions

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    37

    Global Functions

    Hi,

    I am getting a compiler error:

    [Linker error] undefined reference to 'send_packet'
    I get this error when I try to compile example-635.c

    example-635.c
    Code:
    int main(int argc, char* argv[])
      {
      printf("Ultra-simple CFA-635 command-line communications example.\n");
      printf("Crystalfontz America, Inc. http://www.crystalfontz.com\n\n");
      printf("Usage:\n");
      printf("%s PORT BAUD\n");
      printf("PORT is COM1\n");
      printf("BAUD is 115200\n");
    
      /*//If only 0 or 1 parameter is entered, prompt for the missing parameter(s)
      if(argc < 3)
        {
          printf("\nMISSING A PARAMETER. Enter both PORT and BAUD.\n\n");
          return(0);
        }*/
    
      //Check for optional "clear" parameter and set flag if found
      /*int
        cleardisplay=0;
      if((argc > 3)&&(!strcmp(argv[3],"clear"))) cleardisplay=1;*/
    
    
    /*  int
        baud;
      //default the baud to 115200
      if(strcmp(argv[2],"19200"))
        baud=115200;
      else
        baud=19200;*/
    
      if(SetupCommPort())
        {
        printf("Could not open port.");
        return(1);
        }
      else
        printf("Comm Port Opened");
    
      //For some reason, Linux seems to buffer up data from the LCD, and they are sometimes
      //dumped at the start of the program. Clear the serial buffer.
      //while(BytesAvail())
      //  GetByte();
    
    //Outgoing command packets. Either clear the screen
    //or send our line information
    //**********************************************
    /*  if(cleardisplay)
      {
        outgoing_response.command = 6;
        outgoing_response.data_length = 0;
        send_packet();
      }
      else
      {*/
        //Send line 1 to the 635 using command 31
        outgoing_response.command = 31;
        outgoing_response.data[0]=0; //col
        outgoing_response.data[1]=0; //row
        memcpy(&outgoing_response.data[2],">>>This is line 1<<<",20);
        outgoing_response.data_length = 22;  //the col & row position + the 20 char data length
        send_packet();
    
    		//CFA-635 communications protocol only allows
    		//one outstanding packet at a time. Wait for the response
    		//packet from the CFA-635 before sending another
    		//packet.
    		int
    		k;
    		int
    		timed_out;
    		timed_out = 1; //default timed_out is true
    		for(k=0;k<=10000;k++)
    		if(check_for_packet())
    			{
    			ShowReceivedPacket();
    			timed_out = 0; //set timed_out to false
    			break;
    			}
    		if(timed_out)
    		printf("Timed out waiting for a response.\n");
    
        //Send line 2 to the 635 using command 31
        outgoing_response.command = 31;
        outgoing_response.data[0]=0; //col
        outgoing_response.data[1]=1; //row
        memcpy(&outgoing_response.data[2],">>>This is line 2<<<",20);
        outgoing_response.data_length = 22;
        send_packet();
    
    		timed_out = 1; //default timed_out is true
    		for(k=0;k<=10000;k++)
    			if(check_for_packet())
    				{
    				ShowReceivedPacket();
    				timed_out = 0; //set timed_out to false
    				break;
    				}
    		if(timed_out)
    			printf("Timed out waiting for a response.\n");
    
        //Send line 3 to the 635 using command 31
        outgoing_response.command = 31;
        outgoing_response.data[0]=0; //col
        outgoing_response.data[1]=2; //row
        memcpy(&outgoing_response.data[2],">>>This is line 3<<<",20);
        outgoing_response.data_length = 22;
        send_packet();
    
    		timed_out = 1; //default timed_out is true
    		for(k=0;k<=10000;k++)
    			if(check_for_packet())
    				{
    				ShowReceivedPacket();
    				timed_out = 0; //set timed_out to false
    				break;
    				}
    		if(timed_out)
    			printf("Timed out waiting for a response.\n");
    
        //Send line 4 to the 635 using command 31
        outgoing_response.command = 31;
        outgoing_response.data[0]=0; //col
        outgoing_response.data[1]=3; //row
        memcpy(&outgoing_response.data[2],">>>This is line 4<<<",20);
        outgoing_response.data_length = 22;
        void send_packet(void);
    
    		timed_out = 1; //default timed_out is true
    		for(k=0;k<=10000;k++)
    			if(check_for_packet())
    				{
    				ShowReceivedPacket();
    				timed_out = 0; //set timed_out to false
    				break;
    				}
    		if(timed_out)
    			printf("Timed out waiting for a response.\n");
      //}
    //**********************************************
    
      printf("\nCtrl-C to exit.\n");
      printf("Updated display, now waiting for packets\n\n");
    
    /*  while(!cleardisplay)
       {
         usleep(100000);  // 1/10 second
         if(check_for_packet())
           ShowReceivedPacket();
       }*/
    
    /*  if(cleardisplay) printf("Display Cleared.\n");
      printf("Done.\n\n");*/
      BreakDownCommPort();
      //Uninit_Serial();
      return 0;
      }
    //============================================================================
    HANDLE SetupCommPort()
    {       
        //
        // get tty settings from settings dialog
        //
        UpdateTTYInfo();
    
        //
        // open communication port handle
        //
        COMDEV( TTYInfo ) = CreateFile( gszPort,  
                                          GENERIC_READ | GENERIC_WRITE, 
                                          0, 
                                          0, 
                                          OPEN_EXISTING,
                                          FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
                                          0);
    
        if (COMDEV(TTYInfo) == INVALID_HANDLE_VALUE) {   
            ErrorReporter("CreateFile");
            return NULL;
        }
    
        //
        // Save original comm timeouts and set new ones
        //
        if (!GetCommTimeouts( COMDEV(TTYInfo), &(TIMEOUTSORIG(TTYInfo))))
            ErrorReporter("GetCommTimeouts");
    
        //
        // Set port state
        //
        UpdateConnection();
    
        //
        // set comm buffer sizes
        //
        SetupComm(COMDEV(TTYInfo), MAX_READ_BUFFER, MAX_WRITE_BUFFER);
    
        //
        // raise DTR
        //
        if (!EscapeCommFunction(COMDEV(TTYInfo), SETDTR))
            ErrorReporter("EscapeCommFunction (SETDTR)");
    
        //
        // start threads and set initial thread state to not done
        //
        StartThreads();
    
        //
        // set overall connect flag
        //
        CONNECTED( TTYInfo ) = TRUE ;
    
        return COMDEV(TTYInfo);
    }
    'send_packet' is defined in file 'cf_packet.h'

    cf_packet.h
    Code:
    #define MAX_DATA_LENGTH 22
    //============================================================================
    #define MAX_COMMAND 35
    //============================================================================
    typedef struct
      {
      ubyte
        command;
      ubyte
        data_length;
      ubyte
        data[MAX_DATA_LENGTH];
      WORD_UNION
        CRC;
      }COMMAND_PACKET;
    //============================================================================
    word get_crc(ubyte *bufptr,word len,word seed);
    //============================================================================
    extern COMMAND_PACKET
      incoming_command;
    extern COMMAND_PACKET
      outgoing_response;
    //============================================================================
    ubyte check_for_packet(void);
    void send_packet(void);
    //============================================================================
    and send_packet() is declared in file cf_packet.c

    cf_packet.c
    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include "typedefs.h"
    #include "serial.h"
    #include "cf_packet.h"
    //------------------------------------------------------------------------------
    word get_crc(ubyte *bufptr,word len,word seed)
      {
      //CRC lookup table to avoid bit-shifting loops.
      static const word crcLookupTable[256] =
        {0x00000,0x01189,0x02312,0x0329B,0x04624,0x057AD,0x06536,0x074BF,
         0x08C48,0x09DC1,0x0AF5A,0x0BED3,0x0CA6C,0x0DBE5,0x0E97E,0x0F8F7,
         0x01081,0x00108,0x03393,0x0221A,0x056A5,0x0472C,0x075B7,0x0643E,
         0x09CC9,0x08D40,0x0BFDB,0x0AE52,0x0DAED,0x0CB64,0x0F9FF,0x0E876,
         0x02102,0x0308B,0x00210,0x01399,0x06726,0x076AF,0x04434,0x055BD,
         0x0AD4A,0x0BCC3,0x08E58,0x09FD1,0x0EB6E,0x0FAE7,0x0C87C,0x0D9F5,
         0x03183,0x0200A,0x01291,0x00318,0x077A7,0x0662E,0x054B5,0x0453C,
         0x0BDCB,0x0AC42,0x09ED9,0x08F50,0x0FBEF,0x0EA66,0x0D8FD,0x0C974,
         0x04204,0x0538D,0x06116,0x0709F,0x00420,0x015A9,0x02732,0x036BB,
         0x0CE4C,0x0DFC5,0x0ED5E,0x0FCD7,0x08868,0x099E1,0x0AB7A,0x0BAF3,
         0x05285,0x0430C,0x07197,0x0601E,0x014A1,0x00528,0x037B3,0x0263A,
         0x0DECD,0x0CF44,0x0FDDF,0x0EC56,0x098E9,0x08960,0x0BBFB,0x0AA72,
         0x06306,0x0728F,0x04014,0x0519D,0x02522,0x034AB,0x00630,0x017B9,
         0x0EF4E,0x0FEC7,0x0CC5C,0x0DDD5,0x0A96A,0x0B8E3,0x08A78,0x09BF1,
         0x07387,0x0620E,0x05095,0x0411C,0x035A3,0x0242A,0x016B1,0x00738,
         0x0FFCF,0x0EE46,0x0DCDD,0x0CD54,0x0B9EB,0x0A862,0x09AF9,0x08B70,
         0x08408,0x09581,0x0A71A,0x0B693,0x0C22C,0x0D3A5,0x0E13E,0x0F0B7,
         0x00840,0x019C9,0x02B52,0x03ADB,0x04E64,0x05FED,0x06D76,0x07CFF,
         0x09489,0x08500,0x0B79B,0x0A612,0x0D2AD,0x0C324,0x0F1BF,0x0E036,
         0x018C1,0x00948,0x03BD3,0x02A5A,0x05EE5,0x04F6C,0x07DF7,0x06C7E,
         0x0A50A,0x0B483,0x08618,0x09791,0x0E32E,0x0F2A7,0x0C03C,0x0D1B5,
         0x02942,0x038CB,0x00A50,0x01BD9,0x06F66,0x07EEF,0x04C74,0x05DFD,
         0x0B58B,0x0A402,0x09699,0x08710,0x0F3AF,0x0E226,0x0D0BD,0x0C134,
         0x039C3,0x0284A,0x01AD1,0x00B58,0x07FE7,0x06E6E,0x05CF5,0x04D7C,
         0x0C60C,0x0D785,0x0E51E,0x0F497,0x08028,0x091A1,0x0A33A,0x0B2B3,
         0x04A44,0x05BCD,0x06956,0x078DF,0x00C60,0x01DE9,0x02F72,0x03EFB,
         0x0D68D,0x0C704,0x0F59F,0x0E416,0x090A9,0x08120,0x0B3BB,0x0A232,
         0x05AC5,0x04B4C,0x079D7,0x0685E,0x01CE1,0x00D68,0x03FF3,0x02E7A,
         0x0E70E,0x0F687,0x0C41C,0x0D595,0x0A12A,0x0B0A3,0x08238,0x093B1,
         0x06B46,0x07ACF,0x04854,0x059DD,0x02D62,0x03CEB,0x00E70,0x01FF9,
         0x0F78F,0x0E606,0x0D49D,0x0C514,0x0B1AB,0x0A022,0x092B9,0x08330,
         0x07BC7,0x06A4E,0x058D5,0x0495C,0x03DE3,0x02C6A,0x01EF1,0x00F78};
    
      //Initial CRC value is 0x0FFFF.
      register word
        newCrc;
      newCrc=seed;
      //This algorithim is based on the IrDA LAP example.
      while(len--)
        newCrc = (newCrc >> 8) ^ crcLookupTable[(newCrc ^ *bufptr++) & 0xff];
      //Make this crc match the one's complement that is sent in the packet.
      return(~newCrc);
      }
    //============================================================================
    COMMAND_PACKET
      incoming_command;
    COMMAND_PACKET
      outgoing_response;
    //============================================================================
    //                              send_packet()
    //
    // send_packet() will send set the CRC in outgoing_response and send it to
    // the host.
    //----------------------------------------------------------------------------
    void send_packet(void)
      {
      //In order to send the entire packet in one call to "write()", we
      //need to place the CRC packed against the data. If data_length
      //happens to be MAX_DATA_LENGTH, then the position of the CRC is
      //outgoing_response.CRC (like you would expect), but if data_length
      //is less, the CRC moves into the data area, packed into the first
      //unused data position.
      //
      //Create a pointer to the first unused data positions.
      word
       *packed_CRC_position;
      packed_CRC_position=
        (word *)&outgoing_response.data[outgoing_response.data_length];
      *packed_CRC_position=
        get_crc((ubyte *)&outgoing_response,outgoing_response.data_length+2,0xFFFF);
      //command, length, data[data_length], crc, crc
      SendData((ubyte *)&outgoing_response,outgoing_response.data_length+4);
      }
    //============================================================================
    //                              check_for_packet()
    //
    // check_for_packet() will see if there is a valid packet in the input buffer.
    // If there is, it will copy it into incoming_command and return 1. If there
    // is not it will return 0. incoming_packet may get partially filled with
    // garbage if there is not a valid packet available.
    //----------------------------------------------------------------------------
    ubyte check_for_packet(void)
      {
      Sync_Read_Buffer();
      ubyte
        i;
      //First off, there must be at least 4 bytes available in the input stream
      //for there to be a valid command in it (command, length, no data, CRC).
      if((i=BytesAvail())<4)
        return(0);
      //The "peek" stuff allows us to look into the RS-232 buffer without
      //removing the data.
      Sync_Peek_Pointer();
      //Only commands 0 through MAX_COMMAND are valid.
      if(MAX_COMMAND<(0x3F&(incoming_command.command=PeekByte())))
        {
        //Throw out one byte of garbage. Next pass through should re-sync.
        GetByte();
        return(0);
        }
      //There is a valid command byte. Get the data_length. The data length
      //must be within reason.
      if(MAX_DATA_LENGTH<(incoming_command.data_length=PeekByte()))
        {
        //Throw out one byte of garbage. Next pass through should re-sync.
        GetByte();
        return(0);
        }
      //Now there must be at least incoming_command.data_length+sizeof(CRC) bytes
      //still available for us to continue.
      if((int)PeekBytesAvail()<(incoming_command.data_length+2))
        //It looked like a valid start of a packet, but it does not look
        //like the complete packet has been received yet.
        return(0);
      //There is enough data to make a packet. Transfer over the data.
      for(i=0;i<incoming_command.data_length;i++)
        incoming_command.data[i]=PeekByte();
      //Now move over the CRC.
      incoming_command.CRC.as_bytes[0]=PeekByte();
      incoming_command.CRC.as_bytes[1]=PeekByte();
      //Now check the CRC.
      if(incoming_command.CRC.as_word==
         get_crc((ubyte *)&incoming_command,incoming_command.data_length+2,0xFFFF))
        {
        //This is a good packet. I'll be horn swaggled. Remove the packet
        //from the serial buffer.
        AcceptPeekedData();
        //Let our caller know that incoming_command has good stuff in it.
        return(1);
        }
      //The CRC did not match. Toss out one byte of garbage. Next pass through
      //should re-sync.
      GetByte();
      return(0);
      }
    Does anyone know what I need to do to get rid of the [Linker error]? and so I can use send_packet() in example-635.c?

    Any help would be gratly appreciated.

  2. #2
    Registered User
    Join Date
    Mar 2009
    Posts
    20
    cf_packet.c must be compiled and linked with your main program.

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    37
    Thanks Xmariux,

    but how would I compile multiple files?

    Is it:

    gcc -c example-635.c cf_packet.c

    gcc -o example-635.o cfpacket.o example-635

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    20
    2 ways:

    compile main program and linking wiht one command, all objects will be created and an executable will be created after all
    1) gcc -o myprogram example-635.c cf_packet.c


    comlile every source file and then link all objects and compile main
    2)complile cf_packet.c
    gcc -c -o cf_packet.o cf_packet.c

    and compile main program and linked with the object cf_packet.o

    gcc -o myprogram example-635.c cf_packet.o


    wiht -c you compile but the compiler will not try to make an executable just compilation
    you can compile with -c your main program and then u can put all objects just for linking(the third way)
    Last edited by xmariux; 04-15-2009 at 06:33 AM.

  5. #5
    Registered User
    Join Date
    Apr 2009
    Posts
    37
    Hi,

    I have another very similar question:

    Compile error: (.text+0x7):serial.c: undefined reference to 'UpdateTTYInfo'

    This error shows when I run the compile command:
    gcc -o myprogram example-635.c cf_packet.c serial.c show_packet.c SETTINGS.C

    The function UpdateTTYInfo() is defined in file 'SETTINGS.C'

    Code:
    void UpdateTTYInfo() {
     //some code
    }
    The 'UpdateTTYInfo()' function is called in file 'serial.c' that is what gives the compile error.

    To resolve this i created a file called 'settings.h' which iincluded the code

    Code:
    void UpdateTTYInfo(void);
    and #include(d) "settings.h in file 'serial.c' , but still no luck

    Any ideas?

  6. #6
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,794
    your lines shown in the post are copied from the corresponding files as is?

    first thing I would check - you made no mistakes in the function name in one of the 3 places it is mentioned
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    David J. Wheeler

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    20
    change

    Code:
    void UpdateTTYInfo() {
     //some code
    }
    to:

    Code:
    void UpdateTTYInfo(void) {
     //some code
    }
    maybe this is the error , if after this u have errors change SETTINGS.C to SETTINGS.c
    The last change is stupid but i would try it to be sure.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. global functions and OO
    By l2u in forum C++ Programming
    Replies: 2
    Last Post: 05-12-2007, 11:00 AM
  2. Classes and Global Functions
    By d_heyzie in forum C++ Programming
    Replies: 4
    Last Post: 04-17-2007, 07:57 PM
  3. Static functions.... why?
    By patricio2626 in forum C++ Programming
    Replies: 4
    Last Post: 04-02-2007, 08:06 PM
  4. Passing pointers between functions
    By heygirls_uk in forum C Programming
    Replies: 5
    Last Post: 01-09-2004, 06:58 PM
  5. global functions
    By xconspirisist in forum C++ Programming
    Replies: 7
    Last Post: 12-10-2003, 11:35 AM