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.

TMS320F28335: Problems with C I/O

Other Parts Discussed in Thread: TEST2

I am currently attempting to get the micro-controller to write and read from a text file, so that I can ensure that the board will be capable of what I need it to do. Unfortunately, I'm having strange run-time hang-ups with this, and I don't know if this is something that that I'm doing wrong, or if the board simply isn't designed to do so.

I'm attempting to use fprintf and fscanf. Sample below (I don't see a code block in the forum settings.)

#include <stdio.h>

//Global Variables for Easy Debug Access
   float out[10];
   float input[10]={1,2,3,4,5,6,7,8,9,10};
   int test;
   int test2;
   int i;

void WritetoFile(void)

{
    FILE *fp;
    fp = fopen("C:\\Users\\DaJJBomb\\workspace_v5_3\\senior_design_project_code\\hello.txt", "w");
    //test=fwrite(input,sizeof(float),sizeof(input)/sizeof(float),fp);
    for(i=0;i<10;i++)
    {test=fprintf(fp,"%f\n",input);}
    fclose(fp);
}

void ReadfromFile(void)

{
    FILE *fp;
    fp = fopen("C:\\Users\\DaJJBomb\\workspace_v5_3\\senior_design_project_code\\hello.txt", "r");
    for(i=0;i<10;i++)
    { test2=fscanf(fp,"%f\n",out[i]);}
    //test2=fread(out,sizeof(float),sizeof(input)/sizeof(float),fp);
    fclose(fp);
}

void main()
{
    WritetoFile();
    ReadfromFile();
}


When I attempted to build this for the first time, I get a compiler error stating that there's not enough memory in .text to fit the library, so I expanded that section in the linker file:

   .text            : >> RAML0|RAML1|RAML2,     PAGE = 0

Everything else is default. With this line, the code compiles, but when it gets to the first fprintf, it hangs forever.

In order to test it, I used fwrite and fread. It worked for reading and writing strings and integers perfectly, but when I tried to use floats it gave me erroneous results.

I haven't dug deep enough to see whether or not using RAML1 and RAML2 is the reason why this is acting so strangely. I couldn't see them being referenced in the linker file, so they shouldn't be causing any issues, but I'm not 100% sure.

Is there some important element I'm missing, or is this more of a matter of "this board isn't supposed to be performing file I/O operations?" Any help would be greatly appreciated


Thanks for your time,

JJ

  • Jason,

    You've got something wrong someplace.  I've used fprintf and fscanf before.  The linking to RAML0|RAML1|RAML2 is not the problem.  I don't have a ready made F28335 project to post, but I have an old F2812 project.  I've attached the main.c file here.  Code would be same for F28335.  I didn't look very closely at your code, but that's probably not the problem.  Did you disable the watchdog timer?

    On the fread and fwrite with floating point, what did you mean you got erroneous results?  I'm no expert on C I/O stuff, but fread and fwrite are not formatted output functions.  I think they just operate on a byte basis.  So, I'd expect fread/fwrite to just treat floats as any other value, albeit they are 4 bytes in length so you'd need to read/write all 4 bytes to get the whole float transfered.

    Also try increasing the size of your stack and your heap in the project options.  My experience is that if these are too small, C I/O will just fail to work but will not crash (they just complete without actually doing the read or write).  But, you never know.  Give it a try.

    Regards,

    David

  • I've looked into this further, and I have partially fixed the problem. So far, there were 2 issues. The first was a programming error (I was passing the entirety of the input array in the fprintf function, not the individual element.) The second is that, apparently, %f does not appear to work as a floating point indicator. I used %g, and it was able to work.

    The problem I have now is writing a array of floats. It works for 6 elements (if the size is 6 or less there's no problem.) After that it goes haywire. This has to be the symptoms of the heap/stack size explanation you gave. My only issue is I couldn't find it. I've been looking in the build settings and I couldn't find any option for the stack/heap size.

    Thanks for your time,

    Jason

  • Jason,

    In CCS v5, the stack and heap sizes are in the project options, Build->C2000_Linker->Basic_Options.

    A 'blank' means the default size of 0x400 words.  Above, my stack size is 0x200, and the heap would be 0x400 by default if I called any heap using functions (although I am not using any heap in this particular project).

    Regards,

    David 

     

     

    - David

  • Checking in: still working on this. I'm still trying to realize what I can get rid of so that I can make the stack bigger. It is slightly worrisome that memory is already a problem when we are only working with 20 values: what is going to happen when we try to get to 200? 

    I'm also still not understanding why the stack needs to be this large. Just to clarify, the program works as intended until it gets to the point where it crashes. I took a look at the SP during one run, and saw that it successfully returned to its proper value (SP before call = SP after call) after each fprintf / fscanf call until it crashes. When it does, it mysteriously jumps to 0x0015, from around 0x0400. If stack size is the problem, then that would assume that the fprintf / fscanf function has some sort of memory leakage, which is a big red flag.

    In addition, on the iteration where the program crashes I looked at the disassembly execution. It appears the following 3 lines are repeated in an infinite loop:

    0098e1: 1901 SUBB ACC,#1

    0098e2: 7D86 MOV *XAR6++,AR5

    0098e3:   EDFE SBF -2,NEQ

    I feel like this is somehow resulting in a memory leak somewhere, which results in everything else going haywire. Unfortunately, I'm not an expert on ASM, so I can't identify the problem from this alone.

    I still think this is a stack problem, but I want to understand why it is a stack problem before I continue trying to work through this blindly.

    Thanks for your time,

    Jason

  • Jason,

    I really cannot speculate what is going on in your code.  The three code lines you cited don't make much sense:

    0098e1: 1901 SUBB ACC,#1
    0098e2: 7D86 MOV *XAR6++,AR5
    0098e3: EDFE SBF -2,NEQ

    It looks like the accumulator is being used as a loop counter and decremented each pass.  Looping continues until ACC=0.  This is not unusual, but the middle line of code is odd.  It is moving whatever is pointed to by XAR6 into AR5 register, and post-incrementing XAR6.  All it's doing is continuously overwriting whatever is in AR5.  I don't see why any code would be doing this.

    My experience has been that if the stack is too small and you call a C I/O function, the function just returns without executing.  It doesn't cause a crash.  I think you've got something else wrong in the code.  Not sure what though.  It could still be stack related I suppose, but I think more complicated than just the stack being too small.

    My suggestion would be to prune your project down (remove things) until you get the C I/O to work.  The last thing you removed is then a clue to the problem.

    Good luck,

    - David

     

     

  • David M. Alter said:

    Jason,

    I really cannot speculate what is going on in your code.  The three code lines you cited don't make much sense:

    0098e1: 1901 SUBB ACC,#1
    0098e2: 7D86 MOV *XAR6++,AR5
    0098e3: EDFE SBF -2,NEQ

    It looks like the accumulator is being used as a loop counter and decremented each pass.  Looping continues until ACC=0.  This is not unusual, but the middle line of code is odd.  It is moving whatever is pointed to by XAR6 into AR5 register, and post-incrementing XAR6.  All it's doing is continuously overwriting whatever is in AR5.  I don't see why any code would be doing this.

    My experience has been that if the stack is too small and you call a C I/O function, the function just returns without executing.  It doesn't cause a crash.  I think you've got something else wrong in the code.  Not sure what though.  It could still be stack related I suppose, but I think more complicated than just the stack being too small.

    My suggestion would be to prune your project down (remove things) until you get the C I/O to work.  The last thing you removed is then a clue to the problem.

    Good luck,

    - David

    Unfortunately, I don't have anything to prune down. My code is just the file print:

    #include <stdio.h>

    void main(void){

    int input[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};

    int i;

    for(i=0;i<13;i++)

    {printf("%i\n",input[i]);}

    }

    If I change the input array to a size 12, everything works as intended. Otherwise it freezes when the 13th write is attempted.

    The fact that it only works for half as long as a float (freezes on 7th) is why I am assuming that this is a memory problem. But I'm not doing anything else, so I don't understand why I'm already running into memory problems.


  • Hello Jason!

    You can try one useful experiment:

    void main()

    {

    int* pti;
    int i;

    for(i=1;i<401;i++)
    {
           pti = (int *)malloc(i * sizeof(int));
           if(pti != NULL)
           {
            free(pti);
           }
           else break;
    }

    }

    Thus you will get the maximum possible size of the heap for your case ( "i" words ). If "i" will be <<400 then it's worth thinking about memory reallocation at your CMD-file.

    Regards,

    Igor

  • Try disabling the watchdog timer before you do your printf loop.  I bet it will make the problem go away...

     

    void main(void)
    {
       int input[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};
       int i;

       asm(" EALLOW");             // Enable EALLOW protected register access
       SysCtrlRegs.WDCR = 0x00E8;  // Disable the watchdog
       asm(" EDIS");               // Disable EALLOW protected register access

       for(i=0;i<13;i++)
       {
          printf("%i\n",input[i]);
       }
    }

    Regards,

    David

  • The compiler tells me that SysCtrlRegs isn't defined. Am I missing a board-specific C header file?

  • SysCtrlRegs is a structure defined in the F2833x Peripheral Header files.  I assumed you were using these (since everyone does).  If you are just trying to run a quick test, you can use CCS to turn off the WD (on the scripts menu) and then DO NOT reset the device afterwards (or it will re-enable the WD).  Alternately, replace the SysCtrlRegs line in my code with this equivalent:

         *WDCR = 0x00E8;     /* Disable the watchdog */

     and also add this to the top of your source file:

    #define WDCR   (volatile unsigned int *)0x00007029   /* Watchdog control register */

    - David