I can't copy data from RAM to RPAGE RAM with memcpy.

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I can't copy data from RAM to RPAGE RAM with memcpy.

Jump to solution
1,372 Views
j_y_
Contributor I

I can't copy data from RAM to RPAGE RAM with memcpy function.

 

Definition:

#pragma DATA_SEG __GPAGE_SEG GRAM_25K

unsigned char large_buff[LARGE_BUFF_LEN];

#pragma DATA_SEG DEFAULT

 

 

Worked:

  do {

    large_buff[cnt] = src[cnt];

    cnt++;

  } while(size != cnt);

 

Not worked:

    memcpy((unsigned char * )(int)large_buff, src, cnt);

 

I want to copy data faster now.

Labels (1)
0 Kudos
1 Solution
871 Views
kef
Specialist I

Hi

In banked and small memory models all data assumed being near, so memcpy works only for near data (CPU 16bit address space). In large memory model all data is far and memcpy would work for you.

Your copy code should be pretty fast. The only major overhead is compiler generated code to set up GPAGE register on each loop iteration. But you most likely can't remove it from the loop without reworking your copy routine in assembler.

This memcpy should work copying data to and from far data:

void farmemcpy(void * far dest, const void * far src, size_t len)
{
      char * far d = dest;
const char * far s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

For more speed in C you can do separate routines for copy to and from far memory. Removing "far" from src or dest should speed up copying a bit.

void toGmemcpy(void * far dest, const void * src, size_t len)
{
      char * far d = dest;
const char *     s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

void fromGmemcpy(void * dest, const void * far src, size_t len)
{
      char *     d = dest;
const char * far s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

View solution in original post

0 Kudos
3 Replies
871 Views
CrasyCat
Specialist III

Hello

There are 2 problems in your code snippet.

  1- If large_buf is located in banked memory you need to use a far pointer to access it.

      So you should modify the call to memcpy as follows>

          memcpy(large_buff, src, cnt);

  2- You need to make sure the library function memcpy uses far pointers  as parameters.

When you are building in BANKED memory model, memcpy assumes per default, that all pointer are 16-bit wide.

If you need to pass 24-bit pointer to memcpy, you need to rebuild an ansi library supporting 24-bit pointer to char.

This is done as follows:

  • Open the  project {Install}\lib\hc12c\hc12_lib.mcp
  • Open the file libdefs.h in an edit window
  • In this file set the macros LIBDEF_FAR_CONST_STRINGS, LIBDEF_FAR_STRINGS, LIBDEF_FAR_CONST_VOID_PTR, LIBDEF_FAR_VOID_PTR and LIBDEF_FAR_CONSTANTS to 1.
  • Inside of hc12_lib.mcp window go to the target tab select the appropriate target and build it. The target you need to select depends on the compilation options you are using in your project.  Check {Install}\lib\hc12c\readme.txr for more information on the available targets. Alternatively you can define a brand new target, change its name and link the newly created library file to your application.
  • Now build the application and run it. It should work better.

CrasyCat


871 Views
kef
Specialist I

Though it is possible to recompile libraries, I think it is not a good idea to enable far strings in default library. Other projects, that don't need far strings may suffer from reduced execution speed. It may be better to create library with new name and use it instead. Or add required source files to project and change link order so that modified copy is linked instead of code from library. This way it won't affect other projects.

872 Views
kef
Specialist I

Hi

In banked and small memory models all data assumed being near, so memcpy works only for near data (CPU 16bit address space). In large memory model all data is far and memcpy would work for you.

Your copy code should be pretty fast. The only major overhead is compiler generated code to set up GPAGE register on each loop iteration. But you most likely can't remove it from the loop without reworking your copy routine in assembler.

This memcpy should work copying data to and from far data:

void farmemcpy(void * far dest, const void * far src, size_t len)
{
      char * far d = dest;
const char * far s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

For more speed in C you can do separate routines for copy to and from far memory. Removing "far" from src or dest should speed up copying a bit.

void toGmemcpy(void * far dest, const void * src, size_t len)
{
      char * far d = dest;
const char *     s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

void fromGmemcpy(void * dest, const void * far src, size_t len)
{
      char *     d = dest;
const char * far s = src;

  while(len--)
  {
      *d++ = *s++;
  }
}

0 Kudos