Skip to content

Commit

Permalink
Fix #485
Browse files Browse the repository at this point in the history
This fixes #485.
  • Loading branch information
SpenceKonde committed Oct 6, 2023
1 parent e65c607 commit 450c2c4
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 34 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ These are typically planned for release in a future version (usually the next on
* Re-add SPI atttach and detach.
* Add contributed variation on the latch no seq example.

### 1.5.11 (Emergency fix)
* At some point in the recent past, I must have angered the gods of C, and suddenly millis disabled stopped working - the system would hang (actually, with in-depth investigation, it was shown to be bootlooping - before it called init(), it was calling 0x0000 (a dirty reset) instead of eliding a weakly defined function with nothing in the body except a return, or with an empty body. Why was it doing this? And why only when millis was disabled?). millis disabled is a key piece of core functionality, necessitating an urgent fix. Moving the definitions into main.cpp resolved this issue.
* Investigaing reported PWM issues.

## Releases

### 1.5.10 (Emergency fix)
* Enhancement/bugfix - add digitalPinToCanon() - given a pin number, it returns port * 8 + bit_position. This is to be used in some other fixes and enhancements.
* Workaround Arduino CLI regression impacting CI testing.
Expand Down
1 change: 1 addition & 0 deletions megaavr/cores/dxcore/Arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -1185,4 +1185,5 @@ void pinConfigure(const uint8_t digital_pin, const pin_configure_t mode, const M
// open serial port, if the user tied it to a different port? Or thought they
// were going to use software serial "like they always did" (*shudder*)


#endif
20 changes: 9 additions & 11 deletions megaavr/cores/dxcore/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <Arduino.h>
/**
* Empty yield() hook.
*
Expand All @@ -25,10 +26,7 @@
* Its defined as a weak symbol and it can be redefined to implement a
* real cooperative scheduler.
*/
static void __empty() {
// Empty
}
void yield(void) __attribute__ ((weak, alias("__empty")));
void __attribute__((weak)) yield(void) {return;}

/* Hooks to get in real early. onPreMain runs in init3,
* (it gets called by _initthreestuff, which is setting IVSEL if we are using a fake bootloader section,
Expand All @@ -39,21 +37,21 @@ void yield(void) __attribute__ ((weak, alias("__empty")));
* even the blocking delays will give correct times. No class constructors have been called, In fact, the previous paragraph is pretty much
* all that has been done, other than clearing r1 so we can execute compiled C code ()
*/
void onPreMain() __attribute__((weak, alias("__empty")));

//void __attribute__((weak)) onPreMain() {return;}

/* onBeforeInit() after class constructors but before any hardware is initialized per core settings. */
void onBeforeInit() __attribute__((weak, alias("__empty")));
//void __attribute__((weak)) onBeforeInit() {return;}

/* onAfterInit() is called after the init routines, immediately before enabling interrupts. Setup() is called after this.
* And that's really the main purpose of this function - it gives you a way to tell the initialization routines "Hey, don't enable interrupts yet"
* You can prevent interrupts from being enabled by returning a non-zero value
*/
uint8_t onAfterInit() __attribute__((weak));
uint8_t onAfterInit() {
return 0;
}
//uint8_t __attribute__((weak)) onAfterInit() {
// return 0;
//}

void initVariant() { }
//void __attribute__((weak)) initVariant() { }
/* Weak empty variant initialization function. The purpose is unclear. It sounds like it was intended
* initialize the variant, and specific variants would have their own implementation. But in practice
* it seems to be instead used as an initialization callback that libraries can use to run code before
Expand Down
39 changes: 16 additions & 23 deletions megaavr/cores/dxcore/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,23 @@
/* Required by some libraries to compile successfully. Even though it's nonsense in Arduino. */
int atexit(void ( * /*func*/)()) { return 0; }

// these week definitions were moved to hooks.c
void initVariant() __attribute__((weak));
/* Weak empty variant initialization function. The purpose is unclear. It sounds like it was intended
* initialize the variant, and specific variants would have their own implementation. But in practice
* it seems to be instead used as an initialization callback that libraries can use to run code before
* setup, like FreeRTOS - it would have been nice if the official API included such a callback. */


void __attribute__((weak)) onPreMain();
//void __attribute__((weak)) onPreMain() {
/* Override with any user code that needs to run WAY early, in .init3 */
//}
void __attribute__((weak)) onBeforeInit();
//void __attribute__((weak)) onBeforeInit() {
/* Override with any user code that needs to run before init() */
//}
uint8_t __attribute__((weak)) onAfterInit();
//uint8_t __attribute__((weak)) onAfterInit() {
/* Override with any user code that needs to run before interrupts are
* enabled but after all other core initialization.
* return 1 to not enable interrupts) */
// return 0;
//}
/* What the bloody hell is going on? Why does everything fall down around my ears if disable
* millis is set and these functions are located in any other file. What is different?!
* It doesn't seem to be recognizing the "default" definition, because it compiles to a call
* pointed at 0x0000, which constitues directly requesting a dirty reset, and that is indeed
* what you get. And it bootloops very rapidly as a result, because that call haoppens at
* OnBeforeInit(). As the name suggests, that's the callback called before init() is called
* to set up the hardware */

void __attribute__((weak)) initVariant() {return;} // Reserved for library use.
void __attribute__((weak)) onPreMain() {return;} // Called in .init3. Remember to bring your stone tools and loincloth
// you must survive under the most primitive of conditions. No millis, no delay, F_CPU is defined to a speed other than the
// frequency it's running at, constructors have not run, etc.
void __attribute__((weak)) onBeforeInit() {return;} // Called before init. You can step up to maybe the bronze age, but
// things are still pretty rough, because the init() function has not been called and that sets up the clock, the timers
// and a wide variety of other things.
uint8_t __attribute__((weak)) onAfterInit() {return 0;} // Called between init() and the call to sei() to enable interrupts immediately prior to jumping to main.
// Unlike the others, this one has a return value. If you return a 1, sei() will not be called.


#if defined(LOCK_FLMAP)
Expand Down

0 comments on commit 450c2c4

Please sign in to comment.