Discussion Forum

Optimizing problems (volatile hardware register)

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
Sven Petersen
Posted
5-Feb-2002 17:11 GMT
Toolset
C51
New! Optimizing problems (volatile hardware register)
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
New! RE: Optimizing problems (volatile hardware register)
keyword: volatile

Have fun,

Erik
Read-Only
Author
Scott deWolski
Posted
5-Feb-2002 18:18 GMT
Toolset
C51
New! RE: Optimizing problems (volatile hardware register)
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
New! RE: Optimizing problems (volatile hardware register)
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
New! RE: Optimizing problems (volatile hardware register)
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
New! RE: Optimizing problems (volatile hardware register)
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
New! RE: Optimizing problems (volatile hardware register)
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
New! ashamed :(
I'd like to cancel my prevoius message.
Read-Only
Author
Jon Ward
Posted
6-Feb-2002 18:28 GMT
Toolset
C51
New! RE: Optimizing problems (volatile hardware register)
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

Next Thread | Thread List | Previous Thread Start a Thread | Settings