-
Notifications
You must be signed in to change notification settings - Fork 188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding a timeout to the bootloader #209
Comments
This should not be hard to add. So the use case is that ESD has done the equivalent of a double-click, and you want it to reset instead after a period of time? Are these your own boards? Are you using this bootloader instead of the Arduino one because you're using UF2's? |
We tried replicating it using ESD gun which forces it into the bootloader mode, @lodhi-origo tried to remove the double-tap-magic from the main.c but the issue still persists. Yes these are custom boards and we are using SAMD21G18A. Thanks a bunch |
Hi Dan, The ESD has made the SAMD21 reboot to the point where it needs a double-click to continue execution. We would like to implement a timeout at this point, so if it is not getting a double-click, it will continue execution/boot and start the normal bin code/application after a number of seconds e.g. 15 seconds, which should be configurable. |
That will make it worse, I think, because any reset will switch immediately to the bootloader and stay there. I think it might be a question of whether it's really in the bootloader or is stuck in some other way. Does your custom board have an LED that pulses like the Adafruit boards when it's in the bootloader: slow "breathing" pulse when connected to USB, faster pulse when not connected? More in the next post. |
from @lodhi-origo in discord:
// Define the timeout duration in milliseconds
#define BOOTLOADER_TIMEOUT 15000 // 15 seconds
static volatile uint32_t millis = 0;
// Timer function to get current time in milliseconds
static uint32_t get_current_millis(void) {
// This should return the number of milliseconds since the system started
return millis;
}
void SysTick_Handler(void) {
millis++;
}
void init_systick(void) {
SysTick_Config(SystemCoreClock / 1000);
}
SystemInit();
init_systick(); and then initializing the uint32_t start_time = get_current_millis(); and lastly editing in the main // Check if the timeout has been reached
if (get_current_millis() - start_time > BOOTLOADER_TIMEOUT) {
//LED_MSC_ON();
check_start_application(); // Jump to the main application
break; // Exit the loop after jumping
} Re the above: The systick is already running: it's used to do the LED pulsing. There is already a systick handler in void SysTick_Handler(void) { LED_TICK(); } You could add timeout checking there. Another thing I thought you might do is just count the number of LED pulses and stop after a few hundred or so. You may not want to timeout the bootloader if you are connected to USB (check Re your proposed code: // Check if the timeout has been reached
if (get_current_millis() - start_time > BOOTLOADER_TIMEOUT) {
//LED_MSC_ON();
check_start_application(); // Jump to the main application
break; // Exit the loop after jumping
} Instead of BTW, in the above, if the |
That's also the thing that electronically I'm not sure if it is getting into the bootloader or stuck in some other way. However, we do have a pulsating led on our board and it will start pulsating when hit with ESD, so from this we are concluding that it is halting into the bootloader mode. |
For debugging, there is a "log to RAM" mechanism in the UF2 code, but I have not been successful at getting it to work. I don't use Atmel Studio. I use a J-Link directly or from gdb. Writing the bootloader is a nuisance because of the fuses. It's tricky to write to the fuses from JLinkExe: you need to do the write and then step the program one instruction to get the write to complete. |
Hi Dan I initialized volatile uint32_t ledOnToggleCount = 0; so the void led_tick() {
led_tick_on = true;
now++;
if (signal_end) {
if (now == signal_end - 1000) {
LED_MSC_ON();
}
if (now == signal_end) {
signal_end = 0;
}
} else {
uint8_t curr = now & 0xff;
if (curr == 0) {
LED_MSC_ON();
if (limit < 10 || limit > 250) {
led_tick_step = -led_tick_step;
}
limit += led_tick_step;
} else if (curr == limit) {
LED_MSC_OFF();
`ledOnToggleCount++; // Increment the counter here`
}
}
} and then simply adding the below code in main.c after the // Check if the timeout has been reached
if (ledOnToggleCount >= 200) {
resetIntoApp();
} The code compiles successfully given that the |
Could you push your code to a repo I can see? Thanks. |
Here is the fork from adafruit in which I add ledOnToggleCount and use two files from \lib\samd21\samd21a\gcc\gcc which I'm not sure if the linker files are correct for SAMD21G18A. |
Hi Dan By removing the brownout protection in the main.c file it will still work fine. What are the scenarios that it will be useful ? |
Hi - I don't know what you mean here. Did you mean that if you remove the brownout protection your problem goes away? It was added here: #198. See the (long) forum thread referenced there for why it was added. |
We are using SamD21 in weather stations but ESD and Electrostatic becomes an issue sometimes. High Frequency Transient voltages somehow put SamD21 into bootloader mode. I was wondering if anyone can help me implement a timeout to the bootloader. Whereby after in bootloader mode for lets say 1 minutes, It automatically exits the bootloader mode.
The text was updated successfully, but these errors were encountered: