This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems with linked list and xdata

I'm having a problem getting a linked list to work on Keil. I'm using an aduc842 microcontroller from Analog. Linked lists are something we do all the time in c and i'm baffled as to why i cant get it to work in this situation. This code works in the simulator but doesnt work on the actual hardware. Ive got 2k on chip xdata and it's configured as such. Ive tried using void * as well for the link node, which increases the size of the struct by one byte, and that didnt work either.

#include <ADuC842.h>
sbit led = 0xb4;
unsigned char xdata Store[1024] ;
unsigned char xdata * pStore ;
void xdata *  FetchMem ( unsigned int bytes ) {
	unsigned char xdata * ppStore ;
	ppStore = pStore ;
	pStore += bytes ;
	return ppStore ;
}

xdata struct Example {
	unsigned char a ;
	struct Example xdata * Next ;
} ;
struct Example xdata List ;
struct Example xdata * pList ;
int main (void ){
	unsigned char i ;
	FetchMem(1);
	pList=&List ;
	pList->a='a'; pList->Next = 0 ;
	{
		struct Example xdata * rec ;
		rec=FetchMem(sizeof(struct Example));
		rec->a='b'; rec->Next=0;
		pList->Next=rec; pList=rec;}
	{
		struct Example xdata * rec ;
		rec=FetchMem(sizeof(struct Example));
		rec->a='c'; rec->Next=0;
		pList->Next=rec; pList=rec;
	}
	{
		struct Example xdata * rec ;
		rec=FetchMem(sizeof(struct Example));
		rec->a='d'; rec->Next=0;
		pList->Next=rec; pList=rec;
	}
	pList=&List;
	for(;;){
		i=pList->a;
		if(pList->Next==0)break;
		pList=pList->Next;
	}
	led=!led;
	for(;;){}
}

  • Linked lists are something we do all the time in c and i'm baffled as to why i cant get it to work in this situation
    Because "the '51 aint no PC". What you "do all the time in c" may and may not fit the '51 architecture.

    sure, you can "get it to work" but that does not make it right. If you just took one small peek at the code, the use of linked lists, generate with the '51 architecture you would immediately stop using the combination.

    If you have to violate the poor little controller, go ahead and fix/have fixed your code, but why do you have to ignore what you are working with.

    Erik

  • Because "the '51 aint no PC". What you "do all the time in c" may and may not fit the '51 architecture.

    sure, you can "get it to work" but that does not make it right. If you just took one small peek at the code, the use of linked lists, generate with the '51 architecture you would immediately stop using the combination.


    Ive put a lot of thought into my design. Using a few linked lists in xdata is actually the most efficient use of memory in my situation. Yes, even on the little ol' 51'. And no, i'm not using malloc, and yes i'm quite aware of the difference between the '51 and ia32.

    So my problem is that i can assign the next pointer to point to another structure, but when i follow it, it takes me off into the weeds. The code works fine in the simulator, but it doesnt work on the actual hardware. I have 64k of memory on the real hardware. The size of the pointer to the struct is 2 bytes. Ive verified that i can read and write bytes in xdata and that memory settings are correct. Ive been at this for days, i'm frustrated beyond beleif.

  • I have not studied the code, but one think that jumped out right away was that pStore is not explicitly initialized.

  • I have not studied the code, but one think that jumped out right away was that pStore is not explicitly initialized.

    Good catch. I forgot to include that line in this sample program. Still didnt fix the problem though ):

  • What does your program do or not do? You said it doesn't work, but didn't say how.

    Check memory initialization (and existence!) The simulator will init memory differently from real hardware.

    You should also be aware that the 8051 has many different address spaces (data, idata, xdata, etc). C assumes there's only one. C51 supports pointer types of varying sizes depending on where they point. There's also a "tagged" or "generic" pointer type that can point to any memory space, which carries an extra tag byte to denote where it points. (This is why your void* is one byte larger than your xdata*. An xdata* takes up 2 bytes and points into the 16-bit xdata address space. A generic void* might point anywhere, not just xdata.)

    As a result, "the" null pointer value is a bit tricky. There are actually many null pointer values. And they aren't necessarily "0". (C++ specifies that you can write the null pointer value name with the string "0". ANSI C never said so, hence the proliferation of #define NULL as ((void*)0) or ((size_t*)0L) or whatever.)

  • The datasheet shows that registers must be configured properly for accessing internal XRAM. Is this being done in your startup file?

  • Sorry, I see now where you said it is being configured (hopefully correctly).

  • This code works in the simulator but doesnt work on the actual hardware.

    Are you using different memory models (small/compact/large) on the simulator and on the actual hardware ?

    Also, be aware that for pointers, it might be necessary to specify _two_ memory areas - one indicating where the pointer points, and one where the pointer is located.

    For example:

    unsigned char xdata * someptr;
    

    is pointer to a location in xdata, but the pointer itself is located in the memory are specified by the memory model.


    unsigned char xdata * xdata someptr;
    

    would be a pointer to a location in xdata, and the pointer itself is located in xdata, too.

  • This code works in the simulator but doesnt work on the actual hardware.

    What exactly "doesn't work" ? Up to which line does the program what you expect it to do, and what is different from your expectations after that line ?

  • Ive got 2k on chip xdata and it's configured as such.

    So you have

    1. checked "Use on-chip XRAM" in the Options->Target dialog window.

    and

    2. checked "XRAMEN: Enable on-chip XDATA RAM" in the configuration wizard dialog of START_AD.A51 under Setupt Extended Data RAM.

    and

    3. initialized (zeroed) 0x800 bytes of XDATA memory, also in the configuration wizard ?