Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 45 of 45

Thread: please help w code to NOT initialize variables

  1. #26
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    thanks - will try and let you know

  2. #27
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  3. #28
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    406
    Also try this, which gcc accepts:

    int x __attribute__((section(".noinit")));

  4. #29
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,895
    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.

  5. #30
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  6. #31
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,895
    Quote Originally Posted by analog&RFmodels View Post
    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);

  7. #32
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  8. #33
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,895
    Typo... xtren should be extern

  9. #34
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  10. #35
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    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:
      tc = maybe_saved1[0];
      Serial.println(tc);
      rf = maybe_saved2[0];
      Serial.println(rf);
      // refresh values
      tc = 7;
      rf = 1;
      *maybe_saved1 = tc;
      *maybe_saved2 = rf;
    
    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;
    }

  11. #36
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    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:

  12. #37
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    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
    ...

  13. #38
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    406
    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.

  14. #39
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  15. #40
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    @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

  16. #41
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    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.

  17. #42
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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;
    
    }

  18. #43
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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

  19. #44
    Senior Member
    Join Date
    Aug 2019
    Location
    southwest USA
    Posts
    112
    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...l=1#post113980
    // https://forum.pjrc.com/threads/31290...ll=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;
    }

  20. #45
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,764
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •