Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

Disable HAL to reduce memory footprint?

Hello NIOS friends,

I am working on a system that requires the time-critical DMA transfer of massive amounts of data between SDRAM and a custom peripheral. I don't want the instruction or data master of the the NIOS to access the SDRAM bus during these transfers. An idea I got from this forum a while ago is to change the bus arbitration priority in the SOPC builder, so I will have a guaranteed amount of bus cycles against each NIOS cycle. This worked well when the peripheral was reading from SDRAM, but if I do the same thing for writing to SDRAM (with a second DMA controller) the NIOS hangs... Another idea was to let the NIOS spin around in a small subroutine in an on-chip SRAM until the DMA transfer is done and than gain control over the SDRAM bus again. To achieve that, I defined a small (2Kbyte) on-chip RAM and I wanted to store a small (maybe even written in assembly) polling loop in that area. I hoped the linker would be smart enough to handle the definition:

void useless_routine(void) __attribute__ ((section (“.cache”)));

where "cache" is the on-chip RAM block.

But it keeps generating error messages that I am using overlapping memory sections.

OK, then I just made a new project in the IDE, defined all the pointers to point at the on-chip RAM, but the HAL simply makes the footprint to big; even with everything switched off (small footprint, no exit-check etc...)

So: is there a way to park my small subroutine in on-chip RAM using my main program (which is copied from EPCS4 to SDRAM at power up) by somehow telling the linker to do so? Or is it wise to start writing a HAL independend program in assembly?

Truely sorry about the long story. But if you've made it so far, you might be interested enough to come up with a bright idea. Thanks a lot.

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Arjan,

    > void useless_routine(void) __attribute__ ((section (“.cache”)));

    This is fine.

    > But it keeps generating error messages that I am using overlapping

    > memory sections.

    Please provide more detail -- please post the info that squirts out with the

    error.

    > So: is there a way to park my small subroutine in on-chip RAM using my main

    > program (which is copied from EPCS4 to SDRAM at power up) by somehow telling

    > the linker to do so?

    You're already doing it ... based on your example, you must have an on chip memory

    block named "cache". Take a look at your generated.x linker file -- the input section

    name you put in your C code, section (“.cache”), must match the name of an output

    section ... otherwise it'll be dumped into .text (see example below).

    > Or is it wise to start writing a HAL independend program in assembly?

    It's only wise if you really need to do this to meet your requirements. Otherwise,

    why reinvent the wheel? ... stick with the HAL. Your idea to jump to a small bit of

    polling code in on chip memory (leaving the bulk of your code in SDRAM) sounds

    fine.

    > you might be interested enough to come up with a bright idea

    Your idea is fine ... and you're almost there ... don't give up :-) Here's an example.

    There is an on chip memory named "ocm" in SOPCBuider. All code is placed in

    SDRAM ... except for the routine "foo":

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    #define POLLADDR 0x10000000# define XFER_DONE 0x01

    <span style="color:green">int foo (void) __attribute__((section (".ocm")));

    int foo (void)

    {

    volatile unsigned char *p = (volatile unsigned char *)POLLADDR;

    while ((*p & XFER_DONE) == 0)

    ;

    return (0);

    }

    int main()

    {

    foo ();

    return 0;

    }

    </span>[/b]

    --- Quote End ---

    Here&#39;s the objdump, you can see that .ocm is populated:

    <div class='quotetop'>QUOTE </div>

    --- Quote Start ---

    Idx Name Size VMA LMA File off Algn

    0 .entry 00000000 01000800 01000800 00009158 2**5

    CONTENTS, ALLOC, LOAD, READONLY, CODE

    1 .exceptions 000001a8 00000020 00000020 000000b4 2**2

    CONTENTS, ALLOC, LOAD, READONLY, CODE

    2 .text 00007110 000001c8 000001c8 0000025c 2**2

    CONTENTS, ALLOC, LOAD, READONLY, CODE

    3 .rodata 00000090 000072d8 000072d8 0000736c 2**2

    CONTENTS, ALLOC, LOAD, READONLY, DATA

    4 .rwdata 00001d5c 00007368 00007368 000073fc 2**2

    CONTENTS, ALLOC, LOAD, DATA, SMALL_DATA

    5 .bss 00000214 000090c4 000090c4 00009158 2**2

    ALLOC, SMALL_DATA

    6 .sdram 00000000 000092d8 000092d8 000091a0 2**0

    CONTENTS

    7 .epcs_controller 00000000 01000820 01000820 000091a0 2**0

    CONTENTS

    8 .ocm 00000048 03001000 03001000 00009158 2**2

    contents, alloc, load, readonly, code

    9 .avl_slave 00000000 04000000 04000000 000091a0 2**0

    CONTENTS

    10 .flash 00000000 0f000000 0f000000 000091a0 2**0

    CONTENTS

    11 .comment 00000891 00000000 00000000 000091a0 2**0

    CONTENTS, READONLY[/b]

    --- Quote End ---

    I hope this helps.

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thanks Scott, good to hear that I am on track. I needed the confirmation only a Nios God can give me... The only thing I added is a seperate section for code (local_ram.txt) and data (local_ram.rwdata). That fixed the linker error-message of overlapping memory blocks. But the load on the Avalon bus is still too high, even with the Nios running in on-chip RAM, so I will define some tightly coupled memory to offload the Avalon bus completely.

    Thanks again for the help.

    Arjan
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi Arjan,

    > But the load on the Avalon bus is still too high, even with the Nios running in

    > on-chip RAM

    Keep in mind that internally, the DMA master and the cpu masters do not share a

    "common" bus per-se, but are rather muxed at the slave (under control of the

    avalon arbitration logic). That is, cpu access to the on chip ram does not interact

    with dma master access to the sdram. The only time they "interact" is when they

    are attempting to simultaneously access the same slave. Perhaps some of the

    avalon gurus could comment on this.

    If your cpu is running from on chip ram, it should not be accessing the sdram at all.

    Unless ... interrupts are enabled and being handled by exception code that is located

    in the sdram.

    Glad to hear you&#39;re making progress!

    Regards,

    --Scott
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Yeah, it works. Timing is excellent now, you were right. I forgot the 1ms system timer that I left (I thought dorment) in the SOPC builder, but the HAL picked up on it. It linked a nice little interrupt handler (located in SDRAM) that screwed up my carefully planned timing. After deleting that it was exactly as it should be: with SDRAM running close to 100% efficiency.

    Arjan