📄 main.c
字号:
//==========================================================================
//
// main.c
//
// RedBoot main routine
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
// Copyright (C) 2002, 2003, 2004 Gary Thomas
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, tkoeller
// Date: 2000-07-14
// Purpose:
// Description:
//
// This code is part of RedBoot (tm).
//
//####DESCRIPTIONEND####
//
//==========================================================================
#define DEFINE_VARS
#include <redboot.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/hal_if.h>
#include <cyg/hal/hal_cache.h>
#include CYGHWR_MEMORY_LAYOUT_H
#ifdef CYGPKG_IO_ETH_DRIVERS
#include <cyg/io/eth/eth_drv.h> // Logical driver interfaces
#endif
#include <cyg/hal/hal_tables.h>
#include <cyg/infra/cyg_ass.h> // assertion macros
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
#include CYGBLD_HAL_PLATFORM_STUB_H
#else
#include <cyg/hal/plf_stub.h>
#endif
// GDB interfaces
extern void breakpoint(void);
#endif
// Builtin Self Test (BIST)
externC void bist(void);
// Path to code run from a go command or to GDB stubs
static void trampoline(unsigned long entry);
// Return path for code run from a go command or for GDB stubs
static void return_to_redboot(int status);
// Address of area where current context is saved before executing
// trampoline procedure
static void * saved_context;
// Status returned after trampoline execution
static int return_status;
// CLI command processing (defined in this file)
RedBoot_cmd("version",
"Display RedBoot version information",
"",
do_version
);
RedBoot_cmd("help",
"Help about help?",
"[<topic>]",
do_help
);
static char go_usage[] = "[-w <timeout>] [-c] "
#ifdef CYGPKG_IO_ETH_DRIVERS
"[-n] "
#endif
"[entry]";
RedBoot_cmd("go",
"Execute code at a location",
go_usage,
do_go
);
#ifdef HAL_PLATFORM_RESET
RedBoot_cmd("reset",
"Reset the system",
"",
do_reset
);
#endif
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
RedBoot_cmd("baudrate",
"Set/Query the system console baud rate",
"[-b <rate>]",
do_baud_rate
);
#endif
// Define table boundaries
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;
CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
#endif
//
// [Null] Builtin [Power On] Self Test
//
void bist(void) CYGBLD_ATTRIB_WEAK;
void
bist(void)
{
}
//
// 'version' command
//
void
do_version(int argc, char *argv[])
{
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
int seg;
#endif
#ifdef CYGPKG_REDBOOT_FLASH
externC void _flash_info(void);
#endif
char *version = CYGACC_CALL_IF_MONITOR_VERSION();
diag_printf(version);
#ifdef HAL_PLATFORM_CPU
diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
#endif
diag_printf("Copyright (C) 2000, 2001, 2002, Red Hat, Inc.\n\n");
diag_printf("RAM: %p-%p, ", (void*)ram_start, (void*)ram_end);
diag_printf("[%p-%p]", mem_segments[0].start, mem_segments[0].end);
diag_printf(" available\n");
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
if (mem_segments[seg].start != NO_MEMORY) {
diag_printf(" %p-%p, ", mem_segments[seg].start, mem_segments[seg].end);
diag_printf("[%p-%p]", mem_segments[seg].start, mem_segments[seg].end);
diag_printf(" available\n");
}
}
#endif
#ifdef CYGPKG_REDBOOT_FLASH
_flash_info();
#endif
}
//
// This function is called when RedBoot is idle (waiting for user
// input). It will call any registered "idle" routines, e.g. scan
// for incoming network connections, blank an LCD screen, etc.
//
void
do_idle(bool is_idle)
{
struct idle_tab_entry *idle_entry;
for (idle_entry = __RedBoot_IDLE_TAB__;
idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) {
(*idle_entry->fun)(is_idle);
}
}
// Wrapper used by diag_printf()
static void
_mon_write_char(char c, void **param)
{
if (c == '\n') {
mon_write_char('\r');
}
mon_write_char(c);
}
//
// Handle illegal memory accesses (and other abort conditions)
//
static hal_jmp_buf error_jmpbuf;
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
externC
#endif
void* volatile __mem_fault_handler;
static void error_handler(void)
{
hal_longjmp(error_jmpbuf, 1);
}
//
// This is the main entry point for RedBoot
//
void
cyg_start(void)
{
int res = 0;
bool prompt = true;
static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
char *command;
struct cmd *cmd;
int cur;
struct init_tab_entry *init_entry;
extern char RedBoot_version[];
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
int seg;
#endif
// Export version information
CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
// Make sure the channels are properly initialized.
diag_init_putc(_mon_write_char);
hal_if_diag_init();
// Force console to output raw text - but remember the old setting
// so it can be restored if interaction with a debugger is
// required.
cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
console_selected = false;
#endif
console_echo = true;
CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);
ram_start = (unsigned char *)CYGMEM_REGION_ram;
ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
#ifdef HAL_MEM_REAL_REGION_TOP
{
unsigned char *ram_end_tmp = ram_end;
ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
}
#endif
#ifdef CYGMEM_SECTION_heap1
workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
workspace_size = CYGMEM_SECTION_heap1_SIZE;
#else
workspace_start = (unsigned char *)CYGMEM_REGION_ram;
workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
workspace_size = CYGMEM_REGION_ram_SIZE;
#endif
if ( ram_end < workspace_end ) {
// when *less* SDRAM is installed than the possible maximum,
// but the heap1 region remains greater...
workspace_end = ram_end;
workspace_size = workspace_end - workspace_start;
}
// Nothing has ever been loaded into memory
entry_address = (unsigned long)NO_MEMORY;
bist();
#if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER)
fis_zlib_common_buffer =
workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
#endif
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
#endif
for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
(*init_entry->fun)();
}
mem_segments[0].start = workspace_start;
mem_segments[0].end = workspace_end;
#if CYGBLD_REDBOOT_MAX_MEM_SEGMENTS > 1
for (seg = 1; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
cyg_plf_memory_segment(seg, &mem_segments[seg].start, &mem_segments[seg].end);
}
#endif
#ifdef CYGSEM_REDBOOT_PLF_STARTUP
cyg_plf_redboot_startup();
#endif
do_version(0,0);
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
if (!script) {
script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
}
# endif
if (script) {
// Give the guy a chance to abort any boot script
unsigned char *hold_script = script;
int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
script_timeout_ms/1000, script_timeout_ms%1000);
script = (unsigned char *)0;
res = _GETS_CTRLC; // Treat 0 timeout as ^C
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
if (res >= _GETS_OK) {
diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
script_timeout_ms/1000, script_timeout_ms%1000);
continue; // Ignore anything but ^C
}
if (res != _GETS_TIMEOUT) break;
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
}
if (res == _GETS_CTRLC) {
script = (unsigned char *)0; // Disable script
} else {
script = hold_script; // Re-enable script
}
}
#endif
while (true) {
if (prompt) {
diag_printf("RedBoot> ");
prompt = false;
}
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
cmd_history = true; // Enable history collection
#endif
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
cmd_history = false; // Enable history collection
#endif
if (res == _GETS_TIMEOUT) {
// No input arrived
} else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -