Accessing global var of another file

Started by galapogos October 19, 2006
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" <goister@gmail.com> wrote in message
news:1161228715.958607.254020@m73g2000cwd.googlegroups.com...
> 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?
Pass a pionter to that string when calling i2c_send()... Meindert
galapogos wrote:
> 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? >
you need "extern" i.e. extern char *MyBuffer; Take care using library functions in interrupts. Not all are re-entrant. Check the docs.
Neil wrote:
> galapogos wrote: > > 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? > > > you need "extern" > > i.e. extern char *MyBuffer; > > Take care using library functions in interrupts. Not all are > re-entrant. Check the docs.
Thanks for the warning, but I don't think I'll be calling any functions from my ISRs, just playing around with registers.
Thad Smith wrote:
> Meindert Sprang wrote: > > "galapogos" <goister@gmail.com> wrote in message > > news:1161228715.958607.254020@m73g2000cwd.googlegroups.com... > > >>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? > > > > Pass a pionter to that string when calling i2c_send()... > > 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
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?
Meindert Sprang wrote:
> "galapogos" <goister@gmail.com> wrote in message > news:1161228715.958607.254020@m73g2000cwd.googlegroups.com...
>>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? > > Pass a pionter to that string when calling i2c_send()...
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
In article <1161267628.779765.193650@e3g2000cwe.googlegroups.com>, 
goister@gmail.com says...
> > Thad Smith wrote: > > Meindert Sprang wrote: > > > "galapogos" <goister@gmail.com> wrote in message > > > news:1161228715.958607.254020@m73g2000cwd.googlegroups.com... > > > > >>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? > > > > > > Pass a pionter to that string when calling i2c_send()... > > > > 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 > > 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? > >
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 wrote:
> In article <1161267628.779765.193650@e3g2000cwe.googlegroups.com>, > goister@gmail.com says... > > > > Thad Smith wrote: > > > Meindert Sprang wrote: > > > > "galapogos" <goister@gmail.com> wrote in message > > > > news:1161228715.958607.254020@m73g2000cwd.googlegroups.com... > > > > > > >>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? > > > > > > > > Pass a pionter to that string when calling i2c_send()... > > > > > > 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 > > > > 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? > > > > > 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
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?
Mark Borgerson wrote:
> In article <1161267628.779765.193650@e3g2000cwe.googlegroups.com>, > goister@gmail.com says... > >>Thad Smith wrote: >> >>>Meindert Sprang wrote:
>>>>Pass a pionter to that string when calling i2c_send()... >>> >>>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. >>> >>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? > > 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.
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
galapogos wrote:
> Neil wrote: > > you need "extern" > > > > i.e. extern char *MyBuffer; > > > > Take care using library functions in interrupts. Not all are > > re-entrant. Check the docs. > > Thanks for the warning, but I don't think I'll be calling any functions > from my ISRs, just playing around with registers.
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-