Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Accessing RAM using sdcc on 18F14k50

Status
Not open for further replies.

Rusttree

Member
I'm struggling to wrap my head around RAM access using sdcc. Specifically, I'm trying to read the values of BD0STAT, BD0CNT, BD0ADRL, and BD0ADRH, which are the first 4 bytes of Bank 2 in RAM when the USB module is activated. They are located at addresses 0x200, 201, 202, and 203, respectively.

To try to understand how sdcc handles data memory, I compiled a program in sdcc with the following global variables defined:
Code:
int foo = 0x12;
int goo = 0x13;
and found the corresponding lines in the asm file:
Code:
	idata
_foo	db	0x12, 0x00
_goo	db	0x13, 0x00
I gather the 0x00 is the bank in RAM the value is stored, but no address or offset is specified. How does the uC know exactly where foo and goo are in bank 0? And back to my original question, what if I know the exact address in RAM (e.g., 0x200) and I want to access the contents of that address?

Thanks,
Dan
 
What you describe is correct and the way all C compilers work. The variable foo is a 16 bit variable that the compiler can place anywhere. It's value is 0x0012 and it goes in two 8 bit locations, hence db 0x12,0x00. Had you typed int foo = 0x1234 then it would be db 0x34,0x12.

I've not used the sdcc compiler (I will have a look soon) but assume it sticks to the convention of normal C (CONSTANTS = uppercase, variables = lowercase). So, BD0STAT is a constant and has the value 0x200 and the variable bd0stat is located at that address. So var=bd0stat should return the contents of location 0x200. However, C18 doesn't stick to this convention and so I could be wrong.

Mike.
 
Ok, so after the compiler writes "_foo db 0x12, 0x00" into the assembly file, how does the processor know which address in RAM to retrieve that value later on? Is that a transparent step that is done when the assembly code is compiled down to machine code?

Part of the problem I'm having is the header file that comes with sdcc for my PIC doesn't define the BD0STAT register (or the others I mentioned above). I figure I can copy the code for another register that is defined, but there's still something confusing me. If I simply state the absolute address, say 0x200, how does the compiler know if I mean RAM, program memory, or EEPROM? Obviously there exists a unique address 0x200 in each of those memory spaces.

Here's an example of a random register definition I picked out of my pic18f14k50.h file:
extern __sfr __at (0xFBE) CCPR1;

In this case, it just states 0xFBE as the address. How does it know which memory space? When I try to trace that register in the assembly code (created by sdcc from C code), nothing screams out to me: "Define an 8-bit value called CCPR1 at 0xFBE in RAM!" There's clearly an intermediate step between the assembly code and the machine code that I'm missing.
 
In the boostC header files registers are defined as,

#define CCPR1 0x00000FBE

And then the variable ccpr1 is defined as

volatile char ccpr1 @CCPR1;

The @ symbol tells the compiler to place it at 0xfbe as that is the value of CCPR1.

It looks like the sdcc compiler uses a different convention. My guess would be something like,
Code:
struct BD{
    unsigned char STAT;
    unsigned char CNT; 
    unsigned char ADRL;
    unsigned char ADRH;
};

struct BD bd0 __at 0x200;

//and access it as
    var=bd0.CNT;

You could also do,
Code:
unsigned char BD0STAT __at 0x200;
unsigned char BD0CNT __at 0x201; 
unsigned char BD0ADRL __at 0x202;
unsigned char BD0ADRH __at 0x203;

As for how it knows where to place everything, CONSTANTS go in ROM and variables in RAM. Normally.

Mike.
 
Alright, thanks Mike. I think I'm finally starting to get a handle on the memory management concepts I need.

I was able to successfully instantiate the registers I described above with the following code for the sdcc compiler:
Code:
unsigned char __at (0x200) BD0STAT_OUT;
typedef union {
	struct {
		unsigned BC8    	: 1;
		unsigned BC9    	: 1;
		unsigned BSTALL   	: 1;
		unsigned DTSEN  	: 1;
		unsigned UNIMP1         : 1;
		unsigned UNIMP2       	: 1;
		unsigned DTS          	: 1;
		unsigned UOWN          	: 1;
	};
} __BD0STATbits_t;
volatile __BD0STATbits_t __at (0x200) BD0STAT_OUTbits;

unsigned char __at (0x201) BD0CNT_OUT;
unsigned char __at (0x202) BD0ADRL_OUT;
unsigned char __at (0x203) BD0ADRH_OUT;

I have a few USB-specific questions now, but they're off topic to this thread, so I'll create a new post.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top