Pages: [1] 2   Go Down
Author Topic: Arduino pointer-to-function broken? Compiler Issue?  (Read 1987 times)
0 Members and 1 Guest are viewing this topic.
Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi there!
I am having very strange crashes in when using a combination of Messenger, the SD library and function pointers. The sketch is a bit involved to upload, but I have a couple of things that are, definitely, not right (or I am doing something very silly or there's something I don't understand)

The function pointers look like this:

Code:
typedef void (* HandlerFuncPtr)() ; // this is a typedef to the messenger functions
HandlerFuncPtr functions[4] = {DisplayBatteryData, TimeDate,SDInfo,ReadFile};
with all those functions being global static ones.

I compile my sketch with this function:

Code:
void messageCompleted()
{
    for (unsigned char c = 0; c < sizeofarray(commands); c++)
    {
        if(message.checkString(commands[c]))
        {
            functions[c]; //Were we go
            return;
        }
    }
    Serial << "ERROR: Couldn't parse message, commands are" << endl;
    ListCommands();
}
Which obviously does nothing at the funcion[c], because it is not calling the function itself.

What is funky about it, is that, if I add "()" behind
Code:
functions[c]();
the program goes from 18960 bytes to 21070 and becomes super unstable.

Any ideas?
« Last Edit: September 13, 2011, 06:42:18 am by rod.lopez » Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 72
Posts: 3763
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What type is commands? If it isn't an array of  bytes, this: sizeofarray(commands) may be giving you trouble. If it isn't evaluating to four, you'll be overrunning  your functions array. That would definitely cause some serious instability.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the program goes from 18960 bytes to 21070 and becomes super unstable.
I'm guessing you're using too much RAM.
But that's just a guess.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50924
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Which obviously does nothing at the funcion[c], because it is not calling the function itself.
True.

Quote
What is funky about it, is that, if I add "()" behind
the program goes from 18960 bytes to 21070 and becomes super unstable.
You are now actually calling the functions, so, of course the size goes up.

That your sketch becomes unstable is a surprise. Does it often wobble around and fall over? How can you see that happening?

Quote
The sketch is a bit involved to upload, but I have a couple of things that are, definitely, not right (or I am doing something very silly or there's something I don't understand)
Developing this much code without an understanding of you are doing is definitely classified as very silly. There is probably a lot that you don't understand.

There is a lot we don't understand, like how your code can become unstable and fall over.

Perhaps you need to post all of your code, and explain what exactly it is doing wrong.
Logged

Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What type is commands? If it isn't an array of  bytes, this: sizeofarray(commands) may be giving you trouble. If it isn't evaluating to four, you'll be overrunning  your functions array. That would definitely cause some serious instability.

Commands is a list of char*, such as:
Code:
char* commands[4]           = {"battery", "timedate","sdinfo","readfile"};

In any case,  sizeofarray does take care of granularity, though;
Code:
template<typename T>
int sizeofarray(T& obj)
{
        return sizeof(obj)/sizeof(obj[0]);
};

the result is always four smiley
Logged

Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quote
What is funky about it, is that, if I add "()" behind
the program goes from 18960 bytes to 21070 and becomes super unstable.
You are now actually calling the functions, so, of course the size goes up.
Yeah, I didn't think about the compiler optimizing the functions away.

Quote
That your sketch becomes unstable is a surprise. Does it often wobble around and fall over? How can you see that happening?
It sometimes hangs up, sometimes reboots, sometimes displays corrupted data (as, if I try to list the array of char* I see a partly corrupted result.

Quote
Quote
The sketch is a bit involved to upload, but I have a couple of things that are, definitely, not right (or I am doing something very silly or there's something I don't understand)
Developing this much code without an understanding of you are doing is definitely classified as very silly. There is probably a lot that you don't understand.
Sorry, I didn't quite get that comment. I mean that certain behaviors of the program don't make sense. I am not quite a newbie, if that's your assumption smiley
Quote
Perhaps you need to post all of your code, and explain what exactly it is doing wrong.
The main issue that I have is that it doesn't seem to happen with any one system. Only when I use function pointers AND access the SD card do I get issues, it is a bit maddening to be frank.
But if you think that will help and somebody will read it, sure.
« Last Edit: September 13, 2011, 08:26:14 am by rod.lopez » Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 653
Posts: 50924
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But if you think that will help and somebody will read it, sure.
We can also check out AWOL's quite possibly correct suspicion that you are running out of SRAM, so, yes, post the code.
Logged

Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, I've been thinking about that too, the fact that things only fail when I put several systems together has made me think.
Eventually I've figured out it was a SD information function that was designed to open the SD card from scratch (after it was already open) which was leading to a couple of bad bugs AND the out of memory.
I have added a freemem() function to track things down, I am running at 200 bytes, which I find very, very scary smiley-sad
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 76
Posts: 7305
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Any string literals floating in SRAM should find their own places in the FLASH now.
Logged


Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Any string literals floating in SRAM should find their own places in the FLASH now.

Hi liudr, what do you mean exactly? You are talking about the flash memory I guess, is that something the compiler decides before the code runs? So in theory if can increase the string sizes and have no changes in the available RAM, am I right?
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Serial << "ERROR: Couldn't parse message, commands are" << endl;
That string there looks like it should go into flash, because it is a constant (and it does), but it get copied to before "main" runs.
If you have lots of strings like that, they'll gobble up RAM.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What do you mean by "it gets copied to before "main" runs?
...and, it sounding like a bad thing, how do I avoid it? smiley
Logged

Offline Offline
God Member
*****
Karma: 4
Posts: 813
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't see anyone mention this explicitly:

Code:
functions[c]; //Were we go

This will not call the function; it just evaluates to the value of the function pointer. Because that is evaluated but never used, the compiler/linker can actually optimize out the entire functions array, as well as the functions that go into that array! Therefore your program is small.

Thus, when you add the parens after the function pointer, your program actually does what I think it is you want -- use the function pointer table as a vector of functions to call in response to a particular command.
Logged

Stockholm
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Silicon puppeteer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I didn't see anyone mention this explicitly:

Code:
functions[c]; //Were we go

This will not call the function; it just evaluates to the value of the function pointer. Because that is evaluated but never used, the compiler/linker can actually optimize out the entire functions array[...]in response to a particular command.


Agreed, I ended up mentioning it myself smiley
thanks for the input!
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26632
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, it should have read 'it gets copied to RAM before 'main' runs'.

How to avoid that?
Use 'PROGMEM'.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: