Show Posts
|
|
Pages: 1 ... 3 4 [5] 6
|
|
62
|
Using Arduino / Programming Questions / Re: Reason for missing new() / delete()?
|
on: October 05, 2011, 07:24:14 am
|
The sense I get is that if you're writing a library, you should use malloc/free (and in fact, you may have to, since new/delete are gone). If you're writing a sketch for a particular purpose (i.e., the majority of Arduino developers), you should use singleton variables or fixed-size arrays, and not malloc/free/new/delete.
Well said! I think this sums it up nicely, and reflects my conundrum. I'm writing a library, so I have the need to use dynamic memory (and to use a new/delete provided on the Internet). If I was writing a sketch for something static, then yes I may prefer to use fixed-size arrays.
|
|
|
|
|
63
|
Using Arduino / Programming Questions / Re: Reason for missing new() / delete()?
|
on: October 03, 2011, 09:20:45 am
|
Can anyone give me a concise reason that Arduino is missing new() and delete()? Because in a RAM-constrained embedded environment, you shouldn't be using them. (Contentious, or what?) That's what I thought. But then one ends up with this: static PCintPin pinDataAlloc[MAX_PIN_CHANGE_PINS]; as I mention above. If I create a library which depends on the other library, and I essentially hide the details of the other library, now I've got an issue because the developer who uses my library has to deal with implementation-specific details, such as the fact that if they don't understand the library that I'm using, they won't know to change MAX_PIN_CHANGE_PINS. So they'll either A) be wasting the very RAM that our new()-less environment was supposed to conserve, or B) end up with a weird bug. Indeed, in my AdaEncoder library, I dealt with the absence of new() by creating a linked list of structures using malloc(). And when all was said and done, I said to myself, "Damn, all this malarkey I had to go through to use malloc() in a C-stylin' kind of way, rather than just using new(). And did it avail me anything? I mean, what's the big difference between a struct and a class anyway? According to Stroustroup, a class is essentially a struct..." ...Of course, this is the very contention you're alluding to. 
|
|
|
|
|
64
|
Using Arduino / Programming Questions / Re: Reason for missing new() / delete()?
|
on: October 03, 2011, 07:57:40 am
|
BTW, according to this article: http://arduinoetcetera.blogspot.com/2010/04/implementing-new-and-delete-c.html which points more importantly to this discussion: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=410870, the new() operator can be a little more involved because if you are using gcc 4.x and newer (I didn't check it with older versions) and you want to use templates, virtual inheritance and so on you must define some additional functions, which is not used now by compiler, but must be present to satisfy linker So the final code should look like: #ifndef cppfix #define cppfix
#include <stdlib.h>
__extension__ typedef int __guard __attribute__((mode (__DI__)));
void * operator new(size_t size); void operator delete(void * ptr);
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);}; void __cxa_guard_release (__guard *g) {*(char *)g = 1;}; void __cxa_guard_abort (__guard *) {};
void * operator new(size_t size) { return malloc(size); }
void operator delete(void * ptr) { free(ptr); }
#endif
|
|
|
|
|
65
|
Using Arduino / Programming Questions / Re: Reason for missing new() / delete()?
|
on: October 03, 2011, 07:53:10 am
|
Thanks, Nick. I feel better about feeling bad about not having new(), and wanting to implement it in apparent violation of the wishes of the IDE developers. As a matter of fact, what the developers of the PinChangeInt library did was allocate space ahead of time, by defining an array of objects: static PCintPin pinDataAlloc[MAX_PIN_CHANGE_PINS]; ...developers who use this library need to poke around in the .h files to discover what MAX_PIN_CHANGE_PINS does, and set it appropriately. If one neglects to do so, and leaves MAX_PIN_CHANGE_PINS at its default of 8, then if you use this library to catch interrupts on 1 pin, space is allocated for 7 extra PCintPin objects that you won't use. And I, creating a library that uses this library, now have to expose gory details to the developer when I'd rather they have a nice easy interface. I'd much rather use a dynamically-created linked list and have it grow as large or as small as I need. But I preach to the choir. In short: thanks. I'm going to use new() guilt-free. 
|
|
|
|
|
66
|
Using Arduino / Programming Questions / Reason for missing new() / delete()?
|
on: October 02, 2011, 11:33:19 pm
|
|
Hi, Can anyone give me a concise reason that Arduino is missing new() and delete()?
I am finding that I need to jump through hoops to create static methods to do some things, because I can't allocate C++ classes... I need to use malloc() on some data structures.
After having done so, I can only think... "Geez, I wish I had new()".
BTW, I know that there is a new() operator implementation out there such that I can define it myself and I plan to use it... barring a good "Only n00bs use new(), that's why it's left out of the Arduino C++ stuff" explanation.
Thanks.
|
|
|
|
|
67
|
Using Arduino / Programming Questions / Re: C++ getting address of a function
|
on: September 25, 2011, 06:31:55 am
|
You can get the address of a function easily enough. Test case ... Header file (functionheader.h): ... However having said that, you seem to be wanting to take the address of a member function of a class. In this case the function address isn't enough, you need the class instance address too (ie. the "this" variable).
Isn't this a bit convoluted for an ISR? Somehow taking the address of a function which is a class member?
Unfortunately I am having trouble with C++, not C. So I agree that taking addresses of functions is easy, but I want to do it in a C++ kind of way. According to http://www.newty.de/fpt/fpt.html#call , it should be easy: int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++
but as you can see, I get the "was not declared in this scope" error. I wouldn't expect that calling an object's function by reference in an ISR would be so convoluted. To me, it makes perfect sense. ...Oh, I know what you're thinking: "GreyGnome, silly, the interrupt is an out-of-band action, divorced from normal flow of your sketch. How would you expect that to work???" Well hear me out a second: When I used PinChangeInt to create my rotary encoder library, I noticed that I was doing some convoluted actions to get it to work. I also noticed that I was doing convolutions on top of convolutions. In other words, the library works by: - Calls the interrupt vector for the PORT on which the interrupt occurred (vector 0, 1, or 2).
- The vector function figures out what pin caused the interrupt.
- Based on that pin, call the user-defined function.
Well, because of the fact that the library was designed to call a user-defined function in a C way (ie, no this pointer allowed), I needed to create a static function. That is: - The third step above was useless, because the user-defined function was always the same. So trying to determine a pin-to-function correlation was unnecessary work.
- I needed to repeat the second step in my static function. That is, in my static function I figured out what pin caused the interrupt. Additionally,
- I created another array of structures containing all the encapsulated data I needed for each individual pin, so that the static function would grab the pin-specific structure from the array, then perform the proper functions.
It is because I performed that last item that I am looking to do it differently now. Because what is a "structure containing all the encapsulated data"? ...Seems to me, they call that a "class".  In other words, by using the Arduino it seems I must forgo the benefits that C++ classes bring to me and jump back into C. But as a relative n00b I'm not yet comfortable doing that. If I was able to have the interrupt routine - Call the interrupt vector for the PORT on which the interrupt occurred (vector 0, 1, or 2).
- The vector function figures out what pin caused the interrupt.
- Based on that pin, call a class's method.
Then, based on the fact that a class is an encapsulation of my data and the actions I want to perform on that data, I think this way is a lot cleaner. At least, it's more object-oriented.
|
|
|
|
|
68
|
Using Arduino / Programming Questions / Re: C++ getting address of a function
|
on: September 25, 2011, 06:08:42 am
|
I am i wrong? maybe i am but i'm sure with arduino a class does need to be in it's own file and also i thought that constructors weren't allow? Well not in arduino anyway. You have to create a function to set all the stuff you would normally set in the constructor.
If what you say is true, this wouldn't work. But it does: #include <PinChangeInt.h>
#define TESTPIN 4
class it { int aPin; public: it(int arduinoPin); void onInterrupt(void); private: };
it::it(int arduinoPin) { aPin=arduinoPin; }
void it::onInterrupt(void) { Serial.print ("Test of class and constructor created in sketch... WORKS! "); Serial.println(aPin, DEC); };
it testIt=it(TESTPIN);
void setup () { Serial.begin(115200);
testIt.onInterrupt(); }
void loop () { delay(1000); }
...The output is, "Test of class and constructor created in sketch... WORKS! 4" So we have both a class created in a sketch, with a constructor.
|
|
|
|
|
69
|
Using Arduino / Programming Questions / Re: C++ getting address of a function
|
on: September 24, 2011, 01:55:20 pm
|
|
Thanks for the reply, but I don't think we're there yet...
The it::it() is actually a constructor for the class.
I don't know why a class would need to be in its own file. As a matter of fact, I don't get any complaints about my class until I try to get a pointer to a function in the class. So the class seems to work. It's true that for a library you certainly want to organize your work but I don't think that's a requirement imposed by ide or compiler.
|
|
|
|
|
71
|
Using Arduino / Programming Questions / C++ getting address of a function
|
on: September 24, 2011, 12:20:16 pm
|
Hi, I am trying to get the address of a function so as to send it to another function upon interrupt. However, I get "(my function) was not declared in this scope." According to http://www.newty.de/fpt/fpt.html#call, calling a function using a function pointer seems to be pretty easy but I am at a loss. Can you help correct my syntax? Thanks. BTW the below code is just a stub. I want to get past this compiler issue before I move on into the meat of what I'm attempting to do. #include <PinChangeInt.h>
#define TESTPIN 4
class it { int aPin; public: it(int arduinoPin); void onInterrupt(void); private: };
it::it(int arduinoPin) { aPin=arduinoPin; }
void it::onInterrupt(void) { Serial.println(aPin, DEC); };
void setup () { Serial.begin(115200); it testIt=it(TESTPIN); testIt.*onInterrupt; // ERROR here, and/or below (if I uncomment the below). // PCintPort::attachInterrupt(TESTPIN, (testIt.*onInterrupt), CHANGE); }
void loop () { delay(1000); }
|
|
|
|
|
73
|
Using Arduino / Programming Questions / Using cli() and sei() in a library
|
on: September 02, 2011, 04:36:40 pm
|
Hi, I have some library code in which I need to disable interrupts for a short moment. When I try to use cli() / sei(), I get: /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp:290: error: 'cli' was not declared in this scope /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp:295: error: 'sei' was not declared in this scope
I find that I cannot include interrupt.h in my library .cpp file, either (this would be the interrupt.h from AVR library, which on Mac is in /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/etc/options/gcc-version/include/avr/interrupt.h). Can anyone explain why cli() / sei() are not able to be used in my library? Is there a way I can include an AVR .h file, or anything I can do that would be more elegant that, say, copying the macros from the interrupt.h file? Thanks.
|
|
|
|
|
74
|
Using Arduino / Programming Questions / Re: Need to call an uninstantiated method from object method
|
on: August 09, 2011, 07:44:40 am
|
Thanks, that helps. But now I need to pass "this" as an argument to my function. The function is specified in the PinChangeInt.h like this: typedef void (*PCIntvoidFuncPtr)(void); So I have tried to do this: typedef void (*PCIntvoidFuncPtr)(void *); So that I can do this in my Class: PCintPort::attachInterrupt(pinA, interruptWrapper((void *) this), CHANGE); but I get this error: /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp: In member function 'void AdaEncoder::attachInterrupt(int, int)': /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp:68: error: invalid use of void expression if I do: PCintPort::attachInterrupt(pinA, &interruptWrapper((void *) this), CHANGE); I get this: /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp: In member function 'void AdaEncoder::attachInterrupt(int, int)': /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp:68: error: lvalue required as unary '&' operand I can't figure out how to pass this through my static wrapper so as to open up the world of possibilities to me! I need it so that I know which object the interrupt applies to. Thanks again.
|
|
|
|
|
75
|
Using Arduino / Programming Questions / Need to call an uninstantiated method from object method
|
on: August 09, 2011, 12:04:32 am
|
Hi, I am using the PinChangeInt library to set up a number of interrupts for a (relatively) arbitrary number of rotary encoders on my Arduino Uno. I am creating my own Encoder library, which relies on the PinChangeInt library. I have a call in my Encoder library that looks like this: void AdaEncoder::attachInterrupt(int pinA, int pinB) { PCintPort::attachInterrupt(pinA, encoderInterrupt, CHANGE); } Note the AdaEncoder::attachInterrupt() method, above, is not static. But the PCintPort::attachInterrupt() method is. I have a stub encoderInterrupt() method: void encoderInterrupt() {}
The error I get is this: /Users/schwager/Documents/Arduino/libraries/AdaEncoder/AdaEncoder.cpp:65: error: no matching function for call to 'PCintPort::attachInterrupt(int&, <unresolved overloaded function type>, int)' /Users/schwager/Documents/Arduino/libraries/AdaEncoder/../PinChangeInt/PinChangeInt.h:87: note: candidates are: static void PCintPort::attachInterrupt(uint8_t, void (*)(), int) I think what I have to do is make the encoderInterrupt() method static, but I'd like to avoid that. Is there any way I can do so? Or do I need to make encoderInterrupt() static, then solve my problem by utilizing static pointers or arrays? Thanks.
|
|
|
|
|