Go Down

Topic: Software reset in Arduino Zero (Read 5289 times) previous topic - next topic

kinematik

I need now to reset my Zero board using software reset, i.e. when some conditions are met in the sketch, I try to reboot the board.

My reasond for using a software reset instead of a hardware one, are related to a multifunction swicth, that can triggers several functions:
  • 1. ligthning the display (short push)
  • 2. changing the display layout (after lightning the display a series of short pushes)
  • 3. reseting the board when pushed for more than 5 seconds


The code for detecting the reset condition is working, but the "reset function", that I copied from the AVR boards, freezes the Zero board:
Code: [Select]
void(* resetFunc) (void) = 0;//declare reset function at address 0

Anybody has faced this issue (software reset) before?, how can I call a function in Arduino that resets the board?

This is the part of my code that manages the above mentioned functions:
Code: [Select]
  // Switch management
  bool Pulsador = !digitalRead(PULSADOR_PIN);    // Leo Estado Pulsador (Lógica Inversa!!)

   // Lightning the  DISPLAY : 
  if ( (Pulsador) || (millis()-ilumTime) < ILUM_INTERVAL ) {
     digitalWrite(BACKLIGHT_PIN, HIGH); 
     digitalWrite(REDLED_PIN, HIGH); 
     if (Pulsador != PulsadorPre) {              // Ha existido cambio estado Pulsador?
        ilumTime = millis();                     // Fijo Tiempo inicio contar Tiempo iluminación
        resetTime = millis();                    // Fijo Tiempo inicio contar Tiempo Reset
        if (Pulsador){                           // Si Flanco Subida?
          LayoutDisplay++;                       // Cambio Tipo Pantalla
          if (LayoutDisplay > 4) {LayoutDisplay = 0;} // Si llego a Pantalla 3, vuelvoa a la primera
        }
     }
   } else {                                      // Pulsador No activado
     digitalWrite(BACKLIGHT_PIN, LOW); 
     digitalWrite(REDLED_PIN, LOW); 
     LayoutDisplay = 0;
  }

  // SOFTWARE RESET: Switch Time  > RESET_INTERVAL
  if (Pulsador && (millis()-resetTime)> RESET_INTERVAL) {
     // Software Reset
     resetFunc();
  }
  PulsadorPre = Pulsador;          // Almaceno Estado pulsador para detectar cambios

AloyseTech

Try this code :

Before setup() :

Code: [Select]
extern "C" {
  extern void resetZero();
}


after loop() :

Code: [Select]
extern "C" {
#define APP_START_ADDRESS 0x2000

  void resetZero() {
    void (*application_code_entry)(void);
    __set_MSP(*(uint32_t *) APP_START_ADDRESS);
    SCB->VTOR = ((uint32_t) APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);
    application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(APP_START_ADDRESS + 4));
    application_code_entry();
  }
}

Sulimarco

#2
Feb 18, 2016, 04:46 pm Last Edit: Feb 18, 2016, 04:55 pm by Sulimarco
Hi Kinematik,


to reset the processor call this CMSIS function


Code: [Select]
NVIC_SystemReset();      // processor software reset



Ciao
Marco

kinematik

Hi Marco,

Thanks!, it works!. I did not have idea about the CMSIS (the ARM Cortex Microcontroller Software Interface Standar) was available in the Arduino environment.

A brief explantation about CMSISI (ARM standard), for the not so knowledgable people like me: http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php

Can you please elaborate, what else is available and where are these functions defined in the Arduino environment?

kinematik

Try this code :

Before setup() :

Code: [Select]
extern "C" {
  extern void resetZero();
}


after loop() :

Code: [Select]
extern "C" {
#define APP_START_ADDRESS 0x2000

  void resetZero() {
    void (*application_code_entry)(void);
    __set_MSP(*(uint32_t *) APP_START_ADDRESS);
    SCB->VTOR = ((uint32_t) APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);
    application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(APP_START_ADDRESS + 4));
    application_code_entry();
  }
}


thanks Aloise, unfortunately the code freezes my board. Actually I am not using a bootloader but it does not work regardless the value of the star address, I tried both:
Code: [Select]
#define APP_START_ADDRESS 0x2000
#define APP_START_ADDRESS 0x0000



But this is a very nice opportunity to learn more. Would you please elaborate what does the code use and does?, I really don´t understand it, the "extern" keyboard is for declaring a variable/function that lives outside of the scope of the file, and also why the "C" definition should lie before setup?, and then a new "C" definition after the loop?

AloyseTech

#5
Feb 18, 2016, 06:54 pm Last Edit: Feb 18, 2016, 06:56 pm by AloyseTech
try with address 0x000000, but you have to reset all peripheral you're using in the app : SPI.end() for example. By the way, you may have to use it dissconnected to any USB data cable : power your board from an external suply. I'm not sure about the USB problem, but my code only works when I'm not using the USB cable...

The "C" wrapper is for the compiler. And if you use plain C, you have to put the function prototype at the beginning of the code, and then define the function wherever you want.

Code: [Select]
extern "C" {
#define APP_START_ADDRESS 0x0000

  void jumpApplication() {
    /* Pointer to the Application Section */
    void (*application_code_entry)(void);
    /* Rebase the Stack Pointer */
    __set_MSP(*(uint32_t *) APP_START_ADDRESS);
    /* Rebase the vector table base address */
    SCB->VTOR = ((uint32_t) APP_START_ADDRESS & SCB_VTOR_TBLOFF_Msk);
    /* Load the Reset Handler address of the application */
    application_code_entry = (void (*)(void))(unsigned *)(*(unsigned *)(APP_START_ADDRESS + 4));
    /* Jump to user Reset Handler in the application */
    application_code_entry();
  }
}

Sulimarco

Hi Kinematik,

unfortunatly, I am not able to answer to your question.   :smiley-sad:  :smiley-sad:


I discovered the reset function digging in the internet, but I too would like to know which CMSIS functions are available in the Arduino ide and where is possible to find a clear documentation of this.

It would be very useful to have such informations !!!

So I join to your request and I hope that somebody more expert than you and me could find an answer.


Marco
   

MartinL

#7
Feb 18, 2016, 11:51 pm Last Edit: Feb 18, 2016, 11:54 pm by MartinL
The NVIC_SystemReset() function is briefly mentioned together with other CMSIS functions for NVIC control on page 4-7 of the "Cortex-M0+ Devices Generic User Guide". It's possible to download it from the ARM Information Center: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0484c/index.html

cometa

Hello i want to remove the delay after i press the reset button, there are some solution for this?

AloyseTech

The best solution is to skip the bootloader. If you don't need to chanre your application once programmed, compile and program at address 0 instead of 0x2000, and don't put any bootloader.

kinematik

Hello i want to remove the delay after i press the reset button, there are some solution for this?
I am not sure I am understand correctly your requirement: do you want to reset (via software) the Zero board just after pushing a button?

If this is the case is quite easy:

Code: [Select]
bool button = digitalRead(BUTTON_PIN);  

if (button) {
    NVIC_SystemReset();      // processor software reset  
}


You can also go the AloyseTech way, although for me did not work.

Nemo1234

Reset in the form of a power-on reboot is easy. Use assembly language to "jmp 0".
Try this:

void software_Reset() // Restarts program from beginning
{
asm volatile ("  jmp 0"); 
}

Go Up