please help w code to NOT initialize variables

Status
Not open for further replies.
no dice - compiler comes back w "warning 'noinit' attribute directive ignored -
it compiles and of course variables are all zero after restart - but thank you
 
Not sure how your code will work with things not initialized, but one hack you might try is something like: trying to allocate something right at the start of the heap. I am not sure if malloc() will zero it...

But you might instead right at the start of your code do something like:
e
Code:
xtern "C" {
    extern void * _sbrk(int incr);
}
uint8_t *maybe_saved;

void setup() {
    maybe_saved = _sbrk(16);  // not sure what size to try here... I would probably start with 16 or 32... Not sure what malloc does.
...

Again I have not tried it, but I can see creating some structure of data, with data and some checksum or the like to validate?

Obviously this would not go across power cycles.
 
jonr - this version compiles no warnings and the contents of the variables it is used on do live thru the soft restart !!!
- best solution so far - thank you

KurtE - compiler not happy - after supper i will look at some more and maybe post compiler messages - thank you
 
jonr - this version compiles no warnings and the contents of the variables it is used on do live thru the soft restart !!!
- best solution so far - thank you

KurtE - compiler not happy - after supper i will look at some more and maybe post compiler messages - thank you

It probably needs a cast: maybe_saved = (uint8_t*)_sbrk(16);
 
KurtE - here is the top section of my pgm so you can see where i put your statements
and also the compiler error listing - earlier in this thread you can see an eeprom solution
that is the complete code. please do not laugh out loud if i bungled it badly.

Code:
const int led = 13;

// set time per slice
volatile int us = 1000000;
// set slice adder to trigger isr2 = abort long task 
volatile int lg =  100000;


    xtern "C" {
        extern void * _sbrk(int incr);
    }
    uint8_t *maybe_saved;

volatile byte tc __attribute__((section(".noinit")));
volatile byte rf __attribute__((section(".noinit")));

volatile byte srdatar;
volatile byte srdataw;
//volatile byte tc;
volatile byte tx;
volatile byte i;
//volatile byte rf;
volatile byte adder;

  IntervalTimer it1;
  IntervalTimer it2;



// long detect
void isr2() {
    cli();
    tx=99;
    ++tc;
    if(tc > 7) tc = 0;
    Serial.end();
    rf=1;
//    maybe_saved = tc;
    Serial.println("abt wrt rf sb 1");
    Serial.println(rf);
    Serial.println("abt wrt tc sb 4");
    Serial.println(tc);
    delay(5000);
//  this is a software restart
    SCB_AIRCR=0x05FA0004;
    return;
}

// increment task count via timer
void isr() {
    cli();
    ++tc;
    if(tc > 7) tc = 0;
    sei();
    return;
}

void task0(int data) {
Serial.print ("0");
delay(500);
}

void task1(int data) {
Serial.print ("1");
delay(500);
}

void task2(int data) {
Serial.print ("2");
delay(500);
// do this to see response
// to hung or long task
hang:
 goto hang;
}

void task3(int data) {
Serial.print ("3");
delay(500);
  }

int main() {
 maybe_saved = (uint8_t*)_sbrk(16); 
  Serial.begin(9600);
  pinMode(7, INPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  delay(500);
  Serial.println("*");

Code:
Arduino: 1.8.5 (Windows 7), TD: 1.52, Board: "Teensy LC, Serial, 48 MHz, Debug, US English"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dell\Documents\Arduino\libraries -fqbn=teensy:avr:teensyLC:usb=serial,speed=48,opt=ogstd,keys=en-us -ide-version=10805 -build-path C:\Users\Dell\AppData\Local\Temp\arduino_build_261671 -warnings=none -build-cache C:\Users\Dell\AppData\Local\Temp\arduino_cache_711328 -verbose C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dell\Documents\Arduino\libraries -fqbn=teensy:avr:teensyLC:usb=serial,speed=48,opt=ogstd,keys=en-us -ide-version=10805 -build-path C:\Users\Dell\AppData\Local\Temp\arduino_build_261671 -warnings=none -build-cache C:\Users\Dell\AppData\Local\Temp\arduino_cache_711328 -verbose C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino
Using board 'teensyLC' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Using core 'teensy3' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Build options changed, rebuilding all
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\sketch\arf1.ino.cpp" -o "nul"
Generating function prototypes...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\sketch\arf1.ino.cpp" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\preproc\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/precompile_helper" "C:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -Og -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671/pch/Arduino.h" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671/pch/Arduino.h.gch"
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -Og -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Dell\AppData\Local\Temp\arduino_build_261671/pch" "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\sketch\arf1.ino.cpp" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_261671\sketch\arf1.ino.cpp.o"
arf1:35: error: 'xtern' does not name a type
     xtern "C" {

     ^

arf1: In function 'int main()':
arf1:109: error: '_sbrk' was not declared in this scope
  maybe_saved = (uint8_t*)_sbrk(16); 

                                  ^

'xtern' does not name a type
 
KurtE - have you run out of time for this? here instead of a code snippet is an entire pgm that boils it all down
comes up tries to recover from maybe_saved - prints result,waits 5 seconds, re assigns values, does soft restart,
and thus cycle continues. as shown it will run in that cycle over and over but if to prevent warnings i replace for
example tc=maybe_saved1; with tc=*maybe_saved1; it will often "go away" or start an odd cycle of being gone
as far as the serial monitor thinks and then being back but printing nothing after the first cycle. below are code
and error listing (i purposely put the bad goto at the bottom so it would get an error instead of just warnings so
that the "copy errors" would light up and i could grab and paste the compile text output. take that goto out
before compile please. instead of printing a 7 and 1 i get 48 and 0. (comment all of your code and it saves nothing
but prints 7 and 1 as verification.

here is the code:
Code:
volatile byte tc=0x07;
volatile byte rf=0x01;

extern "C" {
        extern void * _sbrk(int incr);
           }

uint8_t *maybe_saved1;
uint8_t *maybe_saved2;

int main() {
 maybe_saved1 = (uint8_t*)_sbrk(16);
  Serial.begin(9600);
  delay(500);
// read hopefully intact data
  Serial.println("*");
  tc=maybe_saved1;
  Serial.println(tc);
  rf=maybe_saved2;
  Serial.println(rf);
  delay(5000);
// refresh values
  tc=7;
  rf=1;
 maybe_saved1 = tc;
 maybe_saved2 = rf;

// soft restart
SCB_AIRCR=0x05FA0004;
}

here is the error listing:

Code:
Arduino: 1.8.5 (Windows 7), TD: 1.52, Board: "Teensy LC, Serial, 48 MHz, Debug, US English"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dell\Documents\Arduino\libraries -fqbn=teensy:avr:teensyLC:usb=serial,speed=48,opt=ogstd,keys=en-us -ide-version=10805 -build-path C:\Users\Dell\AppData\Local\Temp\arduino_build_220854 -warnings=none -build-cache C:\Users\Dell\AppData\Local\Temp\arduino_cache_866353 -verbose C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Dell\Documents\Arduino\libraries -fqbn=teensy:avr:teensyLC:usb=serial,speed=48,opt=ogstd,keys=en-us -ide-version=10805 -build-path C:\Users\Dell\AppData\Local\Temp\arduino_build_220854 -warnings=none -build-cache C:\Users\Dell\AppData\Local\Temp\arduino_cache_866353 -verbose C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino
Using board 'teensyLC' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Using core 'teensy3' from platform in folder: C:\Program Files (x86)\Arduino\hardware\teensy\avr
Detecting libraries used...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\sketch\arf1.ino.cpp" -o "nul"
Generating function prototypes...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\sketch\arf1.ino.cpp" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\preproc\ctags_target_for_gcc_minus_e.cpp"
"C:\Program Files (x86)\Arduino\tools-builder\ctags\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\preproc\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/precompile_helper" "C:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -Og -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854/pch/Arduino.h" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854/pch/Arduino.h.gch"
Using previously compiled file: C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\pch\Arduino.h.gch

"C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -Og -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m0plus -fsingle-precision-constant -D__MKL26Z64__ -DTEENSYDUINO=152 -DARDUINO=10805 -DARDUINO_TEENSYLC -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Dell\AppData\Local\Temp\arduino_build_220854/pch" "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\sketch\arf1.ino.cpp" -o "C:\Users\Dell\AppData\Local\Temp\arduino_build_220854\sketch\arf1.ino.cpp.o"
arf1: In function 'int main()':
C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino:17:5: warning: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'byte {aka unsigned char}' [-fpermissive]

   tc=maybe_saved1;

     ^

C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino:19:5: warning: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'byte {aka unsigned char}' [-fpermissive]

   rf=maybe_saved2;

     ^

C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino:25:15: warning: invalid conversion from 'byte {aka unsigned char}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

  maybe_saved1 = tc;

               ^

C:\Users\Dell\Documents\Arduino\libraries\arf1\arf1.ino:26:15: warning: invalid conversion from 'byte {aka unsigned char}' to 'uint8_t* {aka unsigned char*}' [-fpermissive]

  maybe_saved2 = rf;

               ^

arf1:30: error: expected identifier before numeric constant
 goto 21;

      ^

arf1:30: error: expected ';' before numeric constant
arf1:30: warning: statement has no effect 
 goto 21;

        ^

expected identifier before numeric constant
 
the "maybe_"'s are pointers. To get the value they point to rather than seeing the pointer value or changing the pointer value it has to be dereferenced.

like this makes the compiler happy - two ways:
Code:
[B]  tc = maybe_saved1[0];[/B]
  Serial.println(tc);
[B]  rf = maybe_saved2[0];[/B]
  Serial.println(rf);
  // refresh values
  tc = 7;
  rf = 1;
[B]  *maybe_saved1 = tc;
  *maybe_saved2 = rf;
[/B]

The first ... because an array name is just a pointer - so you index with [square brackets] so [0] give the first value of the pointer type offset zero.
For a pointer to a single value that works - but so does '*' to say use this variable as a pointer and get or set the value in this case set because it is on the left of the assignment.

I tested above code - turning it into a sketch and it seems to fail to save the value - like earlier attempt ... it finds zero's each time on start ... and writing something that way seems to hang the T_LC?

Full sketch in case I messed it up:
Code:
volatile byte tc = 0x07;
volatile byte rf = 0x01;

extern "C" {
  extern void * _sbrk(int incr);
}

uint8_t *maybe_saved1;
uint8_t *maybe_saved2;

void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb

  Serial.print("Enter to any keys to START:\n");
  while ( !Serial.available() )
  {
    delay(1);
  }
  Serial.println("\nThank you \n");
  while ( Serial.available() )
  {
    Serial.read();
  }

}

void loop() {
  maybe_saved1 = (uint8_t*)_sbrk(500);
  Serial.println("*");
  tc = maybe_saved1[0];
  Serial.println(tc);
  rf = maybe_saved2[0];
  Serial.println(rf);
  // refresh values
  Serial.print("\nrefresh values\n");
  tc = 7;
  rf = 1;
  *maybe_saved1 = tc;
  *maybe_saved2 = rf;
  Serial.print("\nEnter to any keys to RESTART:");
  while ( !Serial.available() )
  {
    delay(1);
  }

  // soft restart
  SCB_AIRCR = 0x05FA0004;
}
 
The above ".noinit" idea in place is much better - it works and it doesn't hang. It will always use a known build defined address until the code changes - at which point the value is lost anyhow.

"SCB_AIRCR = 0x05FA0004" >> finds the values and updates them as expected.

They will start 0 after upload or whatever a 'Reset' command from TyCommander triggers.

Code:
int maybe_saved1 __attribute__((section(".noinit")));
int maybe_saved2 __attribute__((section(".noinit")));

void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb

  Serial.print("Enter to any keys to START:\n");
  while ( !Serial.available() )
  {
    delay(1);
  }
  Serial.println("\nThank you \n");
  while ( Serial.available() )
  {
    Serial.read();
  }

}

void loop() {
  Serial.println("*");
  Serial.println(maybe_saved1);
  Serial.println(maybe_saved2);
  // refresh values
  Serial.print("\nrefresh values\n");
  maybe_saved1++;
  maybe_saved2 += 2;
  Serial.println("*__*");
  Serial.println(maybe_saved1);
  Serial.println(maybe_saved2);
  Serial.print("\nEnter to any keys to RESTART:\n\n");
  while ( !Serial.available() )
  {
    delay(1);
  }

  // soft restart
  SCB_AIRCR = 0x05FA0004;
}

Enter to any keys to START:

Thank you

*
0
0

refresh values
*__*
1
2

Enter to any keys to RESTART:

Enter to any keys to START:

Thank you

*
1
2

refresh values
*__*
2
4

Enter to any keys to RESTART:

Enter to any keys to START:

Thank you

*
2
4

refresh values
*__*
3
6

Enter to any keys to RESTART:
 
and the short 1 sec wait version runs right too:
Code:
int maybe_saved1 __attribute__((section(".noinit")));
int maybe_saved2 __attribute__((section(".noinit")));

void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);
}

void loop() {
  Serial.print("\n*\t");
  Serial.print(maybe_saved1);
  Serial.print("\t");
  Serial.print(maybe_saved2);
  // refresh values
  Serial.print("\nrefresh values\t");
  maybe_saved1++;
  maybe_saved2--;
  Serial.print("*__*\t");
  Serial.print(maybe_saved1);
  Serial.print("*__*\t");
  Serial.print(maybe_saved2);
  delay( 1000 );
  // soft restart
  SCB_AIRCR = 0x05FA0004;
}

Code:
*	0	0
refresh values	*__*	1*__*	-1
*	1	-1
refresh values	*__*	2*__*	-2
...
*	117	-117
refresh values	*__*	118*__*	-118
*	118	-118
refresh values	*__*	119*__*	-119
*	119	-119
refresh values	*__*	120*__*	-120
*	120	-120
refresh values	*__*	121*__*	-121
*	121	-121
refresh values	*__*	122*__*	-122
*	122	-122
refresh values	*__*	123*__*	-123
*	123	-123
refresh values	*__*	124*__*	-124
*	124	-124
refresh values	*__*	125*__*	-125
...
 
To summarize for others, analog&RFmodels has come up with a lightweight method of preventing a subroutine from running for too long while allowing operation of the program to continue. The typical heavyweight solution would be preemptive threads.
 
to add to that summary - the 4 task 8 timeslice (01020103) version using the noinit attribute method uses these TLC resources:
pgm space 12%, ram space 26%, both pit timers, and the abort-recover dead time is 250 ms.

defragster - i got the same results you did on the code you posted
 
@analog&RFmodels : nice it working there - ran overnight here - another good summary point would be a view of the task/timeslice code in the end.
Code:
*	14242	-14242
refresh values	*__*	14243*__*	-14243
*	14243	-14243
refresh values	*__*	14244*__*	-14244

Here is a version using a struct for way more info than a couple bits:
Code:
struct {
  uint32_t cnt;
  char szFoo[16];
} bar __attribute__((section(".noinit")));

void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb
  if ( 0 == bar.cnt ) {
    strcpy( bar.szFoo, "\nfresh start\n" );
  }
  else {
    strcpy( bar.szFoo, "\n... restart\n" );
  }
  Serial.print( bar.szFoo );
}

void loop() {
  bar.cnt++;
  Serial.print("\t bar.cnt=");
  Serial.print(bar.cnt);
  delay( 1000 );
  if ( 5 == bar.cnt % 6 )
    SCB_AIRCR = 0x05FA0004; //// soft restart
}

Code:
fresh start
	 bar.cnt=1	 bar.cnt=2	 bar.cnt=3	 bar.cnt=4	 bar.cnt=5
... restart
	 bar.cnt=6	 bar.cnt=7	 bar.cnt=8	 bar.cnt=9	 bar.cnt=10	 bar.cnt=11
... restart
	 bar.cnt=12	 bar.cnt=13	 bar.cnt=14	 bar.cnt=15	 bar.cnt=16	 bar.cnt=17
... restart
 
NOTE: On T_4.1 the above code works for .noinit - except RAM is never set ZERO!!!! So the 'fresh start' detect is not valid! On Reset or UPLOAD!

As noted some posts back - would need to hold a known signature value and a place for that in the struct to compare - then when changed or desired the right alternate action could be taken.
This works on T_4.1 and T_LC::
Code:
struct {
  uint32_t cnt;
  uint32_t sig;
  char szFoo[16];
} bar __attribute__((section(".noinit")));

const uint32_t mySig = 0x12345678;
void setup()
{
  Serial.begin(115200);
  while ( !Serial ) delay(10);
  if ( mySig != bar.sig ) {
    bar.cnt=0;
    bar.sig=mySig;
    strcpy( bar.szFoo, "\nfresh start\n" );
  }
  else {
    strcpy( bar.szFoo, "\n... restart\n" );
  }
  Serial.print( bar.szFoo );
}

void loop() {
  bar.cnt++;
  Serial.print("\t bar.cnt=");
  Serial.print(bar.cnt);
  delay( 1000 );
  if ( 5 == bar.cnt % 6 )
    SCB_AIRCR = 0x05FA0004; //// soft restart
}

*If the struct or code usage ever changes it would need a new bar.sig value.
 
as a final summary point here is the code for 8 timeslices/4 tasks using noinit. i am sure that a real C programmer
could tighten it up and shrink it even further.

in task2 either comment or un-comment the two lines hang:, goto hang; to see normal versus hung/long task
performance



Code:
// teensy lc no hang time slice skeleton
// resources used are 12% code, 26% ram,
// both periodic interrupt timers,and
// calls tasks this order 01020103
//                        ABACABAD
// 8 slices 4 tasks
// this case 1 s ea task
// 8 s = whole pgm
// task 0 runs 4 times, task 1 runs
// 2 times,  tasks 2 and 3 run 1 time
// the 4 task0 runs are evenly spaced in
// time as are the 2 task 1 runs
// in effect task 0 has the shortest latency,
// task 1 has the next least latency, and tasks
// 2 and 3 have the longest latency, and of
// course there are many possibilities w 8 slices
// 01020103, 01230123, 01234567 etc
// aborts slices that run too long, does a soft-
// ware restart, and picks back up with the next
// slice in the sequence of 8
// gone time during restart is 0.25 sec, with
// shorter tasks this might be intolerable
// of course normally tasks would be much shorter
// time but slow allows debug using only serial
// monitor
// have tested debug and smallest code

// set time per slice
volatile int us = 1000000;
// set slice adder to trigger isr2 = abort long task 
volatile int lg =  100000;

volatile byte tc __attribute__((section(".noinit")));
volatile byte rf __attribute__((section(".noinit")));

volatile byte tx;
volatile byte dly=1;

  IntervalTimer it1;
  IntervalTimer it2;

// long detect
void isr2() {
    cli();
    tx=99;
    ++tc;
    if(tc > 7) tc = 0;
    Serial.end();
    rf=1;
//    Serial.println("abt wrt rf sb 1");
//    Serial.println(rf);
//    Serial.println("abt wrt tc sb 4");
//    Serial.println(tc);
//    delay(5000);
//  this is a software restart
    SCB_AIRCR=0x05FA0004;
    return;
}

// increment task count via timer
void isr() {
    cli();
    ++tc;
    if(tc > 7) tc = 0;
    sei();
    return;
}

void task0(int data) {
Serial.print ("0");
delay(dly);
}

void task1(int data) {
Serial.print ("1");
delay(dly);
}

void task2(int data) {
Serial.print ("2");
delay(dly);
// do this to see response
// to hung or long task
//hang:
// goto hang;
}

void task3(int data) {
Serial.print ("3");
delay(dly);
  }

int main() {
  Serial.begin(9600);
  delay(500);
  Serial.println("*");
//  Serial.println("main rd rf sb 1");
//  Serial.println(rf); 
//  Serial.println("main rd tc sb 4");
//  Serial.println(tc);
//  Serial.println("**");
  if(rf==1) {
            rf=0;
//            Serial.println("sr write"); 
            goto cont;
            }
  tc=0;
  tx=0;
  rf=0;


cont:

  it1.begin (isr,us);
  it2.begin (isr2,us+lg);

loopm:
    it2.begin (isr2,us+lg);

    if (tc==0)  task0(1);
    it2.begin (isr2,us+lg);
w0:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==0) goto w0;

    if (tc==1)  task1(1);
    it2.begin (isr2,us+lg);
w1:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==1) goto w1;

    if (tc==2)  task0(1);
    it2.begin (isr2,us+lg);
