Hi:
Does anyone know how to create heap on L1DSRAM without DSP/BOIS support?
Regards,
Alan
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.
Hi:
Does anyone know how to create heap on L1DSRAM without DSP/BOIS support?
Regards,
Alan
Alan,
What device are you using?
And what version of the Code Gen tools?
And just to be clear, you are not using BIOS at all?
Hi David:
Thanks for your reply, below are the detail descriptions:
(1) Evmdm6437
(2) CCS v3.03
(3) CGT v6.1.19
Our application does not have many tasks to deal with, just needs real-time image processing. On the other hand, we found the DSP/BIOS is hard to familiar with, so we do not want to use DSP/BIOS.
We do some image processing like Canny-edge detection and Hough-line transform; we found the performance is not enough in frame-based mode during image processing. According to the TI documentation, suggests user to use slice-based mode by using DMA and L1DSRAM to speed up the data movement, so we try to implement it without DSP/BIOS.
Basically, we dynamically
allocate external memory like DDR2 to store large image and define “.system” on
memory section which mapping to DDR2, but if we want to do it on L1DSRAM also,
how can we do? Or there are another ways to reached it?
Regards,
Alan
Alan,
OK, understood. These are some interesting issues, but since you are not using BIOS, posting on the BIOS forum may not yield quick results. :)
I'll move this thread to the DM64x forum in hopes you'll get a faster response there.
Dave
Hi David:
Thanks for your reminder, we will pay attention to it.
Regards,
Alan
If I understand your question, you already have the heap assigned to a memory location in DDR2, and you want a 'secondary' heap on L1DSRAM.
The short answer is you can't do this with the standard C dynamic memory routines. You have a few options:
1) Roll your own solution that distinguishes between the two different heap sources for all the dynamic memory functions.
2) Treat your sram as a "shared" buffer, and leave management responsibility to the programmer. This works well if you have a clearly defined block that will use a clearly defined piece of memory. For example, If you have 3 image processing "modules", you can use the DATA_SECTION pragma to assign a buffer to a certain section, and then in your linker command file you can allocate that section in L1DSRAM. Each module can then be configured to split this buffer up however they want. It is a lot messier, but with the severe size limitation on fast memory you have to do a lot of hand tuning anyways.
You can use the UNION directive in your lcf to allow the linker to allow different variables to share the same limited memory space. Again, this requires you to manually ensure that routines don't conflict when using this memory.
If you still want some level of L1Dcache when doing this, you can tell the linker to 'skip' the cache size when allocating. This trick works because cache is on the high side of L1D:
imageProcess_fullcacheshared {
*(.imageProcessSRAM)
. += 0x8000; // reserve 32kB worth of cache here
}
Then in your C code, you would use:
#pragma DATA_SECTION(ipBuffer, ".imageProcessSRAM")
Uint8 ipBuffer[L1D_SRAM_SIZE];
Hi Matt:
Thanks for your reply. Basically, it is what you said that we want to dynamically allocate memory both in DDR2 and L1DSRAM. Before we discuss further thought we wanted, we want to clarify your solutions first.
(1)What you mean ” Roll your own solution that distinguishes between the two different heap sources for all the dynamic memory functions “, would you please explain it more clearly?
(2)The second way you mentioned is using lcf to talk to linker to arrange the static memory section during build time, right? We are not familiar with this declaration in lcf, could you provides an example? Thanks!
Regards,
Alan
1) Roll your own: write your own malloc/free routines that let you select the heap you want to use. This is probably a lot more work than you want to do.
2) Let me give you some options here.
a) You have enough L1DSRAM left that you can statically allocate a "scratchpad" buffer that will act like your heap, and you can do this without having to reduce your L1D cache size. You only have one module that will be using this memory. In that case, just statically allocate your buffers and be done with it.
b) Just like option A, except for more than one module will be using this memory, but you as the programmer are going to guarantee that only one module will use it at any one time. (You can either assume that's the case, or add some kind of access control to make sure of it) You can treat each module's memory as a section, and then use a UNION statement in the lcf so the linker knows to place them in overlapping memory.
somewhere in module process1:
#pragma DATA_SECTION(process1Buffer1, ".process1ScratchSection")
char process1Buffer1[SIZE1]
#pragma DATA_SECTION(process1Buffer2, ".process1ScratchSection")
char process1Buffer2[SIZE2]
etc.
You would have similar statements in your module process2, but you would place them in a differently named section. Then in your lcf:
UNION (L1D_FLEX) {
MODULE_dar {
*(.process1ScratchSection)
}
MODULE_wark {
*(.process2ScratchSection)
}
} > L1D
c) In this case, you need such a big buffer in L1D that you can't fit it without reducing your cache. You can dynamically switch your cache allocation to give you lots of SRAM during this processing module and then switch back to cache when you are finished with it. This one is a little more complicated, and I'll only go into detail here if that's what you need.
Hi Matt:
For (1): We use malloc/free routines to dynamically allocate the memory which we defined in lcf, like “.system > DDR2”. How can we use the same directive to map to L1DSRAM. Is it possible to switch between DDR2 and L1DSRAM dynamically?
For (2a)
and (2c): We can easily
understand what you want to express. (2a)
is to fix the size of allocated memory on L1DSRAM and not to change the cache size
of L1D; (2c) is to adjust
the size between L1D_SRAM and L1D_cache dynamically. Right?
For (2b):
UNION
(L1D_FLEX) {
MODULE_dar {
*(.process1ScratchSection)
}
MODULE_wark {
*(.process2ScratchSection)
}
We are sorry to ask a stupid question, what are the effects for “L1D_FLEX”, “MODULE_dar” and “MODULE_wark”? How to quote them in C code?
Regards,
Alan
2b) To be honest, the linker syntax seems to require a name on those areas, and I just made something up. The only thing that I ever reference in my C code is the section names - ".process1ScratchSection" etc., and they are referenced with the DATA_SECTION pragma.
2a/2c) You are correct
1) You can declare an L1D section in the same way that DDR2 is declared, and then use ".system > L1D" to put your heap there. I don't know of any way to change back and forth dynamically. If I recall correctly, malloc/free usually make use of something like a linked list to keep track of memory available on the heap. So it's not as simple as just changing the location that memory is pulled from. That's why you would have to "roll your own", either modify malloc/free to accept an additional argument and be able to manage two different lists, or make a copy of the dynamic memory stuff, change the names, and basically run two different sets of dynamic memory allocation functions.
To me, the advantage of dynamic allocation is using a big heap means you don't have to do excessive manual memory management. Since the L1D space is extremely size limited, you are going to have to do lots of hand tuning anyways so I don't see the return on effort for modifying standard functions just to keep malloc/free calls.
Hi Matt:
Thanks for your explanation. According to your suggestion, so (2b) seems the best solution for user to allocate the L1DSRAM memory dynamically. Right?
If we have many data buffers (BufferA1, BufferA2,..; BufferB1, BufferB2,..) used on different functions, we want to overlay some of them(BufferAx and BufferBx do not coexist; BufferA1/BufferA2 or BufferB1/BufferB2 do coexist). How can we use UNION to declare it?
We try to use an example to explain it as below.
/*----------------------- funcA.c -------------------------------
#pragma DATA_SECTION(BufferA1, ".process1ScratchSection")
char BufferA1[SIZE1]
#pragma DATA_SECTION(BufferA2, ".process1ScratchSection")
char BufferA2[SIZE2]
…….
/*----------------------- funcB.c -------------------------------
#pragma DATA_SECTION(BufferB1, ".process2ScratchSection")
char BufferB1[SIZE3]
#pragma DATA_SECTION(BufferB2, ".process2ScratchSection")
char BufferB2[SIZE4]
……..
/*----------------------- link.cmd -------------------------------
UNION
(L1D_FLEX) {
MODULE_A {
*(.process1ScratchSection)
. += 0x8000; //
reserve 32kB worth of cache here
}
MODULE_B {
*(.process2ScratchSection)
. += 0x8000; //
reserve 32kB worth of cache here
}
} > L1D
---------------------------------------------------------------------------------------------------------
Please give us some suggestion, thanks.
Regards,
Alan
That seems fine, although if you are always going to have 32kB of cache, there is no need to reserve it. Just make your L1D section the expected size of L1D sram (in the lcf MEMORY section), and don't allocate anything to the section where cache resides. You only need the . += trick if you are going to be changing the amount of cache allocated between your modules.
And to be semantically correct, this isn't technically dynamic memory allocation. I'd probably call it static memory allocation with an overlay.