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

Beginner of CCS

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



Joined: 22 Apr 2004
Posts: 1
Location: Taiwan

View user's profile Send private message

Beginner of CCS
PostPosted: Thu Apr 22, 2004 6:57 pm     Reply with quote

Hello,
I am a beginner of CCS compiler. After read the reference document and checked some example code. I make some practice. However, I got one question here, hope someone can answer for me.
Can I separate the source code into small source file. compile each and link together? It seems the compiler always complain:
"function used, but not defined:". It happened on the line that function which defined on another file.
I already put "extern function" statement. What should I do?
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

Linker for CCS
PostPosted: Thu Apr 22, 2004 7:10 pm     Reply with quote

For the answer to your question see this link found by searching for linker on this board:

http://www.ccsinfo.com/forum/viewtopic.php?t=7002
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Thu Apr 22, 2004 8:16 pm     Reply with quote

PCM has some good links! And I really sympathize with this problem because it is so basic that no one thinks to answer it anywhere in the help file. I suffered a while on this.

What I hit upon is this, and I would love to hear WHY any of this is true from people more knowledgeable (well, that's a lot of people I admit):

- The "extern" keyword is tolerated but causes local copies of whatever you THINK you are linking to, to be created, instead of linking to your target global variable. THIS IS BAD; the compiler should instead flag any occurrence of "extern" as an error. Look out. (And as an aside, this was the one and only time Tech Support ever answered a question I've sent them. Coincidentally...?... I hadn't yet bought the compiler...)

- For some strange reason it is not necessary to declare function prototypes for any function which hangs off the main function.

- But you must declare function prototypes for any function which hangs off a sub-function.

- Function prototypes are generally like ANSI prototypes except when any kind of pointer is used. Then they get weird, and to me, scary because I worry that I'm not getting a prototype but a literal declared & allocated. In the example below, in my parsemsg() prototype, I worry about the fact that "char * pPacket" will compile but "char *" will not. The symbol table, perhaps because I don't know how to read it very well, provides me with no comfort on this score.

Example below (my current project). This section is part of a lengthy header file I keep #fuses and all sorts of other constants and directives in, and I admit that it isn't anything too great to show you except that it's real and works. Stylistically, I happen to define structs but not allocate space for them except in a non-functioning routine called globldat(), thus I have to provide their definitions pretty early. This is not necessary -- each person does what they think best. What this DOES indicate usefully re your original question is that I have lots of modules and am fond of #defines.

Code:

/* ===========================================================================
Header Name:   voterhdv.h
Purpose:         main program header:  Sets parameters, declares special data
               structures -- though all global data is allocated in <global_d>.

Comments:      Microchip PIC18F8720 is the target device.

               Note: To change pins, edit pin_defs.h.

               ============================================================================*/

#include <18F8720.h>

....
#fuses, etc. and lots of stuff
...

// Widely-used macros etc: ---------------------------------------------------------
#include    <pin_defs.h>
#include    <k_macros.h>


// Struct Definitions: ---------------------------------------------------------
// These struct definitions must PRECEDE globaldat.c or compiler will get lost:
#include    <structs1.h>      // serial data
#include    <structs2.h>      // error codes
#include    <structs3.h>      // servo data

#include    <globldat.c>      // global data instantiations



// Function Prototypes:  (note, ISRs are prototyped using #INT_xxxx) -----------
// ...These must PRECEDE the project files below, or the compiler gets confused.
// Note, for some reason, I don't need prototypes of anything called by main():
void        parsemsg ( int8 , int8 , char * pPacket, int8 msglength );
//int16       tablecr2 ( char * message, int8 );
//int16       tablecrc ( char * message, int8 );
int16         shiftcrc ( char * message, int8 );
#ifdef   CODE4_CORE
   void        Rspi_a2d ( int8 );
   void        Wspi_d2a ( int8 );
   void        getanins ( int8 );
   float       midvalue ( struct vote_avg_sel * pVAS, float, float, float );
   void         v_avgsel ( int8,
                  struct vote_avg_sel * pVAS,
                  int8 commstatus1,    int8 commstatus2,    int8 commstatus3,
                  float   command1,      float command2,      float command3   );
   void         gd_sched ( int8 );
#endif



// Project Files: --------------------------------------------------------------
#include   <ISRdeflt.c>      // Handles unexpected interrupts
#include <ISRclock.c>      // Clock ticks at 1000 Hz
#include <ISRCOM2R.c>      // receive messages COM2
#include <ISRCOM1R.c>      // receive messages COM1
#include <ISRCOM2T.c>      // transmit messages COM2
#include <ISRCOM1T.c>      // transmit messages COM1
#ifdef   CODE4_PP
   #include <ISRppCTS.c>   // IF... I'm a PP, I Tx my PP2CORE msg via an ISR
#endif

#include <whystart.c>      // analyzes watchdog startup reason
#include <initialz.c>      // startup (chip configuration) code
#include <inputdat.c>      // get new inputs
#include <vote_con.c>      // controller logic, votes, sets up D/A flag
#include <postoutp.c>      // post outputs
#include <waittask.c>      // wait until time to begin next cycle

#include <parsemsg.c>      // parse serial messages
//#include   <tablecr2.c>      // calculate CRC-16 via a table lookup
//#include   <tablecrc.c>      // calculate CRC-16 via a table lookup
#include   <shiftcrc.c>      // calculate CRC-16 via bit-shifting
#ifdef   CODE4_CORE
   #include <Rspi_a2d.c>   // called only from ISRclock: read A2D inputs
   #include <Wspi_d2a.c>   // called only from ISRclock: write D2A outputs
   #include <getanins.c>   // get native 10-bit analog inputs (voltage monitors)
   #include   <midvalue.c>   // don't confuse this with the CC version of voting
   #include <v_avgsel.c>   // vote / average / select utility
   #include   <gd_sched.c>   // CORE2PP -> V2CC subspeed channel scheduler
#endif



What I happen to do is set my #defines, #include this big header file (which itself drags in the chip file in the first line, <, then declare main(). The #defines govern what happens inside the header; the header has lots of details you won't want to clutter your highest-level program with; and it all works. Here's the start of my main function:

Code:

/* ===========================================================================
Function Name:   voterhdv
Purpose:         main function
               ============================================================================*/

// Flags:
#define  CODE4_CORE      // Most important switch: sets CORE vs PPROC vs MONITOR
//#define  CODE4_PP        // One of these three should be defined before the
#define    PP_FCN_CODE 0x02   // KLUDGE KLUDGE -- no Fcn Code yet available, 1,2,3
//#define  CODE4_MON        // main header inclusion of #include voterhdv.h.

// Flags which for final design should be #defined:
#define  FULL_SPEED_PORTS   // ifdef, ports allowed to run at 1MBaud
#define   PP2C_PLAN_A         // ifdef, PP uses DIRECT ISR output of PP2C message
//#define LVP_ACTIVE           // ifdef, low-voltage programming is permitted
//#define SPI_A2D2A_ACTIVE      // ifdef, SPI A2D and D2A are performed
//#define NATIVE_A2D_ON         // ifdef, native A2D is performed
//#define NDEBUG                // ifdef, will NOT generate code for assert() macro
#define EXPLICIT_TRIS      // ifdef, uses FAST_IO and explicit TRIS of ports

// Flags which for final design should NOT be #defined:
//#define FIX_THIS            // ifdef, breaks compile at areas needing repair
//#define BUFFERED_TX         // ifdef, buffers all Tx (PLAN_B REQUIRES THIS)
//#define PP2C_PLAN_B         // ifdef, PP uses BUFFERED output of PP2C message
//#define COM1_DEBUG_USE      // ifdef, >bytes out (requires FULL_SPEED_PORTS off)
//#define TRIVIAL_PROGRAM      // ifdef, program does NOTHING except float pins
//#define PP_COM2_SPITTER      // ifdef, PP blasts 'P' bytes at the CORE
#define  8720_PROTO_BOARD  // ifdef, the CCS prototyping board is present
#define  VERBOSE           // ifdef, fprintf can produce dongle-debugging o/p

#include <voterhdv.h>      // main header file: affected by #defines above

// -----------------------------------------------------------------------------
void main()
{
   // Local Data Definitions:
   BOOLEAN  lOK   = TRUE;

   // Begin Procedure ==========================================================
   whystart();                         // Did I restart from a watchdog timeout?

... and so forth.



Now, I still wonder about is the role of "static." In the help file it is stated that anything "static" is automatically global. I think this is true but haven't checked it.

So my basic advice is to get rid of all "extern" in your code, prototype, and yes, definitely break up your code into different functions.

Good luck,

Smile Robert
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