Optiboot / optiboot

Small and Fast Bootloader for Arduino and other Atmel AVR chips
Other
1.09k stars 401 forks source link

V7.0 MCUSR, I can't get it well. Test_reset.ino example #247

Closed ortegafernando closed 6 years ago

ortegafernando commented 6 years ago

Hi, I have download last version from github. I haven't compiled anything, I used hex file directly.

I have burnt optiboot bootloader into an arduino pro mini, and after that I have seen led flashing 3 times (so, it is ok).

The MCUSR example doesn't work, always show same information.

https://github.com/Optiboot/optiboot/blob/master/optiboot/examples/test_reset/test_reset.ino

I haven't got enough skills to solve this. Anyone could help me?

Thanks.

ortegafernando commented 6 years ago

Hi, meanwhile, could any body check the test_reset sketch and see if she/he gets the same result? Thanks

WestfW commented 6 years ago

What setup are you using what reset methods are you using, and what "same information" are you seeing? During testing, it was unexpectedly difficult to get certain types of reset, given the way an Uno is set up (ie if you power down the board, you end up powering down the USB/Serial converter as well.) I mini should be somewhat more controllable, but you still have the problem where the board can get powered (or partially powered) via the logic level on the RxD pin...

ortegafernando commented 6 years ago

Hi @WestfW and thank a lot for your answer.

I have do it again. This is the setup.

Arduino Pro Mini (I have got another unit, so I have tried again with this new unit) with new optiboot burned (with an Arduino Uno as ISP)

Upload sketch with and USB/Serial converter and after that disconnect DTR pin and GND pin so Pro Mini is off.

I will put here the serial output after some actions that I have done.

  1. Then connect only GND pin:
Reset flag test

Actual MCUSR content: 0x5 Brownout PowerOn
Passed in R2: 0x5 Brownout PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

So this is OK.

  1. Press reset button in arduino pro mini
Reset flag test

Actual MCUSR content: 0x7 Brownout External PowerOn
Passed in R2: 0xF Watchdog Brownout External PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

May be I am wrong, but here we have not only "EXTERNAL" but also Brownout and PowerOn and Watchdog in R2.

  1. Write W in serial input
Reset flag test

Actual MCUSR content: 0x7 Brownout External PowerOn
Passed in R2: 0xF Watchdog Brownout External PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

Again the same, and nothing about Watchdog in MCUSR

@WestfW probably I am doing something wrong, but I have check it with two arduino pro mini's.

May be anybody could try this sketch in another IC's

Or do you want me to do another check?

Thanks a lot

(all serial output in a row):

Reset flag test

Actual MCUSR content: 0x5 Brownout PowerOn
Passed in R2: 0x5 Brownout PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
Reset flag test

Actual MCUSR content: 0x7 Brownout External PowerOn
Passed in R2: 0xF Watchdog Brownout External PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
Reset flag test

Actual MCUSR content: 0x7 Brownout External PowerOn
Passed in R2: 0xF Watchdog Brownout External PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
ortegafernando commented 6 years ago

hi, anybody has tried ? thanks

WestfW commented 6 years ago

Sorry; I've been out of town more than "near keyboard" for the last couple of weeks...

here we have not only "EXTERNAL" but also Brownout and PowerOn and Watchdog in R2.

Did you use the "0" command to reset the MCUSR register before you hit reset? One of the ... features ... of not resetting MCUSR in the bootloader is that its bits are now "sticky" - if you do not explicitly reset them in your sketch, the various reset causes will "add" all the different types of reset that have occurred. It's assumed that people who want to read MCUSR will understand and deal with this in an appropriate way - the test_reset sketch intentionally only does this manually, so that you can see/check the additive effect.

ortegafernando commented 6 years ago

Hi @WestfW

Thanks a lot. I know about MCUSR (a bit), and normally I use it as you says, clearing MCUSR register at the start of my setup.

Normallly I use in my setup (when I have not bootloader):

myMCUSR = MCUSR;
MCUSR = 0;
wdt_disable;

