📄 main.c
字号:
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
if (res == _GETS_GDB) {
int dbgchan;
hal_virtual_comm_table_t *__chan;
int i;
// Special case of '$' - need to start GDB protocol
gdb_active = true;
// Mask interrupts on all channels
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
}
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
// set up a temporary context that will take us to the trampoline
HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end,
breakpoint, trampoline, 0);
// switch context to trampoline (get GDB stubs started)
HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
gdb_active = false;
dbgchan = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
CYGACC_CALL_IF_SET_CONSOLE_COMM(dbgchan);
} else
#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
{
expand_aliases(line, sizeof(line));
command = (char *)&line;
if ((*command == '#') || (*command == '=')) {
// Special cases
if (*command == '=') {
// Print line on console
diag_printf("%s\n", &line[2]);
}
} else {
while (strlen(command) > 0) {
if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
// Try to handle aborts - messy because of the stack unwinding...
__mem_fault_handler = error_handler;
if (hal_setjmp(error_jmpbuf)) {
diag_printf("** command abort - illegal memory access?\n");
} else {
(cmd->fun)(argc, argv);
}
__mem_fault_handler = 0;
} else {
diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
}
}
}
prompt = true;
}
}
}
}
void
show_help(struct cmd *cmd, struct cmd *cmd_end, char *which, char *pre)
{
bool show;
int len = 0;
if (which) {
len = strlen(which);
}
while (cmd != cmd_end) {
show = true;
if (which && (strncasecmp(which, cmd->str, len) != 0)) {
show = false;
}
if (show) {
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)) {
show_help(cmd->sub_cmds, cmd->sub_cmds_end, 0, cmd->str);
}
}
cmd++;
}
}
void
do_help(int argc, char *argv[])
{
struct cmd *cmd;
char *which = (char *)0;
if (!scan_opts(argc, argv, 1, 0, 0, (void *)&which, OPTION_ARG_TYPE_STR, "<topic>")) {
diag_printf("Invalid argument\n");
return;
}
cmd = __RedBoot_CMD_TAB__;
show_help(cmd, &__RedBoot_CMD_TAB_END__, which, "");
return;
}
static void
trampoline(unsigned long entry)
{
typedef void code_fun(void);
code_fun *fun = (code_fun *)entry;
unsigned long oldints;
HAL_DISABLE_INTERRUPTS(oldints);
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
HAL_ARCH_PROGRAM_NEW_STACK(fun);
#else
(*fun)();
#endif
HAL_THREAD_LOAD_CONTEXT(&saved_context);
}
static void
return_to_redboot(int status)
{
CYGARC_HAL_SAVE_GP();
return_status = status;
HAL_THREAD_LOAD_CONTEXT(&saved_context);
// never returns
// need this to balance above CYGARC_HAL_SAVE_GP on
// some platforms. It will never run, though.
CYGARC_HAL_RESTORE_GP();
}
void
do_go(int argc, char *argv[])
{
int i, cur, num_options;
unsigned long entry;
unsigned long oldints;
bool wait_time_set;
int wait_time, res;
bool cache_enabled = false;
#ifdef CYGPKG_IO_ETH_DRIVERS
bool stop_net = false;
#endif
struct option_info opts[3];
char line[8];
hal_virtual_comm_table_t *__chan;
__mem_fault_handler = 0; // Let GDB handle any faults directly
entry = entry_address; // Default from last 'load' operation
init_opts(&opts[0], 'w', true, OPTION_ARG_TYPE_NUM,
(void *)&wait_time, (bool *)&wait_time_set, "wait timeout");
init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG,
(void *)&cache_enabled, (bool *)0, "go with caches enabled");
num_options = 2;
#ifdef CYGPKG_IO_ETH_DRIVERS
init_opts(&opts[2], 'n', false, OPTION_ARG_TYPE_FLG,
(void *)&stop_net, (bool *)0, "go with network driver stopped");
num_options++;
#endif
CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options");
if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
{
return;
}
if (entry == (unsigned long)NO_MEMORY) {
diag_printf("No entry point known - aborted\n");
return;
}
if (wait_time_set) {
int script_timeout_ms = wait_time * 1000;
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
unsigned char *hold_script = script;
script = (unsigned char *)0;
#endif
diag_printf("About to start execution at %p - abort with ^C within %d seconds\n",
(void *)entry, wait_time);
while (script_timeout_ms >= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT) {
res = _rb_gets(line, sizeof(line), CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT);
if (res == _GETS_CTRLC) {
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
script = hold_script; // Re-enable script
#endif
return;
}
script_timeout_ms -= CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT;
}
}
// Mask interrupts on all channels
cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS; i++) {
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
CYGACC_COMM_IF_CONTROL( *__chan, __COMMCTL_IRQ_DISABLE );
}
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
#ifdef CYGPKG_IO_ETH_DRIVERS
if (stop_net)
eth_drv_stop();
#endif
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
if (!cache_enabled) {
HAL_ICACHE_DISABLE();
HAL_DCACHE_DISABLE();
HAL_DCACHE_SYNC();
}
HAL_ICACHE_INVALIDATE_ALL();
HAL_DCACHE_INVALIDATE_ALL();
// set up a temporary context that will take us to the trampoline
HAL_THREAD_INIT_CONTEXT((CYG_ADDRESS)workspace_end, entry, trampoline, 0);
// switch context to trampoline
HAL_THREAD_SWITCH_CONTEXT(&saved_context, &workspace_end);
// we get back here by way of return_to_redboot()
// undo the changes we made before switching context
if (!cache_enabled) {
HAL_ICACHE_ENABLE();
HAL_DCACHE_ENABLE();
}
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_DISABLE_LINE_FLUSH);
HAL_RESTORE_INTERRUPTS(oldints);
diag_printf("\nProgram completed with status %d\n", return_status);
}
#ifdef HAL_PLATFORM_RESET
void
do_reset(int argc, char *argv[])
{
diag_printf("... Resetting.");
CYGACC_CALL_IF_DELAY_US(2*100000);
diag_printf("\n");
CYGACC_CALL_IF_RESET();
diag_printf("!! oops, RESET not working on this platform\n");
}
#endif
#ifdef CYGSEM_REDBOOT_VARIABLE_BAUD_RATE
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <flash_config.h>
#endif
static int
set_comm_baud_rate(hal_virtual_comm_table_t *chan, int rate)
{
int current_rate;
current_rate = CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_GETBAUD);
if (rate != current_rate)
return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
return 0;
}
int
set_console_baud_rate(int rate)
{
int ret = -1;
#ifdef CYGPKG_REDBOOT_ANY_CONSOLE
if (!console_selected) {
int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
int i;
// Set baud for all channels
for (i = 0; i < CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS; i++) {
CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
if (ret < 0)
break;
}
CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
} else
#endif
ret = set_comm_baud_rate(CYGACC_CALL_IF_CONSOLE_PROCS(), rate);
if (ret < 0)
diag_printf("Setting console baud rate to %d failed\n", rate);
return ret;
}
static void
_sleep(int ms)
{
int i;
for (i = 0; i < ms; i++) {
CYGACC_CALL_IF_DELAY_US((cyg_int32)1000);
}
}
void
do_baud_rate(int argc, char *argv[])
{
int new_rate, ret, old_rate;
bool new_rate_set;
hal_virtual_comm_table_t *__chan;
struct option_info opts[1];
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
struct config_option opt;
#endif
init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
(void *)&new_rate, (bool *)&new_rate_set, "new baud rate");
if (!scan_opts(argc, argv, 1, opts, 1, 0, 0, "")) {
return;
}
__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
if (new_rate_set) {
diag_printf("Baud rate will be changed to %d - update your settings\n", new_rate);
_sleep(500); // Give serial time to flush
old_rate = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
ret = set_console_baud_rate(new_rate);
if (ret < 0) {
if (old_rate > 0) {
// Try to restore
set_console_baud_rate(old_rate);
_sleep(500); // Give serial time to flush
diag_printf("\nret = %d\n", ret);
}
return; // Couldn't set the desired rate
}
// 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(3000); // Give serial time to flush
if (!verify_action_with_timeout(5000, "Baud rate changed to %d", new_rate)) {
_sleep(500); // Give serial time to flush
set_console_baud_rate(old_rate);
_sleep(500); // Give serial time to flush
return;
}
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
opt.type = CONFIG_INT;
opt.enable = (char *)0;
opt.enable_sense = 1;
opt.key = "console_baud_rate";
opt.dflt = new_rate;
flash_add_config(&opt, true);
#endif
} else {
ret = CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_GETBAUD);
diag_printf("Baud rate = ");
if (ret <= 0) {
diag_printf("unknown\n");
} else {
diag_printf("%d\n", ret);
}
}
}
#endif
//
// Validate an address to see if it is within any known RAM area
//
bool
valid_address(unsigned char *addr)
{
int seg;
for (seg = 0; seg < CYGBLD_REDBOOT_MAX_MEM_SEGMENTS; seg++) {
if (mem_segments[seg].start != NO_MEMORY) {
if ((addr >= mem_segments[seg].start) && (addr < mem_segments[seg].end)) {
return true;
}
}
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -