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

efficient memcpy of far registers

Dear colleagues,

we are using the TINI DS80C400 platform and the KEIL PK51 development tools.
We would like to perform a fast memcpy of some physical CAN registers located in far memory to a buffer also located in far memory.

We use the following code lines:

#pragma moddp2
#include "absacc.h"

unsigned char far *SrcPtr;
unsigned char far *DestPtr;

SrcPtr = &FVAR(unsigned char, 0xFFDBF7);
/* physical register COM15D0 */
/* or alternatively: SrcPtr = (void far*)0xFFDBF7; */
DestPtr = ...;

memcpy(DestPtr, SrcPtr, 8);
/* should copy 8 bytes */

But it does not work!
What's wrong here?

Thanks for any hint.

Raoul

Parents
  • A good, solid look at the "Pointer Conversions" and "Storage Formats" sections of the C51 manual confirms your suspicions quite nicely. In a nutshell, a generic pointer with the most significant byte equal to 0xff is interpreteted as a pointer to CODE memory, not XDATA.

    Other than writing yourself a function fmemcpy() that takes arguments of type void far *, there's not much that could be done about this, either: it's built into the very concept of generic pointer support, as designed by Keil.

    You have still two other options:

    1) direct moves through far pointers

    2) re-configuration of the CAN part to move it to a different address than the problematic 0xff.....

Reply
  • A good, solid look at the "Pointer Conversions" and "Storage Formats" sections of the C51 manual confirms your suspicions quite nicely. In a nutshell, a generic pointer with the most significant byte equal to 0xff is interpreteted as a pointer to CODE memory, not XDATA.

    Other than writing yourself a function fmemcpy() that takes arguments of type void far *, there's not much that could be done about this, either: it's built into the very concept of generic pointer support, as designed by Keil.

    You have still two other options:

    1) direct moves through far pointers

    2) re-configuration of the CAN part to move it to a different address than the problematic 0xff.....

Children
  • The real problem can be boiled down to this.

    A generic pointer (3-bytes) can address only 16 megabytes of stuff. Using the Keil tools, you can only address 8 megabytes of CPDE and 8 megabytes of XDATA.

    The Dallas 390 and compatible parts have 16 megabytes of CODE and 16 megabytes of XDATA address space.

    To access the CAN register at FF????h you just have to re-map this address range to something in the Keil XDATA address space (02????h-7F????h). These modifications are made in the XBANKING file.

    To map the CAN register to the address range 55????h, all you need to do is modify the far variable access routines in XBANKING to look for 55 in the HI address byte. If found, change it to FF and do the MOVX instruction as normal.

    Jon

  • But would XBANKING.C even be involved at all, for a Dallas 390? In contiguous mode?