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

how do I implement an overplapped execution area?

Hi, I have an application with von neumann memory. I have hardware support to load this memory from a serial flash. I would like to be able to load function sets to a specific location in this memory and run them. To that end I have downloaded the C51: IN-SYSTEM FLASH PROGRAMMING (PART 2) example and it runs OK. I then modified this by adding another function set identical to the first pflash one. How do I get the tools to overlap the execution area for the two sets?

These are the LX51 locate user class settings:
This does not work and I would like it to:
SROM ( C:0x1000-C:0x1FFF),
CODE_FLASHMEM(C:0x2000-C:0x2020) [ ],
CODE_FLASHMEM1(C:0x2000-C:0x2020) [ ],

This does work:
SROM ( C:0x1000-C:0x1FFF),
CODE_FLASHMEM(C:0x2000-C:0x2020) [ ],
CODE_FLASHMEM1(C:0x2000-C:0x2040) [ ],

I attach the files I modified from the example.
This is the srom.c file

#include <string.h>
#include <intrins.h>
#include  "srom.h"               // SROM Handling definitions
extern void flash ( void );     // first function to be executed in RAM.
extern void flash1 ( void );     // first function to be executed in RAM.

SROM_MC (CODE_FLASHMEM)         // define SROM program segment
SROM_MC (CODE_FLASHMEM1)         // define SROM program segment
/*------------------------------------------------
The main C function.
------------------------------------------------*/
void main (void)  {
memcpy (SROM_MC_TRG(CODE_FLASHMEM),     // copy flash function from ROM to RAM
         SROM_MC_SRC(CODE_FLASHMEM),
          SROM_MC_LEN(CODE_FLASHMEM));
flash();                               // calls flash function in RAM
memcpy (SROM_MC_TRG(CODE_FLASHMEM1),     // copy flash function from ROM to RAM
         SROM_MC_SRC(CODE_FLASHMEM1),
          SROM_MC_LEN(CODE_FLASHMEM1));
flash1();                               // calls flash function in RAM
while (1);
}

This is the srom.c file


