- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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'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 CONTENTS8 .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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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're making progress! Regards, --Scott- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page