w2:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==2) goto w2;

    if (tc==3)  task2(1);
    it2.begin (isr2,us+lg);
w3:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==3) goto w3;

    if (tc==4)  task0(1);
    it2.begin (isr2,us+lg);
w4:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==4) goto w4;

    if (tc==5)  task1(1);
    it2.begin (isr2,us+lg);
w5:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==5) goto w5;

    if (tc==6)  task0(1);
    it2.begin (isr2,us+lg);
w6:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==6) goto w6;
    
    if (tc==7)  task3(1);
    it2.begin (isr2,us+lg);

    Serial.println (" ");
w7:
    if (tx>98) {tx=0; goto loopm;}
    if (tc==7) goto w7;

  goto loopm;

}
 
when i sped it up to us=6250 and lg=625 the line in isr2() "++tc" had to be commented to prevent skipping
one task on a restart - who knows, at even faster task intervals it might have to become --tc
6250 625 does a task ea 1/160 of a second or 1 time around all 8 tasks in 1/20 of a second
 
cleaned up redundant code, no longer needs code changes in isr2 depending on slow/fast task time, and the
comments include editing one of the teensy core files so that the abort/recover time goes from 250 ms to
2.5 ms (much more practical). i have not had any usb or start-up glitches with the edit. for faster startup.

// for background about this startup delay, please see these conversations
// https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
// https://forum.pjrc.com/threads/3129...ader-1-24-Issues?p=87273&viewfull=1#post87273

