Merge pull request #724 from rousselk/reboot

Reboot
This commit is contained in:
Oleg Hahm 2014-02-18 13:33:49 +01:00
commit b42496475a
10 changed files with 138 additions and 34 deletions

View File

@ -13,6 +13,8 @@
* @file kernel.h
* @brief Kernel compile time configuration
*
* A reboot() function is also provided (and used by panic() when needed).
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
@ -21,6 +23,8 @@
#define KERNEL_H_
#include <stdbool.h>
#include "attributes.h"
#include "config.h"
#include "tcb.h"
#include "cpu.h"
@ -86,5 +90,16 @@ extern volatile int lpm_prevent_sleep;
extern config_t sysconfig;
/* ------------------------------------------------------------------------- */
/**
* @brief Immediately reboots the system.
*
* This function is used by panic() when the DEVELHELP macro is not defined.
*
* @return WARNING: this function NEVER returns!
*/
NORETURN void reboot(void);
/** @} */
#endif /* KERNEL_H_ */

View File

@ -19,6 +19,7 @@
#include <stdio.h>
#include "arm_cpu.h"
#include "sched.h"
#include "kernel.h"
#include "kernel_internal.h"
#define STACK_MARKER (0x77777777)
@ -84,3 +85,10 @@ void thread_print_stack(void)
printf("STACK (%u)= %X \n", i, *s);
}
NORETURN void reboot(void)
{
while (1) {
arm_reset();
}
}

View File

@ -14,28 +14,29 @@
#include <stdint.h>
#include "cpu.h"
#include "kernel.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
int inISR(void)
{
return (__get_IPSR() & 0xFF);
return (__get_IPSR() & 0xFF);
}
unsigned int disableIRQ(void)
{
// FIXME PRIMASK is the old CPSR (FAULTMASK ??? BASEPRI ???)
//PRIMASK lesen
unsigned int uiPriMask = __get_PRIMASK();
__disable_irq();
return uiPriMask;
// FIXME PRIMASK is the old CPSR (FAULTMASK ??? BASEPRI ???)
//PRIMASK lesen
unsigned int uiPriMask = __get_PRIMASK();
__disable_irq();
return uiPriMask;
}
void restoreIRQ(unsigned oldPRIMASK)
{
//PRIMASK lesen setzen
__set_PRIMASK(oldPRIMASK);
//PRIMASK lesen setzen
__set_PRIMASK(oldPRIMASK);
}
@ -75,34 +76,59 @@ void eINT(void)
void save_context(void)
{
/* {r0-r3,r12,LR,PC,xPSR} are saved automatically on exception entry */
asm("push {r4-r11}");
/* save unsaved registers */
asm("push {LR}");
/* save exception return value */
/* {r0-r3,r12,LR,PC,xPSR} are saved automatically on exception entry */
asm("push {r4-r11}");
/* save unsaved registers */
asm("push {LR}");
/* save exception return value */
asm("ldr r1, =active_thread");
/* load address of currend pdc */
asm("ldr r1, [r1]");
/* deref pdc */
asm("str sp, [r1]");
/* write sp to pdc->sp means current threads stack pointer */
asm("ldr r1, =active_thread");
/* load address of currend pdc */
asm("ldr r1, [r1]");
/* deref pdc */
asm("str sp, [r1]");
/* write sp to pdc->sp means current threads stack pointer */
}
void restore_context(void)
{
asm("ldr r0, =active_thread");
/* load address of currend pdc */
asm("ldr r0, [r0]");
/* deref pdc */
asm("ldr sp, [r0]");
/* load pdc->sp to sp register */
asm("ldr r0, =active_thread");
/* load address of currend pdc */
asm("ldr r0, [r0]");
/* deref pdc */
asm("ldr sp, [r0]");
/* load pdc->sp to sp register */
asm("pop {r0}");
/* restore exception retrun value from stack */
asm("pop {r4-r11}");
/* load unloaded register */
// asm("pop {r4}"); /*foo*/
asm("bx r0"); /* load exception return value to pc causes end of exception*/
/* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */
asm("pop {r0}");
/* restore exception retrun value from stack */
asm("pop {r4-r11}");
/* load unloaded register */
// asm("pop {r4}"); /*foo*/
asm("bx r0"); /* load exception return value to pc causes end of exception*/
/* {r0-r3,r12,LR,PC,xPSR} are restored automatically on exception return */
}
#define USR_RESET (0x102)
#define SWI (0xAB)
__attribute__((naked,noreturn)) void arm_reset(void)
{
int value;
asm volatile (
"mov r0, %1" "\n\t"
"mov r1, %2" "\n\t"
"bkpt" " %a3" "\n\t"
"mov %0, r0"
: "=r" (value) /* output operands */
: "r" USR_RESET, "r" NULL, "i" SWI /* input operands */
: "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc" /* list of clobbered registers */
);
}
NORETURN void reboot(void)
{
while (1) {
arm_reset();
}
}

