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.

Initializing arrays

Other Parts Discussed in Thread: MSP-TS430PN80USB, MSP430F5529

Hi all,

I'm using the MSP430 dev board (usb-80) and am communicating with a few peripherals. Everything work fine, but whenever I try to create a large array everything goes to crap. I don't get an error message or anything, but the program doesn't work properly. As soon as I comment out the array creation it works fine. 

The code is simply

unsigned char Array1[528];

As you can see, the array is meant to be a 1x528 vector of type unsigned char. When I compile the code, it works fine but I don't have press F8 (Resume); it has already started the code automatically, but the program itself does not perform as it should.

Any ideas why this is? Is there a size limit on how large of an array I can create?

Thanks in advance...

  • EDIT: I should mention I am using these arrays in several functions and I would like to make them volatile (I really, really don't want to pass them as arguments because they are used in so many different places, and the program is a state machine using function based on pointers and it would be a nightmare to pass the arrays as arguments).

    I just noticed that if I declare the arrays within my main it works fine, but when I declare them as global variables it doesn't work.

    Just thought I would throw that in the mix as well.

  • Trevor Woods said:
    Is there a size limit on how large of an array I can create?

    Yes, but 528 is nowhere near the limit.

    What memory model are you using?

    Could you be more exact about the program's behavior?  What behavior do you expect?  What behavior do you observe?

    We will probably need a compilable test case which demonstrates the problem to make progress on this.

  • Sorry for the delay, was out of the office.

    I have no idea what memory model I am using; in fact I'm not really sure what you mean.

    I eventually found a way to get it done; I just declared the arrays within my main() and pass them as arguments. It was a nuisance but it works.

    The way that the program was behaving before was just a little bit bizarre. Normally when I build/debug a program, it will build it and then in the top right of CCS there is a play button, pause, stop, etc. and it is up to me to press play to initiate the program run. When I had those arrays as global I didn't have the option to press play; it was greyed out already and I could only stop it. But strangely it was like my program wasn't running. I have an LED toggling on a timer that will flash repeatedly when I don't have the arrays declared, but does not flash when I make them global. 

    Anyway, any thoughts on this? Like I said the program is worked around now, but I'm still curious why it didn't work in the first place.

  • Trevor Woods said:
    Anyway, any thoughts on this? Like I said the program is worked around now, but I'm still curious why it didn't work in the first place.

    I have no idea; I don't know anywhere near enough about your program.  Without a test case, I can only guess, and that's usually not effective; there are just too many possibilities for things that could have gone wrong.  Things like not being able to press "play" are secondary symptoms, and we want to isolate the ultimate cause.  It might be necessary to analyze the program at a finer grain, which probably means cycle-stepping from RESET instead of running to main, and examining the contents of memory.  A complete, reproducible test case that demonstrates the problem would speed this analysis up 100-fold.

  • Unfortunately I can't post my code (NDA) and I frankly don't have enough time to try to reproduce it otherwise. I don't even really have enough time right now to investigate the issue and since I have it running with a workaround I am going to table this issue and maybe come back to it again in the future.

    Thanks for the help though and if I ever sort out what is going wrong I will post back to this thread.

  • Sorry for the delay. I have a little more info on the problem. So I still don't know why the code wasn't compiling properly. That solution I ended up using still works fine, but your response got me thinking and now I am finding a similar problem only in a slightly different form.

    I am using AT45DB321D Atmel Dataflash and am reading the pages (528 bytes each) continuously and storing them in an array on the MCU, then sending that array over USB to a terminal program I wrote. Now the problem is that the stoppage when the array is full and sends is quite slow (it takes about 6 minutes to send 8000 pages of 528 bytes, 10 pages at a time) and I would like to speed up this process. The first thing that springs to mind is storing more pages locally on the MCU at a time (i.e. instead of 10 store 20 or more). So this means declaring a local array on the MCU of length 5280 (for 10 pages; basically 528 bytes multiplied by the number of pages to be sent). Unfortunately the MCU does run out of space in a hurry, but at this point I have no idea how much of the MCU memory I am using, or even how much is available, or of what type (note that I am a bit of an amateur at firmware design).

    So my question is, where do arrays get stored? I am using a MSP-TS430PN80USB dev board, and I am 99% sure there is 128kB of flash memory on it which is where I think the temporary arrays get stored, but I am far from being certain.

    My program won't compile when I try to make an array of larger than 10 pages and I am assuming this is the problem (I just get one of those 'errors during build' errors that don't really help very much). 

    Can anyone help me with this? Thanks in advance!!

  • I presume you mean a global, non-const array.  For MSP, global non-const arrays are located in .bss unless you specifically place them somewhere else.  Look at the linker map file (linker option --map_file) to see where .bss is being placed.  I would be very surprised to see .bss in FLASH; typically FLASH on an MSP is used for read-only data.  Some MSP devices are quite small, and might not have enough internal memory to handle objects of that size.

    Exactly what error message do you get?   You may need to look at the console window; the "problem view" sometimes truncates the real error message.

    You say you are using an MSP-TS430PN80USB.  I'm not familiar with this part, but from looking at the documentation, I gather this is a "socket target board."  You'll have an MSP device installed in the CPU socket.  Do you know the device number for that?

  • Hi,

    Sorry for the delay. I am using the MSP4305529. I don't actually get an error message, my program just doesn't seem to actually work (to be clear, I occasionally get a 'Sandbox 9v9 not built' type error, but not always). I will check again when I am at the office tomorrow for the specific error and will try to dig deeper if there is more to the story.

    My array isn't necessarily global; in fact I have been trying to keep it limited to the scope of the function in which it is being called. I will look into the .bss and linker map file to try to find out more. Basically I would like to find out what is the absolute maximum size I can make it and go from there. Thanks so much for the help!

  • I couldn't find MSP4305529, but I did find MSP430F5529, which has 128KB FLASH and 8K SRAM.

    The theoretical absolute maximum size of an array depends on which data memory model you are using.  It's 0xffff in small data model, and 0xfffff in large data model.  However, you're likely to be constrained by needing to allocate memory for other objects.  Also, if you allocate an object in SRAM, clearly it can't be larger than 8K.  If you declare a non-static variable in a function, the size of the object is limited by the size of the stack.

    I've never seen an error like "Sandbox 9v9 not built"; I have no idea where this error comes from.

  • Sorry, that was a typo. I am using the MSP430F5529. 

    So I have been trying to follow your instructions but unfortunately my knowledge falls a little short. I looked at the .map file and this is what I see in the .bss section:

    .bss 0 00002400 00000504 UNINITIALIZED
    00002400 00000484 main.obj (.bss)
    00002884 00000046 usb.obj (.bss)
    000028ca 00000022 UsbCdc.obj (.bss)
    000028ec 00000008 dma.obj (.bss)
    000028f4 00000008 rts430x.lib : _lock.obj (.bss)
    000028fc 00000008 : boot.obj (.bss)

    I unfortunately have no idea what that means. 

    It does make sense what you said about SRAM; the array fails shortly before 8K, and I'm guessing my other variables and such are using that difference.

    Is there any way I can locate my array in another location that will a) give me more space for the array without sacrificing speed and b) be okay to be written to tens of thousands of times. I'm told I don't need to worry about memory wear too much, but I'd rather be on it than figure out later my strategy is faulty.

    Also of course now that I need to error to come up it won't. Sometimes it rears its head, but usually the way the program fails when the array is too large is that it will compile and run, but it will get stuck somewhere, or the USB won't initialize properly, or my timer interrupt won't fire, etc. It's always something (usually one of those 3 things) and the way it always will get fixed is if I minimize the size of the array down to 5280 bytes.

    Thanks again for the help! I really appreciate it!

  • Before I can interpret that map file snippet, I need to know how the array is declared.

    Is it a function-local object?  Is it static?  Is it const?

  • This is my function:

    if (!(strcmp(wholeString, "contRead"))){
    USBCDC_rejectData(CDC0_INTFNUM);

    BYTE getArray[SIZE];

    //read from the main memory
    int h = 0;
    for(h = 0; h < 10; h++){
    DF1_cont_read(h*PAGES, 0, getArray, PAGES);
    USB_send(getArray, SIZE);
    }
    }

    It is a function that responds to a USB receive event. SIZE and PAGES are declared in a header file like such:

    #define SIZE 5280
    #define PAGES 10

    SIZE is essentially PAGES*528. As soon as I make SIZE much bigger though the program behaves poorly.

    Does this help? Let me know if you need more info...

    And thanks!



  • That's not a whole function, but it should be enough.

    getArray is a local non-const array, which means it will be allocated on the stack.  The stack lives in the ".stack" section.  Check your linker map file to make sure your ".stack" section is large enough to hold 5280 bytes (0x14a0 in hex) with a good margin to allow room for other local variables and stack usage.  My suspicion is that you are actually overflowing the stack without realizing it.  I presume you are using the default linker command file, lnk_msp430f5529.cmd, which allocates .stack to "RAM", which is of size 0x2000, so your .stack is going to be a tight fit, especially since you are already using 0x504 for .bss

    It is recommended you do not make such large variables local to a function.  It is too easy to overflow the stack.

    I cannot make any more specific analysis without more to go on.  What exactly do you mean by "the program behaves poorly"?  Does it work correctly, but slow?

  • I will try to answer the questions you have, but to be honest I feel I am getting a wee bit out of my depth here so please be patient with me :)

    As far my program goes, it will compile and run but usually the way the program fails when the array is too large is that it will get stuck somewhere, or the USB won't initialize properly, or my timer interrupt won't fire, etc. It's always something (usually one of those 3 things) and the way it always will get fixed is if I minimize the size of the array down to 5280 bytes. Typically though it's like the program isn't running at all. My usual debug technique is to have a simple timer toggle an LED every second or so. And when my array is too large the light does not toggle, nor does the program respond in any other way.

    This is my .stack section in the map file:

    .stack 0 00004360 000000a0 UNINITIALIZED
    00004360 00000002 rts430x.lib : boot.obj (.stack)
    00004362 0000009e --HOLE--

    I feel like there is definitely something wrong because obviously none of those sections are very long at all. However, when I run my code with an array at 5280 I get definitive, correct results that aren't incomplete or incorrect (which makes me think the stack isn't overflowing). Of course I barely  understand what it means to 'overflow the stack' so I may or may not be talking out of my backside on that. I am reading a dataflash IC and storing it in the array, and I know exactly what should be in that array and my results match my expectations perfectly which makes me believe that the array, as it stands, works well.

    I was planning on making the array global but decided against it for some reason a while back. I don't mind switching it, if that is what you would recommend.

    Any new thoughts based on this information?
    Thanks again! 


  • The symptoms you are describing (e.g. "it will get stuck somewhere") are secondary symptoms; I cannot diagnose the problem with just those symptoms.  You need to understand the proximal cause for "getting stuck," and I can't help you with that without a test case. 

    That map file fragment shows that your .stack section is only 0xa0 bytes, so you are very certainly overflowing the stack.  The size 0xa0 is about what I would expect on this MSP device.  Basically, stack overflow means that you are clobbering memory adjacent to ".stack" when you write to getArray.  This will lead to unpredictable results.  It might fail today, or it might not.  It will most likely make your program behave in strange ways.  If you are lucky, the program will crash.  See http://en.wikipedia.org/wiki/Stack_overflow

    You must either make the array global or make your stack much, much larger; probably about 0x1800 would do.

  • I would love to send you my program, but unfortunately it is technically the property of the company I work for and I'm not entirely sure where sharing for learning purposes stops and the NDA begins. I know that leaves me in a bit of a bind but for right now that is where I'll have to stand.

    As for increasing the stack; how does one do this safely? I have tried to read up on it but I haven't been able to find decent instructions for CCS.

    Thank you again, you're being a very great help!

  • That's fine, but realize that this means I'm severely limited in my ability to help you.

    You can change the size of the stack with the --stack_size linker option.  See section 7.4.24 "Define Stack Size (--stack_size Option)" in the MSP430 Assembly Language Tools v 4.1 User's Guide (revision G) http://www.ti.com/lit/ug/slau131g/slau131g.pdf

  • I have the same problem with a complex struct variable.

    read chapter B5.1 and B5.2 in document slau157u.pdf. One possible solution is implement function _system_pre_init(void) and return 0.

    By me it helps.