accessing a variable in wiring.c

I have a more complicated problem, but will start simple here. Down in wiring.c, the following variable is defined:

volatile unsigned long timer0_millis = 0;

and is directly accessible in a sketch, for instance:

-- in my sketch:
extern volatile unsigned long timer0_millis;

void loop() 
{
    Serial.println( timer0_millis );
    delay(2000);   
}

I could not find any other extern references to timer0_millis, say in Arduino.h where the prototype for millis() is located. Is there somewhere else I need to look?

What I am wanting to do is define another variable for my own use in wiring.c, and which will be modified inside ISR(TIMER0_OVF_vect). However, if I treat my variable the same way that timer0_millis is treated, the linker cannot find it when I compile the sketch. What am I missing here? IE,

-- added to wiring.c:
volatile unsigned long eCnt=0;

-- in my sketch:
extern volatile unsigned long eCnt;

void loop() 
{
    Serial.println( eCnt );
    delay(2000);   
}

The “make” process the IDE uses does not actually evaluate dependencies on the wiring.c file. Updating it will not automatically cause it to be rebuilt when you next compile. You will have to use -compile (I think it’s shift - it might be ) and the detailed info about the build will scroll by. Get the temp folder name being used for the compile, go there and nuke everything. The next time you build the IDE will build everything and your wiring.c change will then be compiled.

Thanks gardner, I always use verbose compile mode, and had already tried deleting all of the temp directories. I just tried again for good measure, and it still doesn't work. Exit IDE, delete all \temp_dirs, save changes to wiring.c,etc, reopen IDE&sketch, but it still shows 'undefined reference' to the variables, which I assume means fails at the link stage. So still boggled ???

Besides this, I've also wanted to create new functions in wiring.c to call from my sketches. So, I tried creating the functions, and added prototypes to Arduinio.h, just like as done for millis(), etc, but this also doesn't work. The sketch cannot find the functions. So ???

For reference, my basic plan for all this was to hack into ISR(TIMER0_OVF_vect), and make some minor changes [ie, use to modify the above mentioned variables], and then access the variables from my sketches. I did find that the changes in the ISR are made ok, by [temporarily] rewriting the existing micros() function to return the values, but I cannot figure out how to directly reference the variables or the new functions themselves. Has to be something simple that I'm missing.

Hmm. I am unsure what the problem could be. I have done exactly the sort of thing you are trying and had no serious difficulty.
eg: http://forum.arduino.cc/index.php?topic=172529.0

With the wiring.c changes noted in that thread, I can build this sketch without error:

extern volatile unsigned long timer0_sec;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly: 
  Serial.println(timer0_sec);
}

Maybe the extern "C" {} notation is needed for some reason. eg:

extern "C" { extern volatile unsigned long timer0_sec; }

This also builds okay for me.

The extern "C"{} business doesn't work either. I'll try your sketch from the other thread tomorrow to see how it goes. It's gotta be something simple. Thanks.

It is probably something else, time to post your code I thik. This worked fine ( on version 1.5.7 ):

volatile int test_var = 0x1234;
extern volatile int test_var;

void setup() {
  Serial.begin( 9600 );
  Serial.println( test_var, HEX );
}

void loop() {}

oric_dan:
The extern "C"{} business doesn't work either. I'll try your sketch from the other thread tomorrow to see how it goes. It's gotta be something simple. Thanks.

Please post your entire sketch (or one that demonstrates the problem).

There's nothing to it - same as the other guys - maybe I'm just going batty - and time to sleep. Am using IDE v.1.05 here.

The timer0_millis part works fine.

/*
file: test_ecnt
revised: 09/24/14.
************************************************/

extern volatile unsigned long eCnt1;
extern volatile unsigned int eCnt2;
extern volatile unsigned long timer0_millis;

void setup() 
{
  Serial.begin(57600);
}

void loop() 
{
  Serial.println( eCnt1 );
  Serial.println( timer0_millis );
  delay(2000); 
}

Mods to wiring.c

volatile unsigned long timer0_overflow_count = 0;
volatile unsigned long timer0_millis = 0;
static unsigned char timer0_fract = 0;