Code:
// teensy lc no hang time slice skeleton
// resources used are 12% code, 26% ram,
// both periodic interrupt timers,and
// calls tasks this order 01020103
//                        ABACABAD
// 8 slices 4 tasks
// this case 1 s ea task
// 8 s = whole pgm
// task 0 runs 4 times, task 1 runs
// 2 times,  tasks 2 and 3 run 1 time
// the 4 task0 runs are evenly spaced in
// time as are the 2 task 1 runs
// in effect task 0 has the shortest latency,
// task 1 has the next least latency, and tasks
// 2 and 3 have the longest latency, and of
// course there are many possibilties w 8 slices
// 01020103, 01230123, 01234567 etc
// aborts slices that run too long, does a soft-
// ware restart, and picks back up with the next
// slice in the sequence of 8
// gone time during restart is 250 msec, with
// shorter tasks this might be intolerable

// to shorten this to 2.5 ms:
// in cores teensy3 edit pins_teensy.c
// starting at line 607
// from
//  delay(TEENSY_INIT_USB_DELAY_BEFORE);
//  usb_init();
//  delay(TEENSY_INIT_USB_DELAY_AFTER);
// to
//  delay(1);
//  usb_init();
//  delay(1);

// this version isr2 needs no changes when
// running fast vs slow task times

