| Details | Message |
|---|
Read-Only Author Sven Petersen Posted 5-Feb-2002 17:11 GMT Toolset C51 |  Optimizing problems (volatile hardware register) Sven Petersen I have had a rather ugly problem caused due to the optimization.
I am reading data from a fifo. The read port is at address 0x8200 (read only access). It also has a read reset port. Its address is also 0x8200 (both xdata) (write onle access).
When I declare the varables for accessing the fifo like this:
xdata uchar fifo_data _at_ 0x8200; xdata uchar fifo_rres _at_ 0x8200;
It will result in a linker warning memory overlap. Thus I have decided to do it like this:
xdata uchar fifo_data _at_ 0x8200;
#define fifo_rres fifo_data
In a routine I have programmed this code:
fifo_rres = 0xff; // reset fifo read
jpg_adr = 1; // set jpg file address to the next address to be read
fbuf_start = 0; // set buffer start pointer to zero
fbuf_in = 1; // set buffer input pointer to next free byte in buffer
fbuf_pos = 0; // set buffer read pointer to zero
fbuf_startadr = 0; // set buffer startadress to zero
fbuf[0] = fifo_data; // read first byte from jpg file
The result was, that fbuf[0] was always 0xff. Then I have read the disassembly and found that when I want to set fbuf[0], I don't access the fifo read register, but it is written with 0xff.
I think, this is matter of the compiler optimization. The compiler thinks, that when I write 0xff into some address and read it some lines later, it will still be 0xff.
How can I tell the compiler, that it is not the same? I didn't find anything in my C51 manual about that topic. Maybe I just didn't find it. |
|
Read-Only Author erik malund Posted 5-Feb-2002 17:24 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) erik malund keyword: volatile
Have fun,
Erik |
|
Read-Only Author Scott deWolski Posted 5-Feb-2002 18:18 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) Scott deWolski To flesh out a bit;
volatile xdata uchar fifo_data _at_ 0x8200;
#define fifo_rres fifo_data
The keyword 'volatile' tells the compiler to not optimize accesses to a variable, assuming it can be changed by some other, unknown, means. It should be used anytime a variable is changed by a background function, hardware or in a different thread in multi-threaded systems. Best luck
|
|
Read-Only Author Sven Petersen Posted 6-Feb-2002 07:39 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) Sven Petersen Hi there,
thanks for the quick help. I had heard something about "volatile" before, but I couldn't find anything about it in my Keil books. After I got the reply, I have found it as a footnote in the Kernighan&Ritchie.
So what I have done is:
#define FIFO_READ_ADR 0x8200
[...]
xdata volatile uchar fifo_data _at_ FIFO_READ_ADR; // fifo data register (read only)
#define fifo_rres fifo_data
And voila (or should I say volatile), it works. |
|
Read-Only Author Andrew Neil Posted 5-Feb-2002 20:24 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) Andrew Neil
xdata uchar fifo_data _at_ 0x8200;
xdata uchar fifo_rres _at_ 0x8200;
As far as the 'C' language is concerned, these are two separate definitions creating 2 distinct variables - so you will obviously get the Linker warning!
An alternative might be to use a Union - not sure how that might affect the efficiency of access, though?
Other options would be to do it in Assembler, or leave it to the Linker.
|
|
Read-Only Author erik malund Posted 5-Feb-2002 21:48 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) erik malund what about
xdata uchar fifo_data _at_ 0x8200;
#define fifo_rres fifo_data
Erik
|
|
Read-Only Author Norbert Paul Posted 6-Feb-2002 08:29 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) Norbert Paul Just a suggestion:
File fifoin.c:
xdata uchar fifo_data _at_ 0x8200;
File fifoin.h:
extern xdata uchar fifo_data;
#define fifo_rres XBYTE[0x8200]
File the_file_i_use_the_fifo_stuff.c:
#include <absacc.h>
#include "fifoin.h"
/* now fifo_data and fifo_rres are */
/*competely different to the Compiler*/
I know, this is too complicated and -yuck- it's ugly style, but as a starting point for further ideas it may do.
Good Luck
Norbert |
|
Read-Only Author Norbert Paul Posted 6-Feb-2002 08:56 GMT Toolset C51 |  ashamed :( Norbert Paul I'd like to cancel my prevoius message. |
|
Read-Only Author Jon Ward Posted 6-Feb-2002 18:28 GMT Toolset C51 |  RE: Optimizing problems (volatile hardware register) Jon Ward If you're hell-bent on having 2 variables at the same address, there is an easy way to handle it.
1. In your C code, create external definitions. For example:
extern unsigned char xdata var1;
extern unsigned char xdata var2;
2. Create an assembler module that appears as follows:
xseg at 0x8000
public var1
public var2
var1:
var2: DS 1
end
This declares var1 and var2 at XDATA address 0x8000. Each is 1 byte long. If these variables are 16-bit vars, change the DS 1 to DS 2.
Jon |
|