View File

@ -86,3 +86,15 @@ int inISR()
{
return __inISR;
}
/******************************************************************************/
/* System reboot */
NORETURN void reboot(void)
{
/* force an hardware reboot ("Power-Up Clear"), by writing
an illegal value to the watchdog control register */
while (1) {
WDTCTL = 0x0000;
}
}

View File

@ -54,6 +54,7 @@ extern ucontext_t end_context;
extern ucontext_t *_native_cur_ctx, *_native_isr_ctx;
extern const char *_progname;
extern char **_native_argv;
#ifdef MODULE_UART0
#include <sys/select.h>

View File

@ -15,7 +15,9 @@
* @file
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*/
#include <stdio.h>
#include <unistd.h>
#ifdef __MACH__
#define _XOPEN_SOURCE
@ -40,6 +42,8 @@
#include <stdlib.h>
#include "kernel_internal.h"
#include "kernel.h"
#include "irq.h"
#include "sched.h"
#include "cpu.h"
@ -59,6 +63,15 @@ char __end_stack[SIGSTKSZ];
fd_set _native_rfds;
#endif
NORETURN void reboot(void)
{
printf("\n\n\t\t!! REBOOT !!\n\n");
if (execve(_native_argv[0], _native_argv, NULL) == -1) {
err(EXIT_FAILURE, "reboot: execve");
}
errx(EXIT_FAILURE, "reboot: this should not habe been reached");
}
/**
* TODO: implement
*/

View File

@ -41,6 +41,7 @@ int (*real_printf)(const char *format, ...);
int _native_null_in_pipe[2];
int _native_null_out_file;
const char *_progname;
char **_native_argv;
/**
* initialize _native_null_in_pipe to allow for reading from stdin
@ -191,7 +192,9 @@ __attribute__((constructor)) static void startup(int argc, char **argv)
*(void **)(&real_printf) = dlsym(RTLD_NEXT, "printf");
_native_argv = argv;
_progname = argv[0];
int argp = 1;
char *stderrtype = "stdio";
char *stdouttype = "stdio";

View File

@ -1,4 +1,4 @@
SRC = shell_commands.c sc_id.c
SRC = shell_commands.c sc_id.c sc_sys.c
ifneq (,$(filter transceiver,$(USEMODULE)))
SRC += sc_transceiver.c

View File

@ -0,0 +1,24 @@
/**
* Shell commands for system calls
*
* Copyright (C) 2014 Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*
* @ingroup shell_commands
* @{
* @file
* @brief shell commands for system calls
* @author Ludwig Ortmann <ludwig.ortmann@fu-berlin.de>
* @}
*/
#include "kernel.h"
void _reboot_handler(char *unused)
{
(void) unused;
reboot();
}

View File

@ -1,7 +1,7 @@
/**
* Provides prototypes for available shell commands
*
* Copyright (C) 2013 INRIA.
* Copyright (C) 2014 INRIA.
*
* This source code is licensed under the LGPLv2 license,
* See the file LICENSE for more details.
@ -24,6 +24,7 @@
#include "shell_commands.h"
extern void _id_handler(char *id);
extern void _reboot_handler(char *unused);
extern void _heap_handler(char *unused);
#ifdef MODULE_PS
@ -104,6 +105,7 @@ extern void _mersenne_get(char *str);
const shell_command_t _shell_command_list[] = {
{"id", "Gets or sets the node's id.", _id_handler},
{"reboot", "Reboot the node", _reboot_handler},
#ifdef MODULE_LPC_COMMON
{"heap", "Shows the heap state for the LPC2387 on the command shell.", _heap_handler},
#endif