Currently millis() overflows much sooner than you might expect because it is calculated from a timer that ticks every 1024 microseconds.
You could take the overflow interrupt on timer2 which runs at the same rate as the millis() timer and define a 'seconds' counter. That might look something like this...
volatile unsigned long seconds = 0;
SIGNAL(SIG_OVERFLOW2)
{
static long microseconds = 0;
microseconds += 1024;
if ( microseconds > 1000000L) {
seconds++;
microseconds -= 1000000L;
}
}
unsigned long secondsSinceBoot()
{
unsigned long t;
uint8_t oldSREG = SREG;
cli(); // disable interrupts
t = seconds;
SREG = oldSREG; // restore interrupts
return t;
}
Then every 1024 microseconds that SIGNAL function will run and accumulate another 1024 microseconds. When there are more than a million accumulated it increments the second and uses up that million. Then you can check "seconds" to see how long it has been since boot. It isn't quite that easy, because the interrupt could fire in the middle of your code reading "seconds", so I added the function "secondsSinceBoot" to safely get you a copy of "seconds" by briefly disabling interrupts. (they won't be lost, just delayed).
You could stick a call to your function in after seconds gets incremented, but be aware you are running at interrupt level and some things don't work... like delay() will freeze and if you take more than about 900 microseconds you will lose a clock tick and not keep correct time. Probably better to poll seconds from your main loop.
(Crappy code notes: The above code doesn't pay any attention to F_CPU or check that timer2 hasn't been changed from its default function. If you diddle with those sorts of things then you'll know what to do.)