Determining MOD5213 RAM Usage
Determining MOD5213 RAM Usage
I seem to have filled up the 32K RAM on my MOD5213. I cannot find anything of mine that is directly using up that much RAM. Looking at my Map file, I gather there are several items that use lots of RAM, the UserParameters 'blob' (TheBuffer(?) 0x400), the stack (0x1000) and the task stacks (I think 0x400 each). I can call two tasks, but three puts me over the top.
So here are my questions:
I use OSSimpleTaskCreate (because it is simple), if I use OSTaskCreate I have to set up the stack myself. How do I know what size to make it? OSSimpleTaskCreate makes a 1K stack.
How can I change the size of the main stack?
How can I tell what is using up my RAM? I can read the map file but I can't find a map of the RAM. If it is the part marked .data then my variables are hardly using any of it.
Any other thoughts on how to squeeze more data into this RAM would be appreciated. I already have it optimizing for space.
Sam
So here are my questions:
I use OSSimpleTaskCreate (because it is simple), if I use OSTaskCreate I have to set up the stack myself. How do I know what size to make it? OSSimpleTaskCreate makes a 1K stack.
How can I change the size of the main stack?
How can I tell what is using up my RAM? I can read the map file but I can't find a map of the RAM. If it is the part marked .data then my variables are hardly using any of it.
Any other thoughts on how to squeeze more data into this RAM would be appreciated. I already have it optimizing for space.
Sam
Re: Determining MOD5213 RAM Usage
What NetBurner libraries are you using in your application? Are you using C++ libs? Do you have large global variables? How many tasks are running?
The task stacks on the MOD5213 is set to 1024 DWORDs by default so this is 4KBytes (0x1000). The idle stack is set to only use 1KBytes or 0x400. By default only two stacks are created, the idle task and usermain. The initial 1K of ram is also used to store the vector table. The MAP file should contain both the FLASH and RAM usage. The RAM usage for this part will be in the mem range 0x20000000 - 0x20008000. Keep in mind that only statically allocated memory will be in the MAP file, it probably isn't too safe using dynamic memory on a 32K part.
You can decrease the task size of all tasks created with OSSimpleTaskCreate by modifying the USER_TASK_STK_SIZE define in include_nn\constants.h. I would not decrease this too much. The task stack must be large enough to hold all local variable in the task including any local variables in functions called by that task. On top of that the stack must also be able to hold all the registers stored during an interrupt. This will be 80bytes times the max nested interrupts that can occur. Also all local variable in the interrupt routines and functions called by the interrupt routines will be stored on the task stack. If you do not have many interrupts and few local variables then decreasing stack size should be no problem.
I believe the UCOS runtime libraries shows how to use the normal OSTaskCreate. You could also look at some of the RTOS examples such as the semaphore example: C:\nburn\examples\RTOS\OSSemaphore
-Larry
The task stacks on the MOD5213 is set to 1024 DWORDs by default so this is 4KBytes (0x1000). The idle stack is set to only use 1KBytes or 0x400. By default only two stacks are created, the idle task and usermain. The initial 1K of ram is also used to store the vector table. The MAP file should contain both the FLASH and RAM usage. The RAM usage for this part will be in the mem range 0x20000000 - 0x20008000. Keep in mind that only statically allocated memory will be in the MAP file, it probably isn't too safe using dynamic memory on a 32K part.
You can decrease the task size of all tasks created with OSSimpleTaskCreate by modifying the USER_TASK_STK_SIZE define in include_nn\constants.h. I would not decrease this too much. The task stack must be large enough to hold all local variable in the task including any local variables in functions called by that task. On top of that the stack must also be able to hold all the registers stored during an interrupt. This will be 80bytes times the max nested interrupts that can occur. Also all local variable in the interrupt routines and functions called by the interrupt routines will be stored on the task stack. If you do not have many interrupts and few local variables then decreasing stack size should be no problem.
I believe the UCOS runtime libraries shows how to use the normal OSTaskCreate. You could also look at some of the RTOS examples such as the semaphore example: C:\nburn\examples\RTOS\OSSemaphore
-Larry
Re: Determining MOD5213 RAM Usage
Are you using printf() or iprintf()?
Re: Determining MOD5213 RAM Usage
Larry,
I am using C++ (to some extent), but not the actual c++ libs.
(RNixon)
I am using iprintf, not printf.
I am not using any dynamically allocated memory.
I tried (as an experiment, it would break the functionality) reducing the my largest global array substantially, but it didn't give me back much memory, as much as I expected, but it isn't using much of the 32K.
I can fit two tasks, but not three. I'd really like to add at least one more, maybe I'm just trying to do too much with this chip. But I still have lots of code space.
I see a note in constants.h that I can reduce the task size to about 512 if I'm not using floats, so I might try that.
Oddly, if I replace my OSSimpleTaskCreate with (as best as I can tell the correct) the macro expansion, then it seems I can add as many OSTaskCreates as I want w/o a RAM penalty, even though I still use USER_TASK_STK_SIZE and it is still 1024. I need to bring up my hardware and see if it works, I suspect I'm doing something wrong.
I replaced
OSSimpleTaskCreate(IrisTask, IRIS_PRIO);
with
asm( " .align 4 " );
DWORD IrisTaskStk[USER_TASK_STK_SIZE] __attribute__( ( aligned( 4 ) ) );
OSTaskCreate(IrisTask, (0), (void*)&IrisTaskStk[USER_TASK_STK_SIZE], (void *)IrisTaskStk, IRIS_PRIO);
and the replacement didn't increase my RAM usage above what I had with the OSSimpleTaskCreate call commented out.
I would have thought that I could find IrisTaskStk in my map file, but it it wasn't there.
Sam
I am using C++ (to some extent), but not the actual c++ libs.
(RNixon)
I am using iprintf, not printf.
I am not using any dynamically allocated memory.
I tried (as an experiment, it would break the functionality) reducing the my largest global array substantially, but it didn't give me back much memory, as much as I expected, but it isn't using much of the 32K.
I can fit two tasks, but not three. I'd really like to add at least one more, maybe I'm just trying to do too much with this chip. But I still have lots of code space.
I see a note in constants.h that I can reduce the task size to about 512 if I'm not using floats, so I might try that.
Oddly, if I replace my OSSimpleTaskCreate with (as best as I can tell the correct) the macro expansion, then it seems I can add as many OSTaskCreates as I want w/o a RAM penalty, even though I still use USER_TASK_STK_SIZE and it is still 1024. I need to bring up my hardware and see if it works, I suspect I'm doing something wrong.
I replaced
OSSimpleTaskCreate(IrisTask, IRIS_PRIO);
with
asm( " .align 4 " );
DWORD IrisTaskStk[USER_TASK_STK_SIZE] __attribute__( ( aligned( 4 ) ) );
OSTaskCreate(IrisTask, (0), (void*)&IrisTaskStk[USER_TASK_STK_SIZE], (void *)IrisTaskStk, IRIS_PRIO);
and the replacement didn't increase my RAM usage above what I had with the OSSimpleTaskCreate call commented out.
I would have thought that I could find IrisTaskStk in my map file, but it it wasn't there.
Sam
Re: Determining MOD5213 RAM Usage
As much as I love and promote the use of C++ over C, it's not such a good thing we you have limited RAM. I don't have hard fast proof for you but my experience says that exception handling and virtual functions (even just a single virtual destructor) can use up lots of RAM.
Re your Task macro expansion. I didn't read it that carefully but at first glance it looked like you are sharing the same stack among the tasks, a very, very, BAD idea.
Tod
Re your Task macro expansion. I didn't read it that carefully but at first glance it looked like you are sharing the same stack among the tasks, a very, very, BAD idea.
Tod
Re: Determining MOD5213 RAM Usage
I agree with Tod here. The MOD5213 should be sticking to mainly C code since you want to know where all that 32K of RAM is being allocated. Many C++ libs such as iostream require 2 or 3 times more RAM space then this little CPU has. If you are not seeing the stack you created then you probably did not declare it globally. It sounds fishy that you ran out of RAM with only 2 tasks since their stacks should only consume about 25% of the total RAM with the default settings. You should post your original MAP file since that will show where all the other RAM is being allocated.
Re: Determining MOD5213 RAM Usage
Thanks for the responses.
I notice that I've left out the 'static' keyword in my expansion of the OSSimpleTaskCreate macro, which would explain why I wasn't seeing the memory increase when I declared the stack w/o static. (And why it would crash when I tried it that way (I have my hardware up now.))
So now I can control the size of each task w/o changing USER_TASK_STK_SIZE and having to recompile the system files (and then maybe finding a different project that couldn't handle the change...).
It may have looked from the one example like I was sharing stacks for my task, but I wasn't (honest!).
I'd still be glad to hear about where all that 32K is going, if I'm using 12K for three tasks (3*4K each) and 1K for the stack and 1K for the idle task and 1K for serial buffers and 1K for the vector table, I'm only half way there. I've used const where I can to keep things out of RAM (That is how that works?).
I'm not using IO stream, but I'm way too heavily invested in the classes I've developed to back up now.
I've attached part of my map file (it didn't allow attaching a map extension, hence the txt). I suspect the problem lies in this section:
.bss 0x20000c90 0x39d4 main.o
0x20000c93 SerialTaskReady
0x20000c91 FocusTaskReady
0x200011f4 IrisMotor
0x20001130 ZoomMotor
0x20000c90 ZoomTaskReady
0x20001196 FocusMotor
0x20001110 ParamQueue
0x20000c92 IrisTaskReady
0x20000c94 LCParameters
0x2000112c LastFOV
0x200010f4 CommandQueue
.bss 0x20004664 0x88 UserParams.o
0x20004664 Blob
I guess I've just got a lot of variables, and much of that could be due to classes, not sure how you can tell from the map file. As mentioned earlier, I tried shrinking my (apparently) largest data structure but it didn't reduce the RAM usage much.
My 'parameters' struct has parts that could be const, and parts that can't. Maybe I can split it somehow to get the const part into flash (or am I confused about that?).
Sam
I notice that I've left out the 'static' keyword in my expansion of the OSSimpleTaskCreate macro, which would explain why I wasn't seeing the memory increase when I declared the stack w/o static. (And why it would crash when I tried it that way (I have my hardware up now.))
So now I can control the size of each task w/o changing USER_TASK_STK_SIZE and having to recompile the system files (and then maybe finding a different project that couldn't handle the change...).
It may have looked from the one example like I was sharing stacks for my task, but I wasn't (honest!).
I'd still be glad to hear about where all that 32K is going, if I'm using 12K for three tasks (3*4K each) and 1K for the stack and 1K for the idle task and 1K for serial buffers and 1K for the vector table, I'm only half way there. I've used const where I can to keep things out of RAM (That is how that works?).
I'm not using IO stream, but I'm way too heavily invested in the classes I've developed to back up now.
I've attached part of my map file (it didn't allow attaching a map extension, hence the txt). I suspect the problem lies in this section:
.bss 0x20000c90 0x39d4 main.o
0x20000c93 SerialTaskReady
0x20000c91 FocusTaskReady
0x200011f4 IrisMotor
0x20001130 ZoomMotor
0x20000c90 ZoomTaskReady
0x20001196 FocusMotor
0x20001110 ParamQueue
0x20000c92 IrisTaskReady
0x20000c94 LCParameters
0x2000112c LastFOV
0x200010f4 CommandQueue
.bss 0x20004664 0x88 UserParams.o
0x20004664 Blob
I guess I've just got a lot of variables, and much of that could be due to classes, not sure how you can tell from the map file. As mentioned earlier, I tried shrinking my (apparently) largest data structure but it didn't reduce the RAM usage much.
My 'parameters' struct has parts that could be const, and parts that can't. Maybe I can split it somehow to get the const part into flash (or am I confused about that?).
Sam
- Attachments
-
BT2DC2Step.txt
- (29.54 KiB) Downloaded 459 times
Re: Determining MOD5213 RAM Usage
The larges RAM usage seems to be coming from the IrisMotor variable, notice the big jump after the start of the IrisMotor variable (0x200011f4 -> 0x20004664 ). There is about 13K worth of RAM being used there. The CommandList variable is over 3K. That is more then half your total RAM in two variables.
Re: Determining MOD5213 RAM Usage
I think IrisMotor looks big because it is the last listed object but the map file isn't telling us everything. If I change the order of declaration then IrisMotor is 0x6e and FocusMotor becomes the apparent big object. Is there a way to get the map file to list memory usage in order, and/or to have it show actual size of each variable?
Sam
Sam
Re: Determining MOD5213 RAM Usage
Most of the C standard file library stuff got linked in here. You should comb your application for printf and replace with iprintf. Also you should not be using the C FILE objects as they will consume half your memory. Some of the suspect library links I see in your MAP file are: (lib_a-vfprintf.o), (lib_a-sprintf.o), (lib_a-vfprintf.o), plus nearly all file libraries following (lib_a-fflush.o).