//==========================================================================
|
//==========================================================================
|
//
|
//
|
// main.c
|
// main.c
|
//
|
//
|
// RedBoot main routine
|
// RedBoot main routine
|
//
|
//
|
//==========================================================================
|
//==========================================================================
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
// -------------------------------------------
|
// -------------------------------------------
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
|
// Copyright (C) 2002 Gary Thomas
|
// Copyright (C) 2002 Gary Thomas
|
//
|
//
|
// eCos is free software; you can redistribute it and/or modify it under
|
// 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
|
// 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.
|
// 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
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for more details.
|
// for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License along
|
// You should have received a copy of the GNU General Public License along
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
//
|
//
|
// As a special exception, if other files instantiate templates or use macros
|
// 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
|
// 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
|
// 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
|
// 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
|
// License. However the source code for this file must still be made available
|
// in accordance with section (3) of the GNU General Public License.
|
// 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 exception does not invalidate any other reasons why a work based on
|
// this file might be covered by the GNU General Public License.
|
// this file might be covered by the GNU General Public License.
|
//
|
//
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
// at http://sources.redhat.com/ecos/ecos-license/
|
// at http://sources.redhat.com/ecos/ecos-license/
|
// -------------------------------------------
|
// -------------------------------------------
|
//####ECOSGPLCOPYRIGHTEND####
|
//####ECOSGPLCOPYRIGHTEND####
|
//==========================================================================
|
//==========================================================================
|
//#####DESCRIPTIONBEGIN####
|
//#####DESCRIPTIONBEGIN####
|
//
|
//
|
// Author(s): gthomas
|
// Author(s): gthomas
|
// Contributors: gthomas, tkoeller
|
// Contributors: gthomas, tkoeller
|
// Date: 2000-07-14
|
// Date: 2000-07-14
|
// Purpose:
|
// Purpose:
|
// Description:
|
// Description:
|
//
|
//
|
// This code is part of RedBoot (tm).
|
// This code is part of RedBoot (tm).
|
//
|
//
|
//####DESCRIPTIONEND####
|
//####DESCRIPTIONEND####
|
//
|
//
|
//==========================================================================
|
//==========================================================================
|
|
|
#define DEFINE_VARS
|
#define DEFINE_VARS
|
#include <redboot.h>
|
#include <redboot.h>
|
#include <cyg/hal/hal_arch.h>
|
#include <cyg/hal/hal_arch.h>
|
#include <cyg/hal/hal_intr.h>
|
#include <cyg/hal/hal_intr.h>
|
#include <cyg/hal/hal_if.h>
|
#include <cyg/hal/hal_if.h>
|
#include <cyg/hal/hal_cache.h>
|
#include <cyg/hal/hal_cache.h>
|
#include CYGHWR_MEMORY_LAYOUT_H
|
#include CYGHWR_MEMORY_LAYOUT_H
|
|
|
#include <cyg/hal/hal_tables.h>
|
#include <cyg/hal/hal_tables.h>
|
|
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
|
#ifdef CYGBLD_HAL_PLATFORM_STUB_H
|
#include CYGBLD_HAL_PLATFORM_STUB_H
|
#include CYGBLD_HAL_PLATFORM_STUB_H
|
#else
|
#else
|
#include <cyg/hal/plf_stub.h>
|
#include <cyg/hal/plf_stub.h>
|
#endif
|
#endif
|
// GDB interfaces
|
// GDB interfaces
|
extern void breakpoint(void);
|
extern void breakpoint(void);
|
#endif
|
#endif
|
|
|
// Builtin Self Test (BIST)
|
// Builtin Self Test (BIST)
|
externC void bist(void);
|
externC void bist(void);
|
|
|
// Return path for code run from a go command
|
// Return path for code run from a go command
|
static void return_to_redboot(int status);
|
static void return_to_redboot(int status);
|
|
|
|
|
// CLI command processing (defined in this file)
|
// CLI command processing (defined in this file)
|
RedBoot_cmd("version",
|
RedBoot_cmd("version",
|
"Display RedBoot version information",
|
"Display RedBoot version information",
|
"",
|
"",
|
do_version
|
do_version
|
);
|
);
|
RedBoot_cmd("help",
|
RedBoot_cmd("help",
|
"Help about help?",
|
"Help about help?",
|
"[<topic>]",
|
"[<topic>]",
|
do_help
|
do_help
|
);
|
);
|
RedBoot_cmd("go",
|
RedBoot_cmd("go",
|
"Execute code at a location",
|
"Execute code at a location",
|
"[-w <timeout>] [entry]",
|
"[-w <timeout>] [entry]",
|
do_go
|
do_go
|
);
|
);
|
#ifdef HAL_PLATFORM_RESET
|
#ifdef HAL_PLATFORM_RESET
|
RedBoot_cmd("reset",
|
RedBoot_cmd("reset",
|
"Reset the system",
|
"Reset the system",
|
"",
|
"",
|
do_reset
|
do_reset
|
);
|
);
|
#endif
|
#endif
|
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
|
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
|
RedBoot_cmd("baudrate",
|
RedBoot_cmd("baudrate",
|
"Set/Query the system console baud rate",
|
"Set/Query the system console baud rate",
|
"[-b <rate>]",
|
"[-b <rate>]",
|
do_baud_rate
|
do_baud_rate
|
);
|
);
|
#endif
|
#endif
|
|
|
// Define table boundaries
|
// Define table boundaries
|
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
|
CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
|
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
|
CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );
|
extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;
|
extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;
|
|
|
CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
|
CYG_HAL_TABLE_BEGIN( __RedBoot_CMD_TAB__, RedBoot_commands );
|
CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
|
CYG_HAL_TABLE_END( __RedBoot_CMD_TAB_END__, RedBoot_commands );
|
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
|
extern struct cmd __RedBoot_CMD_TAB__[], __RedBoot_CMD_TAB_END__;
|
|
|
CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
|
CYG_HAL_TABLE_BEGIN( __RedBoot_IDLE_TAB__, RedBoot_idle );
|
CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
|
CYG_HAL_TABLE_END( __RedBoot_IDLE_TAB_END__, RedBoot_idle );
|
extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;
|
extern struct idle_tab_entry __RedBoot_IDLE_TAB__[], __RedBoot_IDLE_TAB_END__;
|
|
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
|
extern void HAL_ARCH_PROGRAM_NEW_STACK(void *fun);
|
#endif
|
#endif
|
|
|
|
|
void
|
void
|
do_version(int argc, char *argv[])
|
do_version(int argc, char *argv[])
|
{
|
{
|
#ifdef CYGPKG_IO_FLASH
|
#ifdef CYGPKG_IO_FLASH
|
externC void _flash_info(void);
|
externC void _flash_info(void);
|
#endif
|
#endif
|
char *version = CYGACC_CALL_IF_MONITOR_VERSION();
|
char *version = CYGACC_CALL_IF_MONITOR_VERSION();
|
|
|
diag_printf(version);
|
diag_printf(version);
|
#ifdef HAL_PLATFORM_CPU
|
#ifdef HAL_PLATFORM_CPU
|
diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
|
diag_printf("Platform: %s (%s) %s\n", HAL_PLATFORM_BOARD, HAL_PLATFORM_CPU, HAL_PLATFORM_EXTRA);
|
#endif
|
#endif
|
diag_printf("Copyright (C) 2000, 2001, 2002, Red Hat, Inc.\n\n");
|
diag_printf("Copyright (C) 2000, 2001, 2002, Red Hat, Inc.\n\n");
|
diag_printf("RAM: %p-%p, %p-%p available\n",
|
diag_printf("RAM: %p-%p, %p-%p available\n",
|
(void*)ram_start, (void*)ram_end,
|
(void*)ram_start, (void*)ram_end,
|
(void*)user_ram_start, (void *)user_ram_end);
|
(void*)user_ram_start, (void *)user_ram_end);
|
#ifdef CYGPKG_IO_FLASH
|
#ifdef CYGPKG_IO_FLASH
|
_flash_info();
|
_flash_info();
|
#endif
|
#endif
|
}
|
}
|
|
|
void
|
void
|
do_idle(bool is_idle)
|
do_idle(bool is_idle)
|
{
|
{
|
struct idle_tab_entry *idle_entry;
|
struct idle_tab_entry *idle_entry;
|
|
|
for (idle_entry = __RedBoot_IDLE_TAB__;
|
for (idle_entry = __RedBoot_IDLE_TAB__;
|
idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) {
|
idle_entry != &__RedBoot_IDLE_TAB_END__; idle_entry++) {
|
(*idle_entry->fun)(is_idle);
|
(*idle_entry->fun)(is_idle);
|
}
|
}
|
}
|
}
|
|
|
// Wrapper used by diag_printf()
|
// Wrapper used by diag_printf()
|
static void
|
static void
|
_mon_write_char(char c, void **param)
|
_mon_write_char(char c, void **param)
|
{
|
{
|
if (c == '\n') {
|
if (c == '\n') {
|
mon_write_char('\r');
|
mon_write_char('\r');
|
}
|
}
|
mon_write_char(c);
|
mon_write_char(c);
|
}
|
}
|
|
|
//
|
//
|
// This is the main entry point for RedBoot
|
// This is the main entry point for RedBoot
|
//
|
//
|
void
|
void
|
cyg_start(void)
|
cyg_start(void)
|
{
|
{
|
int res = 0;
|
int res = 0;
|
bool prompt = true;
|
bool prompt = true;
|
static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
|
static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
|
char *command;
|
char *command;
|
struct cmd *cmd;
|
struct cmd *cmd;
|
int cur;
|
int cur;
|
struct init_tab_entry *init_entry;
|
struct init_tab_entry *init_entry;
|
extern char RedBoot_version[];
|
extern char RedBoot_version[];
|
|
|
// Export version information
|
// Export version information
|
CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
|
CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
|
|
|
CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
|
CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
|
|
|
// Make sure the channels are properly initialized.
|
// Make sure the channels are properly initialized.
|
diag_init_putc(_mon_write_char);
|
diag_init_putc(_mon_write_char);
|
hal_if_diag_init();
|
hal_if_diag_init();
|
|
|
// Force console to output raw text - but remember the old setting
|
// Force console to output raw text - but remember the old setting
|
// so it can be restored if interaction with a debugger is
|
// so it can be restored if interaction with a debugger is
|
// required.
|
// required.
|
cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
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);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL);
|
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
|
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
|
console_selected = false;
|
console_selected = false;
|
#endif
|
#endif
|
console_echo = true;
|
console_echo = true;
|
CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);
|
CYGACC_CALL_IF_DELAY_US((cyg_int32)2*100000);
|
|
|
ram_start = (unsigned char *)CYGMEM_REGION_ram;
|
ram_start = (unsigned char *)CYGMEM_REGION_ram;
|
ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
|
ram_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
|
#ifdef HAL_MEM_REAL_REGION_TOP
|
#ifdef HAL_MEM_REAL_REGION_TOP
|
{
|
{
|
unsigned char *ram_end_tmp = ram_end;
|
unsigned char *ram_end_tmp = ram_end;
|
ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
|
ram_end = HAL_MEM_REAL_REGION_TOP( ram_end_tmp );
|
}
|
}
|
#endif
|
#endif
|
#ifdef CYGMEM_SECTION_heap1
|
#ifdef CYGMEM_SECTION_heap1
|
workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
|
workspace_start = (unsigned char *)CYGMEM_SECTION_heap1;
|
workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
|
workspace_end = (unsigned char *)(CYGMEM_SECTION_heap1+CYGMEM_SECTION_heap1_SIZE);
|
workspace_size = CYGMEM_SECTION_heap1_SIZE;
|
workspace_size = CYGMEM_SECTION_heap1_SIZE;
|
#else
|
#else
|
workspace_start = (unsigned char *)CYGMEM_REGION_ram;
|
workspace_start = (unsigned char *)CYGMEM_REGION_ram;
|
workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
|
workspace_end = (unsigned char *)(CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE);
|
workspace_size = CYGMEM_REGION_ram_SIZE;
|
workspace_size = CYGMEM_REGION_ram_SIZE;
|
#endif
|
#endif
|
|
|
if ( ram_end < workspace_end ) {
|
if ( ram_end < workspace_end ) {
|
// when *less* SDRAM is installed than the possible maximum,
|
// when *less* SDRAM is installed than the possible maximum,
|
// but the heap1 region remains greater...
|
// but the heap1 region remains greater...
|
workspace_end = ram_end;
|
workspace_end = ram_end;
|
workspace_size = workspace_end - workspace_start;
|
workspace_size = workspace_end - workspace_start;
|
}
|
}
|
|
|
bist();
|
bist();
|
|
|
#ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
|
#ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
|
fis_zlib_common_buffer =
|
fis_zlib_common_buffer =
|
workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
|
workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
|
#endif
|
#endif
|
|
|
for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
|
for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
|
(*init_entry->fun)();
|
(*init_entry->fun)();
|
}
|
}
|
|
|
user_ram_start = workspace_start;
|
user_ram_start = workspace_start;
|
user_ram_end = workspace_end;
|
user_ram_end = workspace_end;
|
|
|
do_version(0,0);
|
do_version(0,0);
|
|
|
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
|
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
|
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
|
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
|
if (!script) {
|
if (!script) {
|
script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
|
script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
|
# ifndef CYGSEM_REDBOOT_FLASH_CONFIG
|
# ifndef CYGSEM_REDBOOT_FLASH_CONFIG
|
script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
|
script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
|
# endif
|
# endif
|
}
|
}
|
# endif
|
# endif
|
if (script) {
|
if (script) {
|
// Give the guy a chance to abort any boot script
|
// Give the guy a chance to abort any boot script
|
unsigned char *hold_script = script;
|
unsigned char *hold_script = script;
|
int script_timeout_ms = script_timeout * CYGNUM_REDBOOT_BOOT_SCRIPT_TIMEOUT_RESOLUTION;
|
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",
|
diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
|
script_timeout_ms/1000, script_timeout_ms%1000);
|
script_timeout_ms/1000, script_timeout_ms%1000);
|
script = (unsigned char *)0;
|
script = (unsigned char *)0;
|
res = _GETS_CTRLC; // Treat 0 timeout as ^C
|
res = _GETS_CTRLC; // Treat 0 timeout as ^C
|
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
|
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
if (res >= _GETS_OK) {
|
if (res >= _GETS_OK) {
|
diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
|
diag_printf("== Executing boot script in %d.%03d seconds - enter ^C to abort\n",
|
script_timeout_ms/1000, script_timeout_ms%1000);
|
script_timeout_ms/1000, script_timeout_ms%1000);
|
continue; // Ignore anything but ^C
|
continue; // Ignore anything but ^C
|
}
|
}
|
if (res != _GETS_TIMEOUT) break;
|
if (res != _GETS_TIMEOUT) break;
|
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
|
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
|
}
|
}
|
if (res == _GETS_CTRLC) {
|
if (res == _GETS_CTRLC) {
|
script = (unsigned char *)0; // Disable script
|
script = (unsigned char *)0; // Disable script
|
} else {
|
} else {
|
script = hold_script; // Re-enable script
|
script = hold_script; // Re-enable script
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
|
|
while (true) {
|
while (true) {
|
if (prompt) {
|
if (prompt) {
|
diag_printf("RedBoot> ");
|
diag_printf("RedBoot> ");
|
prompt = false;
|
prompt = false;
|
}
|
}
|
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
|
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
|
cmd_history = true; // Enable history collection
|
cmd_history = true; // Enable history collection
|
#endif
|
#endif
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
|
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
|
cmd_history = false; // Enable history collection
|
cmd_history = false; // Enable history collection
|
#endif
|
#endif
|
if (res == _GETS_TIMEOUT) {
|
if (res == _GETS_TIMEOUT) {
|
// No input arrived
|
// No input arrived
|
} else {
|
} else {
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
if (res == _GETS_GDB) {
|
if (res == _GETS_GDB) {
|
int dbgchan;
|
int dbgchan;
|
hal_virtual_comm_table_t *__chan;
|
hal_virtual_comm_table_t *__chan;
|
int i;
|
int i;
|
// Special case of '$' - need to start GDB protocol
|
// Special case of '$' - need to start GDB protocol
|
gdb_active = true;
|
gdb_active = true;
|
// Mask interrupts on all channels
|
// Mask interrupts on all channels
|
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
|
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
|
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
|
CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
|
}
|
}
|
|
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
|
HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
|
#else
|
#else
|
breakpoint(); // Get GDB stubs started, with a proper environment, etc.
|
breakpoint(); // Get GDB stubs started, with a proper environment, etc.
|
#endif
|
#endif
|
dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
|
} else
|
} else
|
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
|
{
|
{
|
expand_aliases(line, sizeof(line));
|
expand_aliases(line, sizeof(line));
|
command = (char *)&line;
|
command = (char *)&line;
|
if ((*command == '#') || (*command == '=')) {
|
if ((*command == '#') || (*command == '=')) {
|
// Special cases
|
// Special cases
|
if (*command == '=') {
|
if (*command == '=') {
|
// Print line on console
|
// Print line on console
|
diag_printf("%s\n", &line[2]);
|
diag_printf("%s\n", &line[2]);
|
}
|
}
|
} else {
|
} else {
|
while (strlen(command) > 0) {
|
while (strlen(command) > 0) {
|
if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
|
if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
|
(cmd->fun)(argc, argv);
|
(cmd->fun)(argc, argv);
|
} else {
|
} else {
|
diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
|
diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
|
}
|
}
|
}
|
}
|
}
|
}
|
prompt = true;
|
prompt = true;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre)
|
show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre)
|
{
|
{
|
bool show;
|
bool show;
|
int len = 0;
|
int len = 0;
|
|
|
if (which) {
|
if (which) {
|
len = strlen(which);
|
len = strlen(which);
|
}
|
}
|
while (cmd != cmd_end) {
|
while (cmd != cmd_end) {
|
show = true;
|
show = true;
|
if (which && (strncasecmp(which, cmd->str, len) != 0)) {
|
if (which && (strncasecmp(which, cmd->str, len) != 0)) {
|
show = false;
|
show = false;
|
}
|
}
|
if (show) {
|
if (show) {
|
diag_printf("%s\n %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage);
|
diag_printf("%s\n %s %s %s\n", cmd->help, pre, cmd->str, cmd->usage);
|
if ((cmd->sub_cmds != (struct cmd *)0) && (which != (char *)0)) {
|
if ((cmd->sub_cmds != (struct cmd *)0) && (which != (char *)0)) {
|
show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);
|
show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);
|
}
|
}
|
}
|
}
|
cmd++;
|
cmd++;
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
do_help(int argc, char *argv[])
|
do_help(int argc, char *argv[])
|
{
|
{
|
struct cmd *cmd;
|
struct cmd *cmd;
|
char *which = (char *)0;
|
char *which = (char *)0;
|
|
|
if (!scan_opts(argc, argv, 1, 0, 0, (void **)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
|
if (!scan_opts(argc, argv, 1, 0, 0, (void **)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
|
diag_printf("Invalid argument\n");
|
diag_printf("Invalid argument\n");
|
return;
|
return;
|
}
|
}
|
cmd = __RedBoot_CMD_TAB__;
|
cmd = __RedBoot_CMD_TAB__;
|
show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
|
show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
|
return;
|
return;
|
}
|
}
|
|
|
static void * go_saved_context;
|
static void * go_saved_context;
|
static int go_return_status;
|
static int go_return_status;
|
|
|
static void
|
static void
|
go_trampoline(unsigned long entry)
|
go_trampoline(unsigned long entry)
|
{
|
{
|
typedef void code_fun(void);
|
typedef void code_fun(void);
|
code_fun *fun = (code_fun *)entry;
|
code_fun *fun = (code_fun *)entry;
|
unsigned long oldints;
|
unsigned long oldints;
|
|
|
HAL_DISABLE_INTERRUPTS(oldints);
|
HAL_DISABLE_INTERRUPTS(oldints);
|
|
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
|
HAL_ARCH_PROGRAM_NEW_STACK(fun);
|
HAL_ARCH_PROGRAM_NEW_STACK(fun);
|
#else
|
#else
|
(*fun)();
|
(*fun)();
|
#endif
|
#endif
|
}
|
}
|
|
|
static void
|
static void
|
return_to_redboot(int status)
|
return_to_redboot(int status)
|
{
|
{
|
CYGARC_HAL_SAVE_GP();
|
CYGARC_HAL_SAVE_GP();
|
|
|
go_return_status = status;
|
go_return_status = status;
|
HAL_THREAD_LOAD_CONTEXT(&go_saved_context);
|
HAL_THREAD_LOAD_CONTEXT(&go_saved_context);
|
// never returns
|
// never returns
|
|
|
// need this to balance above CYGARC_HAL_SAVE_GP on
|
// need this to balance above CYGARC_HAL_SAVE_GP on
|
// some platforms. It will never run, though.
|
// some platforms. It will never run, though.
|
CYGARC_HAL_RESTORE_GP();
|
CYGARC_HAL_RESTORE_GP();
|
}
|
}
|
|
|
void
|
void
|
do_go(int argc, char *argv[])
|
do_go(int argc, char *argv[])
|
{
|
{
|
unsigned long entry;
|
unsigned long entry;
|
unsigned long oldints;
|
unsigned long oldints;
|
bool wait_time_set;
|
bool wait_time_set;
|
int wait_time, res;
|
int wait_time, res;
|
bool cache_enabled = false;
|
bool cache_enabled = false;
|
struct option_info opts[2];
|
struct option_info opts[2];
|
char line[8];
|
char line[8];
|
hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
|
|
entry = entry_address; // Default from last 'load' operation
|
entry = entry_address; // Default from last 'load' operation
|
init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
|
init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
|
(void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
|
(void **)&wait_time, (bool *)&wait_time_set, "wait timeout");
|
init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
|
init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
|
(void **)&cache_enabled, (bool *)0, "go with caches enabled");
|
(void **)&cache_enabled, (bool *)0, "go with caches enabled");
|
if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
|
if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
|
{
|
{
|
return;
|
return;
|
}
|
}
|
if (wait_time_set) {
|
if (wait_time_set) {
|
int script_timeout_ms = wait_time * 1000;
|
int script_timeout_ms = wait_time * 1000;
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
unsigned char *hold_script = script;
|
unsigned char *hold_script = script;
|
script = (unsigned char *)0;
|
script = (unsigned char *)0;
|
#endif
|
#endif
|
diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
|
diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
|
(void *)entry, wait_time);
|
(void *)entry, wait_time);
|
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
|
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
|
if (res == _GETS_CTRLC) {
|
if (res == _GETS_CTRLC) {
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
script = hold_script; // Re-enable script
|
script = hold_script; // Re-enable script
|
#endif
|
#endif
|
return;
|
return;
|
}
|
}
|
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
|
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
|
}
|
}
|
}
|
}
|
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
|
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
|
|
|
HAL_DISABLE_INTERRUPTS(oldints);
|
HAL_DISABLE_INTERRUPTS(oldints);
|
HAL_DCACHE_SYNC();
|
HAL_DCACHE_SYNC();
|
if (!cache_enabled) {
|
if (!cache_enabled) {
|
HAL_ICACHE_DISABLE();
|
HAL_ICACHE_DISABLE();
|
HAL_DCACHE_DISABLE();
|
HAL_DCACHE_DISABLE();
|
HAL_DCACHE_SYNC();
|
HAL_DCACHE_SYNC();
|
}
|
}
|
HAL_ICACHE_INVALIDATE_ALL();
|
HAL_ICACHE_INVALIDATE_ALL();
|
HAL_DCACHE_INVALIDATE_ALL();
|
HAL_DCACHE_INVALIDATE_ALL();
|
|
|
// set up a temporary context that will take us to the trampoline
|
// set up a temporary context that will take us to the trampoline
|
HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
|
HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, go_trampoline, 0);
|
|
|
// switch context to trampoline
|
// switch context to trampoline
|
HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
|
HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
|
|
|
// we get back here by way of return_to_redboot()
|
// we get back here by way of return_to_redboot()
|
|
|
// undo the changes we made before switching context
|
// undo the changes we made before switching context
|
if (!cache_enabled) {
|
if (!cache_enabled) {
|
HAL_ICACHE_ENABLE();
|
HAL_ICACHE_ENABLE();
|
HAL_DCACHE_ENABLE();
|
HAL_DCACHE_ENABLE();
|
}
|
}
|
|
|
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
|
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
|
|
|
HAL_RESTORE_INTERRUPTS(oldints);
|
HAL_RESTORE_INTERRUPTS(oldints);
|
|
|
diag_printf("\nProgram completed with status %d\n", go_return_status);
|
diag_printf("\nProgram completed with status %d\n", go_return_status);
|
}
|
}
|
|
|
#ifdef HAL_PLATFORM_RESET
|
#ifdef HAL_PLATFORM_RESET
|
void
|
void
|
do_reset(int argc, char *argv[])
|
do_reset(int argc, char *argv[])
|
{
|
{
|
diag_printf("... Resetting.");
|
diag_printf("... Resetting.");
|
CYGACC_CALL_IF_DELAY_US(2*100000);
|
CYGACC_CALL_IF_DELAY_US(2*100000);
|
diag_printf("\n");
|
diag_printf("\n");
|
CYGACC_CALL_IF_RESET();
|
CYGACC_CALL_IF_RESET();
|
diag_printf("!! oops, RESET not working on this platform\n");
|
diag_printf("!! oops, RESET not working on this platform\n");
|
}
|
}
|
#endif
|
#endif
|
|
|
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
|
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#include <flash_config.h>
|
#include <flash_config.h>
|
#endif
|
#endif
|
|
|
static int
|
static int
|
set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate)
|
set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate)
|
{
|
{
|
int current_rate;
|
int current_rate;
|
|
|
current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
|
current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
|
if (rate != current_rate)
|
if (rate != current_rate)
|
return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
|
return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
|
|
|
return 0;
|
return 0;
|
}
|
}
|
|
|
int
|
int
|
set_console_baud_rate(int rate)
|
set_console_baud_rate(int rate)
|
{
|
{
|
int ret;
|
int ret;
|
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
|
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
|
if (!console_selected) {
|
if (!console_selected) {
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
|
int i;
|
int i;
|
// Set baud for all channels
|
// Set baud for all channels
|
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) {
|
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) {
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
|
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
|
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
|
if (ret < 0)
|
if (ret < 0)
|
break;
|
break;
|
}
|
}
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
|
} else
|
} else
|
#endif
|
#endif
|
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
|
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
|
|
|
if (ret < 0)
|
if (ret < 0)
|
diag_printf("Setting console baud rate to %d failed\n", rate);
|
diag_printf("Setting console baud rate to %d failed\n", rate);
|
|
|
return ret;
|
return ret;
|
}
|
}
|
|
|
static void
|
static void
|
_sleep(int ms)
|
_sleep(int ms)
|
{
|
{
|
int i;
|
int i;
|
for (i = 0; i < ms; i++) {
|
for (i = 0; i < ms; i++) {
|
CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);
|
CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);
|
}
|
}
|
}
|
}
|
|
|
void
|
void
|
do_baud_rate(int argc, char *argv[])
|
do_baud_rate(int argc, char *argv[])
|
{
|
{
|
int new_rate, ret, old_rate;
|
int new_rate, ret, old_rate;
|
bool new_rate_set;
|
bool new_rate_set;
|
hal_virtual_comm_table_t *__chan;
|
hal_virtual_comm_table_t *__chan;
|
struct option_info opts[1];
|
struct option_info opts[1];
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
struct config_option opt;
|
struct config_option opt;
|
#endif
|
#endif
|
|
|
init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
|
init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
|
(void **)&new_rate, (bool *)&new_rate_set, "new baud rate");
|
(void **)&new_rate, (bool *)&new_rate_set, "new baud rate");
|
if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
|
if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
|
return;
|
return;
|
}
|
}
|
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
|
if (new_rate_set) {
|
if (new_rate_set) {
|
diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);
|
diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);
|
_sleep(500); // Give serial time to flush
|
_sleep(500); // Give serial time to flush
|
old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
|
old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
|
ret = set_console_baud_rate(new_rate);
|
ret = set_console_baud_rate(new_rate);
|
if (ret < 0) {
|
if (ret < 0) {
|
if (old_rate > 0) {
|
if (old_rate > 0) {
|
// Try to restore
|
// Try to restore
|
set_console_baud_rate(old_rate);
|
set_console_baud_rate(old_rate);
|
_sleep(500); // Give serial time to flush
|
_sleep(500); // Give serial time to flush
|
diag_printf("\nret = %d\n", ret);
|
diag_printf("\nret = %d\n", ret);
|
}
|
}
|
return; // Couldn't set the desired rate
|
return; // Couldn't set the desired rate
|
}
|
}
|
old_rate = ret;
|
old_rate = ret;
|
// Make sure this new rate works or back off to previous value
|
// Make sure this new rate works or back off to previous value
|
// Sleep for a few seconds, then prompt to see if it works
|
// Sleep for a few seconds, then prompt to see if it works
|
_sleep(3000); // Give serial time to flush
|
_sleep(3000); // Give serial time to flush
|
if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {
|
if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {
|
_sleep(500); // Give serial time to flush
|
_sleep(500); // Give serial time to flush
|
set_console_baud_rate(old_rate);
|
set_console_baud_rate(old_rate);
|
_sleep(500); // Give serial time to flush
|
_sleep(500); // Give serial time to flush
|
return;
|
return;
|
}
|
}
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
|
opt.type = CONFIG_INT;
|
opt.type = CONFIG_INT;
|
opt.enable = (char *)0;
|
opt.enable = (char *)0;
|
opt.enable_sense = 1;
|
opt.enable_sense = 1;
|
opt.key = "console_baud_rate";
|
opt.key = "console_baud_rate";
|
opt.dflt = new_rate;
|
opt.dflt = new_rate;
|
flash_add_config(&opt, true);
|
flash_add_config(&opt, true);
|
#endif
|
#endif
|
} else {
|
} else {
|
ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
|
ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
|
diag_printf("Baud rate = ");
|
diag_printf("Baud rate = ");
|
if (ret <= 0) {
|
if (ret <= 0) {
|
diag_printf("unknown\n");
|
diag_printf("unknown\n");
|
} else {
|
} else {
|
diag_printf("%d\n", ret);
|
diag_printf("%d\n", ret);
|
}
|
}
|
}
|
}
|
}
|
}
|
#endif
|
#endif
|
|
|
//
|
//
|
// [Null] Builtin [Power On] Self Test
|
// [Null] Builtin [Power On] Self Test
|
//
|
//
|
void bist(void) CYGBLD_ATTRIB_WEAK;
|
void bist(void) CYGBLD_ATTRIB_WEAK;
|
|
|
void
|
void
|
bist(void)
|
bist(void)
|
{
|
{
|
}
|
}
|
|
|