// have tested debug and smallest code

// set time per slice
volatile int us = 6250;
// set slice adder to trigger isr2 = abort long task 
volatile int lg = 625;

volatile byte tc __attribute__((section(".noinit")));
volatile byte rf __attribute__((section(".noinit")));

volatile byte tx;
volatile byte dly=500;

  IntervalTimer it1;
  IntervalTimer it2;

// long detect
void isr2() {
    cli();
    if(tc > 7) tc = 0;
    Serial.end();
    rf=1;
//    Serial.println("abt wrt rf sb 1");
//    Serial.println(rf);
//    Serial.println("abt wrt tc sb 4");
//    Serial.println(tc);
//    delay(5000);
    digitalWrite(LED_BUILTIN, LOW);
//  this is a software restart
    SCB_AIRCR=0x05FA0004;
    return;
}

// increment task count via timer
void isr() {
    cli();
    ++tc;
    if(tc > 7) tc = 0;
    sei();
    return;
}

void task0(int data) {
it2.begin (isr2,us+lg);
Serial.print ("0");
delayMicroseconds(dly);
}

void task1(int data) {
it2.begin (isr2,us+lg);
Serial.print ("1");
delayMicroseconds(dly);
}

void task2(int data) {
it2.begin (isr2,us+lg);
Serial.print ("2");
delayMicroseconds(dly);
// do this to see response
// to hung or long task
hang:
  goto hang;
}

