This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Section layout question (cgtools 5.2.10, 28x)



I wish to change the section layout in my F28335 project.

Right now I have two sections Section1 and Section2. They are defined in the linker command file as follows:

   Section1 : > RAML0
              START(_Section1_Start),
              END(  _Section1_End)

   Section2 : > MODDATAPAGE


where MODDATAPAGE is defined as

   MODDATAPAGE : origin = 0x00A000, length = 0x40


I.e., all locations inside Section2 belong to the same data page.

Now, I wish to make Section2 reside inside Section1, i.e., the addresses of all objects of Section2 should be between &Section1_Start and &Section1_End, and Section2 should still be a data page (64 words long and properly aligned).

How do I do that?

  • I assume what you care about is that all of Section2 goes into one data page, and not that it starts exactly at address 0x00A000.  

    So first I want to restate what you currently have, but a bit differently.

    Section1 {
       *(Section1)   /* all input sections named "Section1" */
    } > RAMLO, START(_Section1_Start), END(_Section1_End)
    
    Section2 {
       *(Section2)   /* all input sections named "Section2" */
    } > MODDATAPAGE
    

    I'll show two solutions.  The first one is simpler, but makes a presumption that is probably true, but possibly not true.

    First solution ... Presume the input sections named Section2 have the blocking flag set.  The .bss and .ebss sections from compiler generated code usually have this flag set.  Read about blocking in the C28x Assembly Language Tools book.  Just search for "blocking".  Briefly, if a section has this flag set, the assembler and linker will work together to make sure the input section will not cross a page boundary.  Or, if it is bigger than page, start on a page boundary.  Blocking is similar to alignment, but weaker.  If that is the case, then you can do this ...

    New_Output_Section {
       *(Section1)
       *(Section2)
    } > RAMLO, START(_Section1_Start), END(_Section1_End)
    

    If, for some reason, you cannot be assured of the blocking of the Section2 input sections, then you can do this ...

    New_Output_Section {
       *(Section1)
       . = align(64);
       *(Section2)
    } > RAMLO, START(_Section1_Start), END(_Section1_End)
    

    Because this is using alignment and not blocking, this restrains placement a bit more than you really need.  

    Thanks and regards,

    -George

  • Hello George,

    Thank you for your quick response.

    You wrote:

       I assume what you care about is that all of Section2 goes into one
       data page, and not that it starts exactly at address 0x00A000. 


    Yes, that's what I want. Both sections are filled with C variables using #pragma DATA_SECTION. The variables in Section2 are also accessed by assembly code that assumes they are all in the same data page.

       First solution ... Presume the input sections named Section2 have the
       blocking flag set.  The .bss and .ebss sections from compiler generated
       code usually have this flag set.  Read about blocking in the C28x
       Assembly Language Tools book.  Just search for "blocking".  Briefly, if
       a section has this flag set, the assembler and linker will work together
       to make sure the input section will not cross a page boundary.  Or, if
       it is bigger than page, start on a page boundary.  Blocking is similar
       to alignment, but weaker.  If that is the case, then you can do this ...

       New_Output_Section {
         *(Section1)
         *(Section2)
       } > RAMLO, START(_Section1_Start), END(_Section1_End)


       If, for some reason, you cannot be assured of the blocking of the
       Section2 input sections, then you can do this ...


    Indeed, I'm not sure what the blocking of Section2 is, as it is generated by the compiler (I don't use any other pragmas than DATA_SECTION for the variables in Section2).

    So I have decided to try your second suggestion:
      
       New_Output_Section {
          *(Section1)
          . = align(64);
          *(Section2)
       } > RAMLO, START(_Section1_Start), END(_Section1_End)

       Because this is using alignment and not blocking, this restrains
       placement a bit more than you really need. 

    This appears to make Section2 start at the beginning of a data page, which is what I want. The problem with this approach is, that Section2 may grow beyond the size of a data page as more variables are stuffed into Section2. This would happen without any notification by the linker and it would break the assembly code.

    So, what I believe to need in addition to alignment is a size restriction on Section2. Would that be possible?

    Thanks and regards,
    Johannes

  • I presume the definition of the data in Section2 is in one or more source files, and the code which operates on that data is in completely different source files.  And you want to avoid loading the DP (data pointer register) before every access to data from Section2.  You are doing that by insuring Section2 is aligned on a page boundary.  (Side note ... Blocking also solves this problem, and doesn't fragment memory as badly.)

    You are right to worry about what happens if Section2 data becomes bigger than a page.  In such a case, a page boundary within the Section2 data block is unavoidable.  

    There is no straightforward way to configure the linker to prevent an output section from growing beyond a certain size.  An indirect method is to allocate the section to a memory range that is constrained to the desired size.  But, as you have seen, that can cause other problems.

    I am having hard time coming up with a suggestion for you to try next.  Part of the difficulty relates to your need to define the _Section1_Start and _Section1_End symbols.  What is the purpose of those symbols?  What problem do they solve?  There might be another way to do it.

    Thanks and regards,

    -George

  • For certain reasons certain variables in our software are to be put into a memory range for which a read-write memory test has to be done cyclically. This memory range is Section1. For this test I need the start and the end address of Section1.

    Unfortunately, some of the variables of Section2 actually also have to belong to the tested memory range. (My fault to address that section issue that late). As I didn't want to change the assembly code that relies on all of Section2 being in the same data page I thought it might be easiest to make Section2 part of Section1.

    As it seems to be difficult to restrict the size of Section2, maybe on could put Section2 into a memory range of restricted size (as you suggest), for example at the end of RAML0 and place Section1 just in front of Section2 and run the memory test from START(Section1) to END(Section2)...

    Thanks and regards

    Johannes