#include <string.h>
#include <intrins.h>
#include "srom.h" // SROM Handling definitions
extern void flash ( void ); // first function to be executed in RAM.
extern void flash1 ( void ); // first function to be executed in RAM. SROM_MC (CODE_FLASHMEM) // define SROM program segment
SROM_MC (CODE_FLASHMEM1) // define SROM program segment
/*------------------------------------------------
The main C function.
------------------------------------------------*/
void main (void) {
memcpy (SROM_MC_TRG(CODE_FLASHMEM), // copy flash function from ROM to RAM SROM_MC_SRC(CODE_FLASHMEM), SROM_MC_LEN(CODE_FLASHMEM));
flash(); // calls flash function in RAM
memcpy (SROM_MC_TRG(CODE_FLASHMEM1), // copy flash function from ROM to RAM SROM_MC_SRC(CODE_FLASHMEM1), SROM_MC_LEN(CODE_FLASHMEM1));
flash1(); // calls flash function in RAM
while (1);
}


This is the pflash1.c file which needs to be added to the example project.

#include <intrins.h>
#pragma USERCLASS(CODE = FLASHMEM1)      // user class CODE_FLASHMEM
/*------------------------------------------------
Module stored in ROM and will be executed in RAM.
----------------------------------------------*/
/*------------------------------------------------
Delay function FUN
------------------------------------------------*/
void delay1 ( unsigned int i )
{
while (i--);
}
/*------------------------------------------------
This function should handle your Flash Memory FUN
------------------------------------------------*/
void flash1 ( void )
{
unsigned int i= 0x0FFF;
  delay1(i);
  _nop_();
}


This is the other file in the project. Pflash.c which is unmodified from the example.

/*------------------------------------------------------------------------------
PFLASH.C
Copyright 1995-2002 Keil Software, Inc.
------------------------------------------------------------------------------*/
#include <intrins.h>
#pragma USERCLASS(CODE = FLASHMEM)      // user class CODE_FLASHMEM
/*------------------------------------------------
Module stored in ROM and will be executed in RAM.
------------------------------------------------*/
/*------------------------------------------------
Delay function
------------------------------------------------*/
void delay ( unsigned int i )
{
while (i--);
}
/*------------------------------------------------
This function should handle your Flash Memory
------------------------------------------------*/
void flash ( void )
{
unsigned int i= 0xFFFF;
  delay(i);
  _nop_();
}

Thanks for any help!

  • When you use this linker configuration:

    SROM ( C:0x1000-C:0x1FFF),
    CODE_FLASHMEM(C:0x2000-C:0x2020) [ ],
    CODE_FLASHMEM1(C:0x2000-C:0x2040) [ ],
    

    Where does the linker locate flash and flash1 in the RAM? I'm assuming that flash starts at 0x2000 and flash1 starts after flash.

    Jon

  • Yes, one is after the other. The other setting it wont build. They take each about 0x20 bytes code space. I want them to both be at the same execution spot since that part of code space will have only either flash in it or flash1 in it at any given time.

    Thanks

  • What error do you get from the linker?

    Jon

  • I set it to the smallest execution space it could be,
    e.g.
    this works
    CODE_FLASHMEM(C:0x2000-C:0x2013) [ ] ,
    CODE_FLASHMEM1(C:0x2014-C:0x2027) [ ]

    This
    CODE_FLASHMEM(C:0x2000-C:0x2013) [ ] ,
    CODE_FLASHMEM1(C:0x2000-C:0x2013) [ ]
    generates these errors:

    *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: CODE SEGMENT: ?PR?_DELAY1?PFLASH1 LENGTH: 00000BH
    *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: CODE SEGMENT: ?PR?FLASH1?PFLASH1 LENGTH: 000009H
    *** ERROR L121: IMPROPER FIXUP MODULE: Srom.obj (SROM) SEGMENT: ?PR?MAIN?SROM OFFSET: 00002AH
    *** ERROR L120: CONTENT BELONGS TO ERRONEOUS SEGMENT SEGMENT: ?PR?_DELAY1?PFLASH1
    *** ERROR L120: CONTENT BELONGS TO ERRONEOUS SEGMENT SEGMENT: ?PR?FLASH1?PFLASH1

    Thanks

  • So I looked at this some more and still need help. found that if I add the following SEGMENT calls
    ?PR?*?PFLASH1 () [!],
    ?PR?*?PFLASH () [!]
    then the flash map marks all the functions from flash and flash1 like this:

    "
    *** '?PR?FLASH1?PFLASH1' no space reserved for execution at: 00200FH
    "
    but I still cannot restrict the execution space from the use class definitions so that they overlap and both start at 0x2000. It always wants to set the code sequential.

    I did find one thing that worked for overlapped execution. Adding these SEGMENTS
    ?PR?FLASH?PFLASH1 (C:0x2000) [!],
    ?PR?FLASH1?PFLASH (C:0x2000) [!]
    In this case both functions simulated correctly but if you tried to single step through them it would try to single step through the function whose file was closest to the top of the project workspace window.

    However I cant seem to make this SEGMENTS type of approach work for all the functions in the files. e.g. the delay functions are not overlayed. I suppose I could map the delay functions like I did the flash functions above, but then I would be calling out the execution start of EACH function. This seems not right at best.

    If I try to set the user class calls like this:
    CODE_FLASHMEM1(C:0x2000-C:0x2020) [!] (which I hoped would indicate to the linker that it should not reserve the execution memory) I get a syntax error.

    How can I implement this type of functionality?
    Or is it possible. It seems like the fact that the linker can do this:
    ?PR?FLASH?PFLASH1 (C:0x2000) [!],
    ?PR?FLASH1?PFLASH (C:0x2000) [!]
    means it could do it also for the classes.

    Any help is appreciated.

  • Currently, only the segment definition allows you to specify that no memory is reserved (this is required for overlapping segments). The class definition does not support this.

    If you use segments, you may want to use the linker's RESERVE directive to block-off the section of memory you use for RAM execution.

    Source-level debugging is going to be problematic. In general, debuggers have a look-up table for each address range in the program. There is a one-to-one correlation between each address range and the source code. So, when it comes to debugging, the debugger will not be able to "know" what function is actually occupying the memory (since it is overlapped). It will most likely use the first source file it finds.

    Jon

  • OK thanks for the hint on RESERVE. Although it seems like my problem is more in line with getting the linker to not reserve the memory.

    Do you know if there a way to use the SEGMENTS directive to link several functions together in the manner that the CLASS directive did?

    I have tried this type approach:
    SEGMENTS (?PR?*?PFLASH1 (0x2000) [!])
    but this compiles bad code since all the functions execute at 0x2000.

    Anyway it does not seem like the tools support reusing code space except for at best one function at a time.

    Thanks