Are you suggesting to trigger the DMA after every write?
It'd be a waste to trigger the DMA every time I write few bytes to the 10KB buffer.
My main problem is, how to efficiently decide when to trigger the DMA?
And base on what to make that decision?
But, I'd not want the uC to be get an interrupt from the DMA on its completion of transfer, every time I write a log.
If you want to keep the latest data, then the only option is to overwrite old data. Write some "book-keeping info" to the first bytes in the memory which tells where the latest data is located.Since I need to write into the 1MB buffer in Cyclic mode, I need to take into account knowing when I reached the end of the 1MB buffer.
If I'd write known-sized amount of data into the 1MB buffer, it'd make it more efficient to know when I reached the 1MB buffer's end.
What would you suggest please?
Size = (Last Address Written To 10KB Buffer - Last Address in 10KB Buffer that was Transferred by DMA to 1MB Buffer) //Size is Size to Transfer
if (Size < 0) Size += 10KB
Size = (Size > (Last Address of 10MB Buffer - Next Address to Write to in 10MB Buffer) ?
Size : (Last Address of 10MB Buffer - Next Address to Write to in 10MB Buffer)
The reason I hope to optimize it cycles-wise, is that the TIMER's ISR works under the context of Disabled Interrupts Mode.Why is it so important to squeeze out one or two instructions..
Yes, but it'd happen in background and therefore won't delay the uCthe data transfer itself takes many times longer than the dma triggering itself.
Size =(Last Address Written To 10KB Buffer - Last Address in 10KB Buffer that was Transferred by DMA to 1MB Buffer)
NorthGuy said:On cicrcular buffers: I have posted a response to one of your queries where I described how to organize circular buffers efficiently. You probably can find it.
However, the copying into the large 1MB buffer is not done by SW, but by the DMA.NorthGuy said:With circular buffer I usually allocate a piece whch has a size of power of 2 and never worry about circularity.
Could you elaborate on that please?NorthGuy said:You cannot get off the hook with interrupts that easily, because your interrupt code will now interfere with your buffer-writting code, and you will have to spend quite a bit of your precious cycles to make sure they don't harm each other.
The addresses are not powers of two. The size of the buffer is a power of two.Therefore, correct me if I'm wrong, but you can't have the DMA to AND each address with a power of 2, right?
that is since the DMA which I work with, is given with Source Address, Destination Address, and Length (and of course Channel, and Interrupt Mode)
I may be missing something, but in the case that the size of the big buffer is a power of 2, e.g. 1024KB = 1MB.misterT said:The addresses are not powers of two. The size of the buffer is a power of two.
It doesn't.. It only helps with the efficiency of the software buffer. DMA is designed to be efficient way to move data around.. don't try to make it any more efficient in software. That is impossible.How does that help for efficient circularity in the 1MB Buffer, using the DMA?
True.. no way around it.In this case, I'd need to tell the DMA to move Data of size of only 0.8KB from Last-Transferred-Address-to-1MB-Buffer.
that is since the DMA which I work with, is given with Source Address, Destination Address, and Length (and of course Channel, and Interrupt Mode)
Could you elaborate on that please?
How will triggering the DMA in the Timer's ISR will harm the circular writing to the 10KB Buffer?
Thanks!NorthGuy said:You use the same Head and Tail for both 1MB and 10K (which you can always re-make to 8K), but to access 8K you do &0x1fff, but to access 1MB you do &0xfffff. So you pass to DMA: Source - SmallBuffer[Tail&0x1fff], Destingation - BugBuffer[Tail&0xfffff], Length - (Head-Tail).
Are you talking on a situation where we'd fail the calculate the correct length?NorthGuy said:You will have some problems when it wraps around, but nothing too bad.
T,misterT said:It doesn't.. It only helps with the efficiency of the software buffer. DMA is designed to be efficient way to move data around.. don't try to make it any more efficient in software. That is impossible
How do you define the Head and Tail? (I didn't understand how you calculated the correct length please)
Are you talking on a situation where we'd fail the calculate the correct length?
I'd appreciate it if you could elaborate on that please.
Got you!Head is the counter of what you wrote. It gets incremented for every byte you write, and it points to the place where you continue writing.
Tail is the counter of what you already took out with your DMA. It gets incremented for every byte you transfer with DMA, and it points to the place where untransferred data begins.
Yes, I see now.The size available for DMA transfers is the difference between the two. Size = Head - Tail;
Yes, you're right.Say, the Tail&0x1fff is 0x1ff8 and you need to transfer 20 bytes. Apparently, you cannot do this in a single transfer, because DMA won't wrap. You need to transfer 8 bytes, then 12 from the beginning of the buffer. You'll have to deal with that somehow. There are many ways to do that.
Head&0x1FFF - Tail&0x1FFF gives you: 0x000C - 0x1FF8 = 0xE014
if (head&0x1FFF > tail&0x1FFF) size = Head&0x1FFF - Tail&0x1FFF
else size = 0x2000 - Tail&0x1FFF
That is of course in the case where Head > Tail. (as you said below).
Yes, you're right.
How would you deal with it?
What would you find to be an efficient way of handling it?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?