From: Lawrence J. <law...@jt...> - 2002-05-30 20:18:30
|
This is possibly more of a programming question than an SDCC question, but I'm not sure, so I'll start here: With sdcc created libraries that use global variables, such as circular buffers for serial ports, presumably the variables must be declared global in the library source, or the source of one of the library functions. These same variables must be declared as extern ... in every other place they're used, such as an application that may need access. I mentioned serial ports above because that's what I'm currently fiddling around with on an AT89C2051. The serial port functions are based on those of Wolfgang Esslinger, as mentioned in the sdcc manual. My first question, is that in looking into the contents of _ser.c, there is a bit variable: static bit ser_txBusy; This is declared outside of any function, hence it is global, I think. If this is the case, my question is: Why? I looked through some old programming documentation on storage classes and it isn't ever stated that you can't do this, but this may be because nobody would ever want to, unless there's a reason I don't see. When I was trying to link in functions from a library based on _ser.c, I kept getting this stubborn warning about ser_txBusy being declared as global and not being defined anywhere, even if I put the declaration as a global in my application (meaning right above main). After a while, I started to question why this needs to be static, so I changed the declaration to simply read: bit ser_txBusy; ...and it now compiles, well sort of. The next problem that cropped might be related to sdcc. The block of variables is as follows: unsigned char ser_txIndexIn; unsigned char ser_txIndexOut; unsigned char ser_rxIndexIn; unsigned char ser_rxIndexOut; unsigned char ser_txBuffer[TXBUF]; unsigned char ser_rxBuffer[RXBUF]; static bit ser_txBusy; What I did, initially, was create discrete functions one per file, with the file names identical to the functions. (John McClintock: I was already well into this before you responded to my post of yesterday, so it was too late to turn back.) In each file, I declared the above block as: extern unsigned char ser_txIndexIn; extern unsigned char ser_txIndexOut; extern unsigned char ser_rxIndexIn; extern unsigned char ser_rxIndexOut; extern unsigned char ser_txBuffer[TXBUF]; extern unsigned char ser_rxBuffer[RXBUF]; extern static bit ser_txBusy; ...in all files except for ser_init.c, which obviously is the initialisation routine. In that file, I declared without extern. When I tried to then compile a program with only the initialisation routine and interrupt handler, I would get a "Multiple definition of _ser_rxBuffer" followed by a crash. It strikes me as a little strange that it wouldn't complain about any of the other variables. I checked and rechecked this because I couldn't see where the error was coming from. Eventually, I changed the above block of variables to all be extern in all functions and placed a global declaration in the header file for the would-be library. The global declaration was wrapped within: #ifndef _SERLIB #define _SERLIB <global variables go here> #endif and the compile step had a -D_SERLIB on it for building the library. I, of course, don't put the -D_SERLIB on the command-line for building the application, so the block gets declared there. Why didn't the global declaration in ser_init.c work? Should it have worked at all? This would have been much simpler in my books, and since you can't do anything without the initialisation step, you must end up declaring the global variables there, but not so. ______________________________________________________ Lawrence Johnson J-Tech Engineering Ltd 1050 Quadling Avenue Coquitlam BC Canada V3K 2B2 Tel 604 936 7468 Fax 604 936 7426 Cel 604 802 7579 http://www.jtecheng.com |