void task3(int data) {
it2.begin (isr2,us+lg);
Serial.print ("3");
delayMicroseconds(dly);
}

int main() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN,HIGH);
  Serial.begin(9600);
  delay(500);
//  Serial.println("*");
//  Serial.println("main rd rf sb 1");
//  Serial.println(rf); 
//  Serial.println("main rd tc sb 4");
//  Serial.println(tc);
//  Serial.println("**");
  if(rf==1) {
            rf=0;
//            Serial.println("sr write"); 
            goto cont;
            }
  tc=0;
  tx=0;
  rf=0;

cont:

  it1.begin (isr,us);
  it2.begin (isr2,us+lg);

loopm:
    it2.begin (isr2,us+lg);
    if (tc==0)  task0(1);
w0:
    if (tc==0) goto w0;
    if (tc==1)  task1(1);
w1:
    if (tc==1) goto w1;
    if (tc==2)  task0(1);
w2:
    if (tc==2) goto w2;
    if (tc==3)  task2(1);
w3:
    if (tc==3) goto w3;
    if (tc==4)  task0(1);
w4:
    if (tc==4) goto w4;
    if (tc==5)  task1(1);
w5:
    if (tc==5) goto w5;
    if (tc==6)  task0(1);
w6:
    if (tc==6) goto w6;
    if (tc==7)  task3(1);
    Serial.println (" ");
w7:
    if (tc==7) goto w7;
  goto loopm;
}
 
With a signature value (like p#41) the code would/should work on even Teensy's that don't Zero RAM on upload/reset. Then that state could be ID'd to know the value there was not from prior run.

Indeed those TEENSY_INIT_USB_DELAY_'s are not needed without USB init and they hold up code entry. If USB is needed - removing those delay's did seem to harm its starting IIRC based on prior linked threads. Also reading that I see @defragster helpfully noted - it would be nice if those delay's went away when USB was not part of the build.

local Cores could be recoded to use variables for those delays - and then selectively set them 0 in the startup_early_hook() if USB is not needed.
 
Status
Not open for further replies.
Back
Top