Guidelines on Memory Allocation for CreateTaskandStack

Discussion about writing software for VS1005 and the VSOS Operating System. Also posts about VS1005-related hardware design and device drivers should be posted here.
Post Reply
isonthomas
Senior User
Posts: 145
Joined: Mon 2016-08-22 8:20

Guidelines on Memory Allocation for CreateTaskandStack

Post by isonthomas » Mon 2016-09-19 15:19

Hi

Another clarification item:

Do we have any specific guidelines on the memory to be allocated when a task is created using CreateTaskandStack API.

In my current application, I have a task created using this method that handles the SPI communication with the host and takes care of the Audio playing. I allocated 1024 word initially for this task but the observation was that it is corrupting some memory. The values stored in some variables are getting corrupted with only this much memory. This issue was resolved after increasing it to 2048words. It looks a bit too much but the variable which was getting corrupted previously is not affected after increasing the stack size for the task.

Apart from SPI communication handling, this particular task is handling the reading of "index file" which contains the audio file name with its complete path(each of them is 512 characters long which is stored in local array on the task) and the creation of another task that takes care of the actual file play. I have read some where that playing of file requires a good deal of X and Y memory. My question is, if I start the file play from a task created using CreateTaskandStack, should the X and Y memories required for the file play also be accounted while allocating the stack for the task? For example, if the file play requires 7500w of X and 3500w of Y, is it mandatory that the task from which the file play is started should have a stack size of more that 11000words?

-Ison

User avatar
Panu
VLSI Staff
Posts: 2780
Joined: Tue 2010-06-22 13:43

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by Panu » Tue 2016-09-20 6:41

Hi!
if the file play requires 7500w of X and 3500w of Y, is it mandatory that the task from which the file play is started should have a stack size of more that 11000words?
Absolutely not! The decoders allocate this from global memory, or by using malloc(), as should you when you allocate buffers. Very little stack should used in DSP programs. For buffers and large local variables, use the keyword static. Using global variables is a good thing in DSP programming, as opposed to PC programming. Global and static variables are fast to use. They are dynamically allocated by LoadLibrary() and freed by DropLibrary(). Their addresses are also calculated at this time, instead of stack-allocated local variables, which are more slow to use.

Inside your own program, you can use malloc() for allocation of buffers that you don't need the whole time. But always use global variables for allocating buffers that you need all the time. Try to use the same buffer for many purposes, if you can.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

isonthomas
Senior User
Posts: 145
Joined: Mon 2016-08-22 8:20

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by isonthomas » Tue 2016-09-20 8:27

Hi Panu,

Thank you for the clarification.

Is there any method by which we can know if the task created is using more stack than how much ever is allocated for it?

On a completely different topic:

Code: Select all

  if (adcFP) {
    /* Close file */
    RunLoadedFunction(i2sLib, ENTRY_4, (void *)adcFP);
    adcFP = NULL;
  }
This is a code section from the README.txt file of AUIADC library.

1. Shouldn't we use adcLib instead of i2sLib ? I guess this is a typo.
2. In the file close operation, the last parameter of RunLoadedFunction() seems to take u_int16 type but here it is type casted to (void*) which is giving error while compiling

-Ison

User avatar
Henrik
VLSI Staff
Posts: 1180
Joined: Tue 2010-06-22 14:10

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by Henrik » Tue 2016-09-20 10:20

Hello Ison!
isonthomas wrote:Is there any method by which we can know if the task created is using more stack than how much ever is allocated for it?
Actually, there is, although this method is not 100% sure if someone uses lots of stack but there are big holes in its usage.

See this one:

Code: Select all

S:>tasks

Task 0x0021, priority 1, in RUNNING, name "MainTask"
  State: 3 (TS_READY)
  Stack: Start 0x0030, size 0x200, in use 0xf6, max used 0x176 (0x8a free)
  Stack Trace: current PC 0x42b7, Tasks::main[195]
    Next: PC 0x1e88 @ stack 0x008c, KERNEL
    Next: PC 0x408a @ stack 0x0086, shell::main[47]
    Next: PC 0x04c1 @ stack 0x007c, KERNEL
    Next: PC 0x0566 @ stack 0x003e, KERNEL
    Next: PC 0x0087 @ stack 0x0032, KERNEL