//ADDED 09/24/14.
volatile unsigned long eCnt1=0;
volatile unsigned int eCnt2=0;
 
 
#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
	// copy these to local variables so they can be stored in registers
	// (volatile variables must be read from memory on every access)
	unsigned long m = timer0_millis;
	unsigned char f = timer0_fract;

	m += MILLIS_INC;
	f += FRACT_INC;
	if (f >= FRACT_MAX) {
		f -= FRACT_MAX;
		m += 1;
	}
	timer0_fract = f;
	timer0_millis = m;
	timer0_overflow_count++;
	
	//ADDED 09/24/14.
	eCnt1++;
	eCnt2++;
}

Errors

C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega1284p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -IC:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\cores\standard -IC:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\variants\tredici C:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\cores\standard\WMath.cpp -o C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\WMath.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega1284p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -IC:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\cores\standard -IC:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\variants\tredici C:\Documents and Settings\Wanderer\My Documents\Arduino\hardware\tredici\cores\standard\WString.cpp -o C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\WString.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\WInterrupts.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\wiring.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\wiring_analog.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\wiring_digital.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\wiring_pulse.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\wiring_shift.c.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\CDC.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\HardwareSerial.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\HID.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\IPAddress.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\main.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\new.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\Print.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\Stream.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\Tone.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\USBCore.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\WMath.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-ar rcs C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\WString.cpp.o 
C:\winapps\ArduinoIDE\v1.0.5\hardware\tools\avr\bin\avr-gcc -Os -Wl,--gc-sections -mmcu=atmega1284p -o C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\test_ecnt.cpp.elf C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\test_ecnt.cpp.o C:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp\core.a -LC:\DOCUME~1\Wanderer\LOCALS~1\Temp\build2553182313848906727.tmp -lm 
test_ecnt.cpp.o: In function `loop':
C:\winapps\ArduinoIDE\v1.0.5/test_ecnt.ino:18: undefined reference to `eCnt1'
C:\winapps\ArduinoIDE\v1.0.5/test_ecnt.ino:18: undefined reference to `eCnt1'
C:\winapps\ArduinoIDE\v1.0.5/test_ecnt.ino:18: undefined reference to `eCnt1'
C:\winapps\ArduinoIDE\v1.0.5/test_ecnt.ino:18: undefined reference to `eCnt1'

It compiled fine for me. Are you sure you modified the correct wiring.c?

Foo, talk about a complete screw up. I was sure I had tried this earlier, but I guess not.

As it turns out, it compiles fine for all of the regular Arduino boards, but not for any of the mega1284 boards, either from the maniacbug 1284 library, or the latest Moteino-Mega board [which uses the 1284 - don't ask me why he calls it a -Mega].

That explains the whole thing. maniac-1284 has its own core files. Double-foo. Sorry, my screw-up.

oric_dan:
For reference, my basic plan for all this was to hack into ISR(TIMER0_OVF_vect), and make some minor changes [ie, use to modify the above mentioned variables], and then access the variables from my sketches.

I do believe it would be best practice to add an accessor function to wiring.c to actually get the variable, vs having sketches access the variables directly. This is because the multi-byte volatiles are not updated atomically and it is possible for a thread running at non-interrupt-priority to obtain inconsistent values when reading a long that is updated in an ISR. Accesses to these types should be bracketed by a CLI/SEI. This logic can easily be put into a simple accessor function, simplifying and de-risking the main program design.

Bad night, last night, oof. Was also dealing with a flakey SD shield - turned out to be those half-reliable female headers on the Arduino board not making good contact, so bent the pins. It's all working now.

gardner:

oric_dan:
For reference, my basic plan for all this was to hack into ISR(TIMER0_OVF_vect), and make some minor changes [ie, use to modify the above mentioned variables], and then access the variables from my sketches.

I do believe it would be best practice to add an accessor function to wiring.c to actually get the variable, vs having sketches access the variables directly. This is because the multi-byte volatiles are not updated atomically and it is possible for a thread running at non-interrupt-priority to obtain inconsistent values when reading a long that is updated in an ISR. Accesses to these types should be bracketed by a CLI/SEI. This logic can easily be put into a simple accessor function, simplifying and de-risking the main program design.

Thanks for the suggestion. I actually had written an accessor function, but it wouldn't work either due to the referencing problem [even with a fcn prototype in Arduino.h]. All good now. Thanks.