Show Posts
Pages: 1 ... 69 70 [71] 72 73 ... 121
1051  Using Arduino / Programming Questions / Re: A function to handle multiple datatypes on: November 04, 2012, 04:25:23 am
No, a pointer would be disastrous.  p would be an address to a pointer.

You can overload the function, but still isn't sufficient for arrays.
/*May cause ambiguities occur, if so the function prototypes need more specific matches. ( all constant data can be accessed via references, so constant pointers may not be able to match a higher overload.*/
template <typename T> void sendAnything (const T& value)
  const byte* p = (const byte*) &value;
  for (unsigned int i = 0; i < sizeof( value ); i++)
      Serial.write (*p++);
  }  // end of sendAnything

template <typename T> void sendAnything (const T* value)
    const byte* p = (const byte*) value;
    for (unsigned int i = 0; i < sizeof( T ); i++)
      Serial.write (*p++);

Or partially specialise a class template:
template <typename T> struct Sender{

  static void Send( const T& value ){

    const byte* p = (const byte*) &value;
    for (unsigned int i = 0; i < sizeof( value ); i++)
      Serial.write (*p++);

template <typename T> struct Sender< T* >{

  static void Send( const T* value ){

    const byte* p = (const byte*) value;
    for (unsigned int i = 0; i < sizeof( T ); i++)
      Serial.write (*p++);

You can mix overloads with templates, so you can have a non-template function for char* and templates for everything else.
As with the class method you could do a full specialisation ( different from the partial specialisation above ) for the character arrays.
In the char* specific version, code could check for a null char.
1052  Using Arduino / Programming Questions / Re: A function to handle multiple datatypes on: November 03, 2012, 10:37:25 am
Easy: use a pointer to void.

Guessing you didn't read the whole thread above. Turns out that people seem to have VERY strong opinions as to the use of void pointers to allow you to cast between incompatible types.

I agree there are strong opinions, but for good cause.

Aggression and arguments shouldn't be necessary; this isn't opinion; it is fact. And to follow analogies, its similar to arguing: Its legal to drive across the traffic lights while they are red, simply because you can see no cars.

If you are not considering why we posted our concerns, how about asking for a proof why it is safe. C/C++ is built upon a set of rules; if it is allowed, the standard will state it.

I have been doing some reading of my own and I feel that the void pointer is the best way for me to achieve what I want as I want to totally disregard the type of data and just see it as a stream of bytes.
Good decision.

Not a good decision, this is also wrong, as stated before. Arranged into a different scenario, still, the code below is not valid. There are no if's, or but's, it is just how C++ rolls.

void PrintIntFromStream( void *v_Stream ){
  int *i_StreamPtr = ( int* ) v_Stream;
  Serial.print( "Int aliased from stream: " );
  Serial.println( *i_StreamPtr  );

If you read my post above, I mentioned casting directly to char* is fine, because it is allowed and would fix your code. However the void* breaks the strict aliasing rule and therefore subsequent casts are undefined behaviour.

A large part of the problem is the strict aliasing rule is an addition to the standard, therefore material based on the standard before the addition are rampant throughout the net. Also it is interpreted differently between C and C++, so trying to port broken ideas in C only make things worse in C++.

Take a moment to read this:
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
— a type compatible with the effective type of the object,
— a qualified version of a type compatible with the effective type of the object,
— a type that is the signed or unsigned type corresponding to the effective type of the object,
— a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a sub aggregate or contained union), or
— a character type.

This is an actual excerpt from the standard, if you managed to grasp all that, you may have noticed the last line. This is the rule on which I based my fix for your function. The one basic aliasing tool is char, for reasons such as endianess and alignment ( there is method in their madness ).

There is nothing in that list that explicitly mentions a cast to incompatible types including void* types. The reason your code works ( if it does ) like my example above, is it relies on undefined behaviour. What that actually means is, the code you have written has not met any conditions for optimisations that rely on the strict aliasing rule. When one can be applied the compiler is free to disregard interactions with aliased data. I say 'disregard' with a notion that there are some circumstances where you reverse the optimising capacity of the compiler.

You may say, "'optimisations', this isn't part of the discussion", but guess what, the strict aliasing rule is pretty much specifically for them. This is why you don't get aliasing compile errors, as some of the optimisations are linker based, after the compiler has done its thing. This rule actually matters!!!

For clarity:
Strict aliasing is an assumption, made by the C (or C++) compiler, that dereferencing pointers to objects of different types will never refer to the same memory location (i.e. alias each other.)

Now for the fun part.

Using Arduino IDE 1.5

 - AVR Compiler version 4.3.2
 - Optimisation flags 'Os'

This flag is the compile for size option ( i.e ) removing dead code. It also includes all 'O2' optimisations which include... <drum roll>
-fstrict-aliasing compiler specification which enforces the notion that you obey the rule. The only way to deal with aliased incompatible types safely is through non-portable attributes... Or use C++ properly.
1053  Using Arduino / Programming Questions / Re: A function to handle multiple datatypes on: November 02, 2012, 06:48:01 am
The point is, you don't want to defeat type checking.
Yes. Sometimes you do.
Why do you think compiler-writers built that in?
Equally, why do you think they built in void pointer?

Type checking is very useful, a great invention. Sometimes however, it is nice to be able to side-step it if it gets in your way. C allows that.

Nick's advice is sound. It is a serious flaw expecting C++ behaviour to reflect that of C. You do not want to break type checking by using a void*, there are uses for these types but destroying type safety is not one of them.

The strict aliasing rule must be adhered to, you cannot assume your compiler ( or even subsequent versions of it ) will always provide working 'undefined behaviour'.

Even in the function by Chris Parish,

const byte* p = (const byte*)(const void*)&value;

In this line, the void* cast explicitly breaks the strict aliasing rule, whereas simply casting to char* ( or byte* )  wouldn't.
1054  Development / Other Software Development / AtomicBlock, now for DUE and other platforms. on: November 02, 2012, 12:44:46 am
As the new Due has come out, I have recently updated my AtomicBlock system to now support a few more platforms.

AtomicBlock V1.2 (beta)

Now supports:

AVR 8-bit processors
  • Arduino 8-bit family ( Compiled / Tested )
  • Teensy 2.0 ( Not Compiled / Not Tested )
  • Teensy++ 2.0 ( Not Compiled / Not Tested )
ARM Cortex-M3
  • Arduino DUE ( Compiled / Not Tested )
  • Olimex STM32 / Leaflabs Maple. ( Compiled / Not Tested )
ARM Cortex-M4
  • Teensy 3.0 ( Compiled / Not Tested )


  • C++ compiler required.

The new code is posted on google code here:
I have also uploaded the file to the original post [here].
1055  Development / Other Software Development / Re: Fast alternative to digitalRead/digitalWrite on: November 01, 2012, 05:59:30 am
Oh. You had same problem as I do. Arduino is slow... Well I had another problem. I can't create easy libraries with bare avr c. So I started project to overcome this problem.

As a result I have very nice implementation for digital pins. That is only thing really working yet. Timers and analogRead is next.

Wanted to let you know what I have found out, so here is the project:

Hi, had a look at your library. Seems you are doing similar things to the ideas I'm implementing in my own library. I also noticed you are using a very basic version of my AtomicBlock library. I'm about to release a new version compatible with AVR, AVR32, PIC32, ARM Cortex M/R  if you are interested.
1056  Using Arduino / Programming Questions / Re: Data type confusion on: October 31, 2012, 11:22:15 am
Volatile prevents the compiler from applying certain optimisations that can be unsafe if used between contexts.

The cpu uses registers, so variables in ram are copied to a register for computation. This information isn't tracked, so which does the ISR use; the ram copy or the register. Volatile ensures the register is flushed to ram before it loses context.

So, yes your ISR can be slower as more instructions can be emitted for volatile data.
1057  Using Arduino / Programming Questions / Re: Functions not in reference on: October 31, 2012, 07:06:11 am
SP** are SPI registers.
Here is the SPI documentation:

And 'ISR' reference:
1058  Using Arduino / Programming Questions / Re: Get program size (flash used) RUNTIME - possible? on: October 30, 2012, 08:34:31 am
Like AWOL said, this is not a very useful piece of information, however someone on the forum came up with this:

extern int _etext;
extern int _edata;
static inline unsigned SketchSize() { return (unsigned)(&_etext) + ((unsigned)(&_edata) - 256); }
1059  Using Arduino / Programming Questions / Re: Why do functions not work when I call them? on: October 28, 2012, 09:55:23 pm
is a function pointer

is a function call
1060  Development / Other Software Development / Re: BOARD preprocessor directives from IDE on: October 28, 2012, 10:06:34 am
Here is something I use, original was from fat16lib's original DigitalPin library

// 168 and 328 Arduinos
#if defined(__AVR_ATmega168__) ||defined(__AVR_ATmega168P__) ||defined(__AVR_ATmega328P__)
  #define CHIPSET ATmega_168_168P_328P

// Mega 1280 & 2560
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  #define CHIPSET ATmega_1280_2560

// Sanguino
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
  #define CHIPSET ATmega_644_644P_1284P

#elif defined(__AVR_ATmega32U4__)

  // Teensy 2.0
  #ifdef CORE_TEENSY
    #define CHIPSET ATmega_32U4_A

  // Teensy
    #define CHIPSET ATmega_32U4_B

  // Teensy++ 1.0 & 2.0
  #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
    #define CHIPSET AT90USB_646_1286

Just replace the CHIPSET defines with your platform specific stuff.

Here is a link to a thread on detecting the Due.,128520.0.html
1061  Using Arduino / Programming Questions / Re: Trying to use binary number (B10000) in lib and getting error. on: October 27, 2012, 02:44:51 am
Here is a link to a post I made on Tom Torfs binary number macros.
It allows similar '0b' notation but is not compiler specific.,93201.msg700368.html#msg700368
1062  Products / Arduino Due / Re: Identifying Due in Libraries on: October 27, 2012, 02:15:09 am
Hi all, I'm updating my AtomicBlock library for the Due, the update contains versions for 'ARM' and the 'Cortex M3' variant. However I can't find any defines to conditionally decide which to use.

Is there a macro like _TARGET_ARCH_xx or similar?
1063  Products / Arduino Due / Re: random number generator (TRNG) API ? on: October 25, 2012, 07:43:19 pm
I can't answer your question, but thanks for pointing me to the system register definitions. Hadn't looked in the Devices folder of CMSIS.
1064  Products / Arduino Due / Re: USB fash drives and HDD on: October 25, 2012, 06:01:44 am
After looking for AT91 and USB 'on the go' specifics with little success, I noticed the USBHost library provided in the IDE download uses a library from circuits@home:

There is already a mass storage interface there, weather it works or not I do not know ( someone who has used the USB host shield may be able to answer this. )

Editing it shouldn't be too hard if modifications are needed. It will still need a library on top to provide a 'client' interface. The mass storage interface is just implementing a way of sending/receiving commands/data too and from a USB device that supports the MSD protocol, not much in the way of file system control.

1065  Using Arduino / Programming Questions / Re: warning: internal error: out of range error on: October 25, 2012, 03:18:54 am
I bet there is plenty to optimise, 555K in one file pretty much guarantees you have added inefficiencies to your app, too hard to maintain properly.

What scientific stuff are you doing, the due will have different timings and accuracies, and no AVR specific code will port.
Post your code, I bet we can shave off some kb.
Pages: 1 ... 69 70 [71] 72 73 ... 121