Page 1 of 2

close the command shell

Posted: Thu Sep 18, 2014 2:18 pm
by ucasano
Hello all,

I am trying to close the command shell in order to make a system restart/reset.
The command shell prompts on sd2.

The way I do it is:

Code: Select all

int main(void) {
   uint32_t ApplicationAddress = FLASH_BASE;
   uint32_t stack = *(__IO uint32_t*) ApplicationAddress;
   pFunction Jump_To_Application = (pFunction) (*(__IO uint32_t*) (ApplicationAddress + 4));
   halInit();
   chSysInit();

   /* init dshell */
   dshell_init();

   while (!restart_flag) {
      /* create shell */
      dshell_create();

      chThdSleepMicroseconds(200);
   } /* main while */

   dshell_exit();

   chSysDisable();
   /* Clear pending interrupts just to be on the save side*/
   SCB_ICSR = ICSR_PENDSVCLR;

   /* Disable all interrupts */
   for(i=0; i<8; i++)
      NVIC->ICER[i] = NVIC->IABR[i];

   __set_MSP(stack);
   Jump_To_Application();

   return 0;
}


where:

Code: Select all

void dshell_init(void) {
   /*
    * Shell manager initialization.
    */
   shellInit();

   /*
    * Activates the serial driver 6 and SDC driver 1 using default
    * configuration.
    */
   /*
    * Activates the serial driver 1 using the driver default configuration.
    * PA2(TX) and PA3(RX) are routed to USART2.
    */
   sdStart(&SD2, NULL);
   palSetPadMode(GPIOA, GPIOA_USART2_TXD, PAL_MODE_ALTERNATE(7));
   palSetPadMode(GPIOA, GPIOA_USART2_RXD, PAL_MODE_ALTERNATE(7));
}

void dshell_create(void) {
   if (!shelltp)// && (SDU1.config->usbp->state == USB_ACTIVE))
         shelltp = shellCreateStatic(&shell_cfg1, waShellThread, sizeof(waShellThread), NORMALPRIO);
   else if (chThdTerminated(shelltp)) {
      chThdRelease(shelltp);    /* Recovers memory of the previous shell.   */
       shelltp = NULL;           /* Triggers spawning of a new shell.        */
   }
}

void dshell_exit(void) {
   /* shellExit(RDY_OK); */
   sdStop(&SD2);
}


I had to comment the shellExit stuff because otherwise system hangs.
Is this way the right one?

Thank you in advance.
-g

Re: close the command shell

Posted: Thu Sep 18, 2014 4:02 pm
by Giovanni
Hi,

shellExit() must be called from the shell thread, you cannot kill a shell from outside, the only option you have is to reset (chIQResetI()) the input queue of the SD driver, that will make the shell logout. The you have to chThdWait() the shell thread in order to recover memory.

Giovanni

Re: close the command shell

Posted: Thu Sep 18, 2014 4:14 pm
by ucasano
Hi giovanni, I need to kill the shell from outside.

How can I accomplish it, with the code I reported above?

I suggest the following shell_exit function:

Code: Select all

void dshell_exit(void) {
   sdStop(&SD2);

   if(shelltp) {
      chThdTerminate(shelltp);     // Requesting termination.
   }

   if (shelltp && chThdTerminated(shelltp)) {
      chThdWait(shelltp);
      shelltp = NULL;
   }

}


What about it?

Re: close the command shell

Posted: Thu Sep 18, 2014 4:16 pm
by Giovanni
That would not work, the shell is waiting for input on the input queue.

Giovanni

Re: close the command shell

Posted: Thu Sep 18, 2014 6:10 pm
by ucasano
uhmmmm looks like an exam... :D

So, what about this:

Code: Select all

void dshell_exit(void) {

   if(shelltp) {
      chThdTerminate(shelltp);     // Requesting termination.
   }

   if (shelltp && chThdTerminated(shelltp)) {
      chThdWait(shelltp);
      shelltp = NULL;
   }

   sdStop(&SD2);
}

Re: close the command shell

Posted: Thu Sep 18, 2014 6:38 pm
by Giovanni
chThdTerminate() IS NOT GOING TO WORK because the thread does not check for it. The only way to make the shell exit is to RESET THE INPUT QUEUE of the serial driver.

Giovanni

Re: close the command shell

Posted: Fri Sep 19, 2014 8:45 am
by ucasano
Ok, in such a case the following should do the trick:

Code: Select all

void dshell_exit(void) {

   chSysLock();
   chIQResetI(&SD2);
   chSysUnlock();

   if (shelltp && chThdTerminated(shelltp)) {
      chThdWait(shelltp);
      shelltp = NULL;
   }

   sdStop(&SD2);
}

Re: close the command shell

Posted: Fri Sep 19, 2014 8:52 am
by Giovanni
It should, but you have to reset just the queue, not the driver.

Giovanni

Re: close the command shell

Posted: Fri Sep 19, 2014 9:04 am
by ucasano
this "restart in bootloader mode" should work like a complete reset of the system, with all of its peripherals and accessories.

do you know a smarter way to reset the micro-stuff ;) ?
-g

Re: close the command shell

Posted: Fri Sep 19, 2014 9:24 am
by Giovanni