This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Pass 1 dimensional array in function

Passing any arrays by value or pointer does not work very well.

I can try integrating an array into a structure, but that is not how I would do it.

if I have: frame( unsigned char &mbrtubuf, int &uslen) and the receiving side is :

frame ( unsigned char *somepointer, and int *uslen) neither of the variables are passed

correctly to the function. Prototype is in a header file. Does not work and when it does work

its becomes unstable. Terrible compiler. It should work and I should even have to think

about it. I spend more time on the Compiler then I do on the actual program.

The only way I can get the array into a fucntion is by declaring it external in the function.

Any ideas

Phil

Parents
  • Textbook C here, the compiler is fine
    
    frame ( unsigned char *somepointer, and int *uslen); //prototype
    
    void main(void )
    {
       unsigned char cArray[10];     // declaration
       int nArray[10];               // declaration
    
    
       frame( cArray, nArray);       // Call
       while(1);
    }
    
    // Function
    frame ( unsigned char *somepointer, and int *uslen)
    {
        unsigned char c
        int n
    
        c = *somepointer;
        n = *uslen;
    }
    
    
    

Reply
  • Textbook C here, the compiler is fine
    
    frame ( unsigned char *somepointer, and int *uslen); //prototype
    
    void main(void )
    {
       unsigned char cArray[10];     // declaration
       int nArray[10];               // declaration
    
    
       frame( cArray, nArray);       // Call
       while(1);
    }
    
    // Function
    frame ( unsigned char *somepointer, and int *uslen)
    {
        unsigned char c
        int n
    
        c = *somepointer;
        n = *uslen;
    }
    
    
    

Children
  • Hi Neil

    Your right it works in this scope, but not when the scope is across multiple files. The pointers never see each other. The function pointers work, but not across a multiple files. I have had to use global variables to pass back and forth between function to get it right.

    Maybe, I am doing something wrong. I am using small memory model with xdata place on specific variables.

    Part 2 questions: How does one understand when the stack overflows underflows and pointers don't point to the right locations. How does one translated the dissassembly back to C code.
    Maybe if I could found away to view the Assembly code, to see where the pointers and Stacks are and watch this link, I might gain some confidence in what I am doing. My Linker shows some links.

    Part 3 is there any real advantage using the UV to compile code or can I use Silicon Labs IDE.

    Part 4 It appears that I have many interrupts going on including serial interrupts both rec. and trans. The message frame is coming in; It's being decoded then all breaks loose and it jams up.

    Stack, pointers, and timing of the interrupts is what I need to see here.

    How can I go about troubleshooting this with Keil tools and IDE's. I see the code running for minutes possible hours then right out of the blue. Communication stops. I can watch dog out of this stuck loop, but I would like for it to run without feeding the dog, if I can.

    Phil

    What me

  • but not when the scope is across multiple files.

    If so, that's because there's something with how you organize your program into multiple source files. And since you opted to show not a shred of actual source code, nor any other concrete facts about "it doesn't work" actually means, that's all that can be said about this.

    If you want help, you really need to make a better job of presenting the problem.

    The pointers never see each other.

    That makes no sense whatsoever. What do you mean by that?

    The function pointers work, but not across a multiple files.

    What would function pointers have to do with anything you said so far?

    How does one understand when the stack overflows underflows

    One doesn't. One makes sure that doesn't happen, instead.

    How does one translated the dissassembly back to C code.

    One doesn't. Because there's no need to.

  • Either doing stuff wrong, or having wrong expectations about how 'C' works - or both!

    As Hans-Bernhard Broeker says, you have not given sufficient information to be able to tell.

    "The function pointers work"

    You are aware, aren't you, of the significant limitations thta C51 places on function pointers...?!

    "It appears that I have many interrupts going on"

    Don't you know?

  • 1)If you are using Global Variables they need to be defined in one C module and declared with an extern in a header shared by the other modules. The same with functions. There are several limitations for function pointers and the Keil 8052 compiler. The functions must be declared reentrant. This has to do with the 8052 Architecture. Function pointers are not a great choice with this CPU

    2) C will not underflow the stack, you would have to do that in ASM. Overflows you need to check. one way is to write a number to all the RAM in the stack area and inspect with a debugger or a monitor function in code.

    3) They are tools which ever gets the most work done. ( disclaimer: I never used the Silicon Labs IDE)

    4) Interrupts: Are you using volatile where it is needed. Are you properly handling non-atomic variables? Are you calling non reentrant functions ( Like printf()) Calling functions from multiple interrupts with different priorities? Calling functions from the main loop and interrupts? These situations could work it the functions are declared reentrant. Not that Interrupts that call a lot on library functions ( like float or long math) push everything on the stack. This makes slow interrupts, and burns though a lot of stack space.

  • Hi All

    I found the problem why the pointers were not linking correctly! It appears that across multiple files, one needs the keyword "extern" in from of the prototype as in the previous examples all works, but without the this "C" keyword nothing links and when it does; the variables become unstable. I used this keyword on global variables, but I didn't think for some reason I needed it on the protoypes. This might also solve some other issues I had with function pointers but that is another topic all together.

    Now, that the PDU frame seems to be working. I am also trying to find ways to troubleshoot software, my biggest problem is learning what tools work. Is there a file that would show memory locations and how they are linked? The Stack seems to be O.K., most of the time, I can stop the program via breakpoints, and view, but there must some way to view this in a run time matter to show real time data.

    Right now. I am multiplexing 5 ADC's with a serial hardware interrupt. I am sampling at a Max freq of about 50Khz with an internal timer. Now, I trying to find ways to troubleshoot software in a run time matter for stable ADC numbers. I think my interrupts are effecting the ADC sampling measurements, but not sure how to view this problem. I have No RTOS, at this time. I have a digital scope.

    ADC samples are averaged, but I am not filtering at this time. Hardware op amps seem O.K., Power supply is heavily filtered. The ADC interrupt needs to interleave between all the other interrupts and still come up with the right answer?

    Any Ideas?

    Phil

  • You wrote:

    Terrible compiler. It should work and I should even have to think
    
    about it. I spend more time on the Compiler then I do on the actual program.
    

    But in the end, you don't know standard C and the needs for "extern" to tell the compiler that there exists a variable somewhere, but don't allocate a copy of it in this specific file.

    You have two choices for global variables. Either have a global variable visible only inside a single source file. You do that with a "static" keyword, telling the compiler to hide the linkage information for the variable - basically making the variable into an anonymous, unnamed, global variable.

    Or you can share a global variable between multiple files. In which case you can allocate the variable in one single file. And then let the other files know about it with the "extern" keyword (using header files).

    The above is standard C. It isn't a "terrible compiler" but a minimum requirement for a standards-compliant compiler.

    Have you looked for some good C books? After having gained enough knowledge, it's then time to get the ISO standard.

    Besides that, you also do need to walk through the manual for the Keil C51 compiler, to find out what platform-specific things you must know about.

    When something doesn't work, it's (at least) a 99.99% chance that it is a user error, and not a compiler error. Blaming the tools just hurts you, since that only means you spend your time looking in the wrong direction. In this case, you complained about the time you have spent on the compiler instead of on the program. Maybe that time should have been spent on manuals and the C language instead?

    For debugging, you need to go multiple routes, depending on what problems to look for.

    You can use GPIO with LED to measure the runtime of interrupts.
    You can compute the number of interrupts/second your program needs.
    You can figure out the potential timing problems based on your real-time needs and the interrupt load.

    For finding logic errors, it's normally best to deactivate different parts of the code and try to debug module-by-module.

    You also need to spend time just reading the code. For all interrupts you have, you must look at what global variables they make use of, and make sure that your code can correctly share these variables between the interrupt handler and the main loop code.

    You also have to track down any function call you make from an ISR. Are any of these functions also called from the main loop? If so, the function needs to be reentrant. But it is normally best to duplicate that function and have one copy called by the ISR and one copy called by the main loop. Even then, you must check the usage of global variables and make sure that a switch from main loop to ISR processing at any single point in time will be safe. If it isn't, then you have found a critical section. And critical sections must be protected - in some situations by blocking interrupts while inside the critical section.

  • It appears that across multiple files, one needs the keyword "extern" in from of the prototype

    No, one doesn't need that. If you think you do, either your reasoning is wrong, or you again failed to represent your actual problem in a useful manner.

    the variables become unstable.

    You're still making no sense at all. Either you're talking about prototypes, or you're talking about variables. Can't be both, because prototypes are for functions, not variables.

  • No! As already pointed out, you do not need that!

    See: c-faq.com/.../extern.html

    Therefore, this is not what "fixed" your problem.

    In general, when you don't know what "fixed" a problem, you should assume that it is not fixed; you have probably just (temporarily) masked the symptoms - not fixed the cause.

    "This might also solve some other issues I had with function pointers but that is another topic all together."

    Highly unlikely!

    As already noted, there are far more fundamental issues with function pointer in C51.
    Have you studied those issues yet?

    "my biggest problem is learning what tools work"

    It sounds much more likely that your biggest problem is that you are trying to build a large project without having first grasped the basics of 'C' programming.

    You really need to lay solid foundations before building the upper storeys of the house!

    The tools work - but you have to spend time learning how to use them correctly & effectively.

    "Is there a file that would show memory locations and how they are linked?"

    Yes - it is called the Linker Listing or "map" file.

  • Thank You For the correction.

  • "Therefore, this is not what "fixed" your problem."

    if your assertion is that you don't know what the problem is, you necessarily don't know what "fixed" the problem.

    the op's solution (of using "extern") may not be the right fix for his problem, but that doesn't mean the use of "extern" isn't the fix for his problem.

  • "if your assertion is that you don't know what the problem is, you necessarily don't know what 'fixed' the problem"

    No, that wasn't my assertion.

    My "therefore" referred to the fact that 'extern' is entirely redundant on a function prototype; that's why it directly followed my citation of c-faq.com/.../extern.html

    Since the presence or absence of the 'extern' makes no difference to a function prototype, it follows that adding (or removing) 'extern' to (or from) function prototypes cannot have been the fix to the OP's problem.

    I then went on to say:

    "In general, when you don't know what "fixed" a problem, you should assume that it is not fixed; you have probably just (temporarily) masked the symptoms - not fixed the cause"

  • "it follows that adding (or removing) 'extern' to (or from) function prototypes cannot have been the fix to the OP's problem."

    just because it cannot fix the problem doesn't mean that it doesn't fix the problem.

    Of all the people, you are the one who generalized that sometimes not all things work per specification / logic / etc., in another thread.

    just because it isn't supposed to work doesn't by itself mean that it doesn't work. and in this case, the OP's experience trumped your "logic".

  • No, I never said that.

    "just because it cannot fix the problem doesn't mean that it doesn't fix the problem"

    Eh??!

    If it cannot fix the problem then, by definition, it did not fix the problem!

    Most likely, some other change that also happened (intentionally or otherwise) in the process of adding/removing the 'extern' is what caused the change of behaviour.

    And, again, the "change of behaviour" may be just a masking of the symptoms - not a fix of the problem.