We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
You'll have to be more specific than just stating "it does not work" before anyone can give you meaningful help. How exactly does it fail to work?
We first tested memcpy from a source to a destination buffer in the far memory space. This works, even across a 64kb boundary. When we set the source start address to 0xFFDBF7 which should be the physical location of a CAN peripheral the copy action is not performed at runtime. Copying however works when instead of using pointers we use individual _at_ variables. This is however not an efficient solution. I suspect that 0xFFDBF7 is not a valid far address, and it seems to me that remapping of the corresponding registers is the only solution. Does this make sense? best regards, Raoul
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.....
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?