[... other tasks snipped for brevity ...]
In the output you can see how much stack is allocated by each task. In this case, maximum stack usage has been 0x176 words, and at worst, 0x8a words have been free in the stack.

And, as Panu said:

Code: Select all

char myGoodBuf[256]; /* Outside of any function, to space is taken from global memory, this is ok. */

int main(char *parameters) {
  char myBadBuf[256]; /* This space will be taken from stack, DON'T DO THIS! */
  static char myOtherGoodBuf[256]; /* This is taken from global memory, not stack, so it's ok. */
}
On a completely different topic:

Code: Select all

  if (adcFP) {
    /* Close file */
    RunLoadedFunction(i2sLib, ENTRY_4, (void *)adcFP);
    adcFP = NULL;
  }
This is a code section from the README.txt file of AUIADC library.

1. Shouldn't we use adcLib instead of i2sLib ? I guess this is a typo.
It's definitely a copy-and-paste typo, and the same typo was in two other documents, too. I will correct them for the next release.
2. In the file close operation, the last parameter of RunLoadedFunction() seems to take u_int16 type but here it is type casted to (void*) which is giving error while compiling
You are correct again. The cast should be to (s_int16) although (u_int16) would also work. I will correct the documentation for the audio drivers. Thanks for bringing these issues to our attention!

Kind regards,
- Henrik
Good signatures never die. They just fade away.

User avatar
Panu
VLSI Staff
Posts: 2780
Joined: Tue 2010-06-22 13:43

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by Panu » Tue 2016-09-20 15:39

RunLoadedFunction() seems to take u_int16 type but here it is type casted to (void*) which is giving error while compiling
You are correct again. The cast should be to (s_int16) although (u_int16) would also work. I will correct the documentation for the audio drivers. Thanks for bringing these issues to our attention!
Hmm, we could also rewrite RunLibraryFunction as a macro so that it would be cast automatically; then all parameter passing in all functions would be done as void ptrs.
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

isonthomas
Senior User
Posts: 145
Joined: Mon 2016-08-22 8:20

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by isonthomas » Wed 2016-09-21 6:19

Hi,

Thanks for the input. It seems to work fine after typecasting to s_int16. Kindly let me know if it is not OK and a macro implementation is better.

Another doubt :

I am using the RunLoadedLibrary() function while loading the usb host library as well. In the unloading part there is no code section for closing the file pointer as done in adCFP.

Code: Select all

  if (usbHostFP) {
    /* Close file */
    RunLoadedFunction(usbLib, ENTRY_4, (void *)usbHostFP);
    usbHostFP= NULL;
  }
Is it not necessary for usb host library? Will it create any memory issues? Kindly let me know if it is required. From a quick look I couldn't find a README documentation on the usbhost library

-Ison

User avatar
Panu
VLSI Staff
Posts: 2780
Joined: Tue 2010-06-22 13:43

Re: Guidelines on Memory Allocation for CreateTaskandStack

Post by Panu » Wed 2016-09-21 6:40

Hi!

Great that your things are moving forward. The s_int16 approach is ok; my idea about macros is that there wouldn't be a need for the programmer to do type casts and the compiler would not nag about it.
if (usbHostFP) {
/* Close file */
RunLoadedFunction(usbLib, ENTRY_4, (void *)usbHostFP);
usbHostFP= NULL;
}
There's nothing like this in the USBHOST driver; the AudioFP file pointer is a construction made specifically for the audio drivers, because you need a file handle to read the audio data with fread. But the USB host driver is a just a simple block device driver, the OS handles everything automatically just by using the drive letter in the file name. There are no user callable entry functions (other than main()) in the USB host driver, please remove anything like
RunLoadedFunction(usbLib, ENTRY_4, (void *)usbHostFP);
from your code. Running that line would be extremely dangerous, in effect causing a jump to a random location.
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

Post Reply