But with optiboot, I understood that optiboot saves MCUSR in any kind of "r2" register (that i don't know), and optiboot also does all of stuff with MCUSR.

I understood that we have to read "r2" register as MCUSR is also "contaminated" with the watchdog reset of optiboot.

So I understand it wrong.

Are you saying that we need to use the "0" command to reset the MCUSR register? or the r2 register?

Thanks a lot.

ortegafernando commented 6 years ago

Hi @WestfW I am fighting with this sketch.

Probably I am not an expert, but I usually work with watchdog and MCUSR.

I have tried this secuence with optiboot 7.0 and optiboot 4.4 (the one that comes wth arduino IDE 1.8.6): (first of all, I have checked the last two bytes of flash to check that I have optiboot 7.0)

  1. power on --> MCUSR and R2 are Ok
  2. write "0" to put MCUSR to 0x00h
  3. push reset button -->MCUSR is Ok, R2 includes watchdog
  4. write "0" to put MCUSR to 0x00h
  5. write "w" to generate a watchdog --> boot loop until I power off the arduino pro mini.

This is the serial output with that secuence with optiboot 7.0:

Reset flag test

Actual MCUSR content: 0x5 Brownout PowerOn
Passed in R2: 0x5 Brownout PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
0

MCUSR content: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

Reset flag test

Actual MCUSR content: 0x2 External
Passed in R2: 0xA Watchdog External
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
0

MCUSR content: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
w
Reset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüReset flag tesüRe ..... .... .... .... ....

And with optiboot 4.4: MCUSR and R2 are wrong as optiboot 4.4 doesn't take care of it. But watchdog is working perfectly.

  1. power on
  2. write "0" to put MCUSR to 0x00h
  3. push reset button
  4. write "0" to put MCUSR to 0x00h
  5. write "w" to generate a watchdog --> pro mini reboots and wait again for a new command.
Reset flag test

Actual MCUSR content: 0x0
Passed in R2: 0x34 Brownout Unknown
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
0

New MCUSR content: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

Reset flag test

Actual MCUSR content: 0x0
Passed in R2: 0x34 Brownout Unknown
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
0

New MCUSR content: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
w

Reset flag test

Actual MCUSR content: 0x0
Passed in R2: 0x34 Brownout Unknown
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

What I am doing wrong?

When I work with ATMEGA328P standalone chips, I have this instructions at the begining of the setup:

  myMCUSR = MCUSR;
  // Clear all MCUSR registers immediately for 'next use'
  MCUSR = 0;
  wdt_disable();

The test_reset.ino sketch hasn't "wdt_disable()" probably because optiboot 7.0 takes care of it. But then ... why I am getting a boot loop ? I haven't change anything in your sketch, and I have only optiboot 7.0 or 4.4 burnt into my pro mini.

Regards

(just in case, my fuses: pro.menu.cpu.8MHzatmega328opti7.upload.maximum_size=32256 pro.menu.cpu.8MHzatmega328opti7.upload.maximum_data_size=2048 pro.menu.cpu.8MHzatmega328opti7.upload.speed=57600 pro.menu.cpu.8MHzatmega328opti7.bootloader.low_fuses=0xFF pro.menu.cpu.8MHzatmega328opti7.bootloader.high_fuses=0xDE pro.menu.BOD.1v8.bootloader.extended_fuses=0xFE pro.menu.cpu.8MHzatmega328opti7.bootloader.file=optiboot7/optiboot_atmega328.hex pro.menu.cpu.8MHzatmega328opti7.build.mcu=atmega328p pro.menu.cpu.8MHzatmega328opti7.build.f_cpu=8000000L)

ortegafernando commented 6 years ago

hi, anybody has tried ? thanks

WestfW commented 6 years ago

why I am getting a boot loop ? I'm getting the boot loop as well. But not on ATmega8! Which is particularly mysterious. I don't see LED flashes within the loop, so I'm not sure it's a "normal" boot loop. Investigating... (Sorry for the delay. For some reason, your earlier updates didn't result in me getting the usual email notification, so I didn't realize that you had updated the issue...)

WestfW commented 6 years ago

Ahh. I see. You can't turn off the watchdog while WDRF is set. If you set MCUSR to 0, and then jump to the bootloader, it will run the bootloader as intended, but if there is no bootloader traffic, it will do a watchdog reset. At that point, WDRF is the only bit set in MCUSR, so the startup code bypasses the reset of WDRF (necessary to get support of the application flag in the sketches), but then when it tries to do the WATCHDOG_OFF it fails because WDRF is still set. Essentially, there's no (easy?) way to tell the difference between "a watchdog timeout occurred during the user sketch" (we want the sketch to restart immediately, with WSRF still set) and "a watchdog occurred in the bootloader after the application requested that the bootloader run" (in which case we want the application to run after disabling the watchdog.)

Unfortunately, that makes perfect sense - in the latter case, the bootloader is essentially being run as a subroutine of the application, so the cases are indistinguishable.

One workaround is to just say that any application that wants to use the bootloader by request must ensure that any application that starts (either the original, or whatever is bootloaded)

ortegafernando commented 6 years ago

Hi @WestfW I almost not understand you ;) Your postis very difficult for me but that is my problem, not yours. So .....

  1. is there any easy solution to updateoptiboot ? --> You said that "NOT".
  2. is there any easy solution to do in my sketcj ? --> Here again, I ask you for help
  3. is it impossible to get it working.

What is the correct option?

Thanks.

WestfW commented 6 years ago

1) No, I can't think of a way to fix Optiboot itself. 2) your sketch can turn off the watchdog early in setup(). I did update the example to show this. It will need to do something else to tell the difference between an actual watchdog timeout, and a watchdog timeout that happened in the bootloader. 3) get what working? The example by itself is pretty meaningless. The main "problem" is using both watchdog timeout and "bootloader called from the application" in the same application. "working" would depend on exactly what you want to have happen...

ortegafernando commented 6 years ago
  1. No, I can't think of a way to fix Optiboot itself.
  2. your sketch can turn off the watchdog early in setup(). I did update the example to show this. It will need to do something else to tell the difference between an actual watchdog timeout, and a watchdog timeout that happened in the bootloader.
  3. get what working? The example by itself is pretty meaningless. The main "problem" is using both watchdog timeout and "bootloader called from the application" in the same application. "working" would depend on exactly what you want to have happen...

Ok, I will try and check option 2. Let's see what I get.

Thanks a lot.

WestfW commented 6 years ago

I've started another "issue" to cover the technical aspects of this bug: https://github.com/Optiboot/optiboot/issues/250 (The discussion can keep going here, though.)

ortegafernando commented 6 years ago

Hi @WestfW I have tried again and I think that if I repeat things that I usually do in my sketches (see this previous message I think that my problem is solved. I never use "jump to bootloader" in my apps.

This is my setup's initial code in test_reset.ino example:

  myMCUSR = MCUSR;
  MCUSR = 0;
  wdt_disable();

  Serial.begin(9600);  // Initialize serial port
  Serial.println(F("Reset flag test\n"));

  printReset("Actual MCUSR content: 0x", MCUSR);
  printReset("Actual myMCUSR content: 0x", myMCUSR);
  .......
  ......

With this code (that is very similar to yours) I can get the information that I want in myMCUSR byte variable.

That is the same way as I usually work with barebone chips without bootloader, in which MCUSR is not modified by "anyone" before sketch starts.

This is the serial output with these steps:

  1. power on
  2. push reset button
  3. write W NOTE: Now there is no need to write 0 to MCUSR because I already do it at the first part of my sketch
Reset flag test

Actual MCUSR content: 0x0
Actual myMCUSR content: 0x5 Brownout PowerOn
Passed in R2: 0x5 Brownout PowerOn
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
Reset flag test

Actual MCUSR content: 0x0
Actual myMCUSR content: 0x2 External
Passed in R2: 0xA Watchdog External
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep
Reset flag test

Actual MCUSR content: 0x0
Actual myMCUSR content: 0x8 Watchdog
Passed in R2: 0x8 Watchdog
Passed in GPIOR0: 0x0

Send 0-9 to set MCUSR, (W)atchdog enable, (J)mp to bootload, (S)leep

You can see, that myMCUSR content is working perfectly (for me). It has "power on", "external" and "watchdog" value in each step, so for me it is working.

@WestfW what do you think about this ? I am not sure if I am doing something wrong changing your code in setup, but as I don't use "jump to bootload", I think that your Optiboot 7.0 has a great advance about MCUSR register over older versions.

Hope your answer. May be the solution is not complete, but it is working for my purpose, isn't it ?

WestfW commented 6 years ago

Sounds good to me. The bootloader continues to put mcusr contents in R2 for "backward compatibility", but you don't need to look at both R2 and the actual MCUSR... I'll go ahead and close this issue.

ortegafernando commented 6 years ago

Thanks a lot. I still don't understand :worried: :worried: exactly R2's stuff but ... ... ... It works for me. (I hope :smile: )