1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

Accessing global var of another file

Discussion in 'Embedded' started by galapogos, Oct 19, 2006.

  1. galapogos

    galapogos Guest

    Hi,

    I have a multi-file project and in main.c I have a global array to
    store a string of characters. In my main function I call function
    i2c_send from another file(i2c.c) that sends this string over i2c.
    Naturally, my i2c isr is in i2c.c, and naturally it needs to write the
    string into the i2c buffer for the transmission to begin. Since I can't
    pass the string into the isr as a parameter, the string within i2c has
    to be a global. Short of doing a strcpy in my i2c_send function, what
    can I do to let my isr refer to the string in main.c and copy that into
    the i2c buffer?
     
    galapogos, Oct 19, 2006
    #1
    1. Advertisements

  2. Pass a pionter to that string when calling i2c_send()...

    Meindert
     
    Meindert Sprang, Oct 19, 2006
    #2
    1. Advertisements

  3. galapogos

    Neil Guest

    you need "extern"

    i.e. extern char *MyBuffer;

    Take care using library functions in interrupts. Not all are
    re-entrant. Check the docs.
     
    Neil, Oct 19, 2006
    #3
  4. galapogos

    galapogos Guest

    Thanks for the warning, but I don't think I'll be calling any functions
    from my ISRs, just playing around with registers.
     
    galapogos, Oct 19, 2006
    #4
  5. galapogos

    galapogos Guest

    How would i2c_send save it in a static pointer? I don't quite get that
    point. You mean create another global string var in i2c.c and do a
    strcpy?
     
    galapogos, Oct 19, 2006
    #5
  6. Just saving the pointer to the string in the i2c.c send function seems
    a bit dangerous. What if the string is local (stack) variable and the
    stack has changed before the i2c interrupt handler has actually
    transmitted the bytes?

    To be safe, I think i2c_send() has to copy the string to a static
    variable and set a flag so that a subsequent call to i2c_send
    can't accept another string until the first has been transmitted by
    the interrupt routine. The other alternative is that i2c_send and
    the isr implement a queue to handle the input strings until the
    isr can send them.

    Mark Borgerson
     
    Mark Borgerson, Oct 19, 2006
    #6
  7. galapogos

    Thad Smith Guest

    I agree. In general, your i2c module shouldn't know or care who calls
    i2c. That design philosophy makes it much easier to use code for other
    applications. The pointer can be saved by i2c_send in a static pointer
    within ic2.c that the interrupt routine can access.
     
    Thad Smith, Oct 19, 2006
    #7
  8. galapogos

    galapogos Guest

    I see what you mean. However, for my application, i2c_send() only needs
    to send an n-byte data once in the entire program lifetime, and will
    never be called again. Since that is the case, I think I would be able
    to get away with not dealing with this case. I guess then I won't need
    to copy or even create a static variable within i2c_send, but use the
    pointer that is passed in by main?
     
    galapogos, Oct 20, 2006
    #8
  9. galapogos

    Thad Smith Guest

    Yes, you could do that. The difference is the specified interface.

    In the first case (save pointer), you specify that the contents of the
    buffer must remain intact until the transmission is complete. You would
    probably have another function to determine whether the transmission is
    complete. The caller must insure that the data remains intact, so can't
    be an auto array of a function that is being exited before completion.
    The advantages of this approach are that the data doesn't have to be
    copied, so runs faster, doesn't need to use dynamic memory allocation or
    set at arbitrary size limit.

    In the second case (save data), the interface to the caller is simpler,
    since the data is saved by the call. The disadvantage is that you need
    additional memory and either dynamic memory allocation (usually best
    avoided in small embedded applications) or a fixed maximum size. If you
    know the maximum length for your application and can dedicate a buffer,
    it works well.
     
    Thad Smith, Oct 20, 2006
    #9
  10. I would follow Neil's suggestion, but skip the pointer entirely. You
    don't need a pointer.

    Just prefix the definition of the global buffer with the word "extern".
    Note that if you do this, the compiler will not know that it should
    force the buffer to "actually exist" for the linker, so the linker will
    go looking for it and not find it. After all, when the compiler sees
    the word "extern", it will think that you are telling it that the
    global buffer is defined in another file. To say, "No, I want it to be
    visible elsewhere, *and* I want you to make the space, you have to
    initialize it. Putting zeros in it would suffice: "

    extern char global_buffer[512] = {0}; // put 512 zeros in it

    This act of initializing the buffer forces the compiler to make some
    meat for the linker to use.

    In the file that handles the interrupt, do the same, but this time
    don't initialize:

    extern char global_buffer[512];

    -Le Chaud Lapin-
     
    Le Chaud Lapin, Oct 24, 2006
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.