* [ECOS] RE: twothread example in redboot.
@ 2004-04-30 14:20 Vedaraman Sethuraman (IE10)
0 siblings, 0 replies; only message in thread
From: Vedaraman Sethuraman (IE10) @ 2004-04-30 14:20 UTC (permalink / raw)
To: Sai Naidu, ecos-discuss
[-- Attachment #1: Type: text/plain, Size: 5163 bytes --]
Hi,
Pls see the attached code to run threads from Redboot.
During the redboot start, you should use cyg_user_start() instead of
cyg_start().
you can see the thread_a() main entry.
Also i have moved the Redboot user input loop to threads. Then only i was
able to schedule. Otherwise i you cann't schedule.
One problem what i am facing after this modification is "Some of the input
characters are missed while scanning input from keyboard" as the scanning
cycle is slow. I don't know why it behaves like this.
Regards,
Vedaraman.
-----Original Message-----
From: Sai Naidu [mailto:naiduk@intotoinc.com]
Sent: Thursday, April 29, 2004 8:34 PM
To: ecos-discuss@sources.redhat.com
Subject: twothread example in redboot.
hi!
I have some queries regarding the thread scheduling in redboot.
I require to build a redboot bootloader with a server (http and tftp)
running in the background.
I was not aware how the threads are scheduled so I have made use of the
"twothreads.c" example program which was there in "ecos/examples"
directory of the code checked out from the CVS.
Iam building the image for IXP425 (ecosconfig new grg redboot). I have
included the following packages for the target.
target grg {
alias { "Generic Residential Gateway" grg }
packages { CYGPKG_HAL_ARM
CYGPKG_HAL_ARM_XSCALE_CORE
CYGPKG_HAL_ARM_XSCALE_IXP425
CYGPKG_HAL_ARM_XSCALE_GRG
CYGPKG_IO_PCI
CYGPKG_DEVS_ETH_INTEL_I82559
CYGPKG_DEVS_ETH_ARM_GRG_I82559
CYGPKG_DEVS_FLASH_STRATA
CYGPKG_DEVS_FLASH_GRG
CYGPKG_ERROR
CYGPKG_IO
CYGPKG_MEMALLOC
CYGPKG_KERNEL
CYGPKG_LIBC_STDLIB
CYGPKG_LIBC_STDIO
CYGPKG_LIBC_I18N
CYGPKG_LIBC_TIME
}
In order to run my two threads program, i have included a command in
the "packages/redboot/current/src/main.c". The idea is, when i run this
command from the redboot prompt, the twothread.c program get run.
The code added to the "packages/redboot/current/src/main.c" file is as
follows.
RedBoot_cmd("runThreads",
"Execute tftp server",
"",
do_threadsExpl
);
void do_threadsExpl(int argc, char *argv[])
{
cyg_user_start();
}
the cyg_user_start() is the one which is defined in the "twothreads.c"
file. I am pasting the file below
/******************************************/
#include <cyg/kernel/kapi.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/* now declare (and allocate space for) some kernel objects,
like the two threads we will use */
cyg_thread thread_s[2]; /* space for two thread objects */
char stack[2][4096]; /* space for two 4K stacks */
/* now the handles for the threads */
cyg_handle_t simple_threadA, simple_threadB;
/* and now variables for the procedure which is the thread */
cyg_thread_entry_t simple_program;
/* and now a mutex to protect calls to the C library */
cyg_mutex_t cliblock;
/* we install our own startup routine which sets up threads */
void cyg_user_start(void)
{
diag_printf("Entering twothreads' cyg_user_start() function\n");
cyg_mutex_init(&cliblock);
cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
"Thread A", (void *) stack[0], 4096,
&simple_threadA, &thread_s[0]);
cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
"Thread B", (void *) stack[1], 4096,
&simple_threadB, &thread_s[1]);
cyg_thread_resume(simple_threadA);
cyg_thread_resume(simple_threadB);
}
/* this is a simple program which runs in a thread */
void simple_program(cyg_addrword_t data)
{
int message = (int) data;
int delay;
diag_printf("Beginning execution; thread data is %d\n", message);
cyg_thread_delay(200);
for (;;) {
delay = 200 + (rand() % 50);
/* note: printf() must be protected by a
call to cyg_mutex_lock() */
cyg_mutex_lock(&cliblock); {
diag_printf("Thread %d: and now a delay of %d clock ticks\n",
message, delay);
}
cyg_mutex_unlock(&cliblock);
cyg_thread_delay(delay);
}
}
/******************************************************/
I then built and complied the image and burnt it on to the flash.
Now when i run the command runThreads from the redboot prompt , i am
not getting the required output. The threads just do not run.
/*********OUTPUT************************/
RedBoot> runThreads
Entering twothreads' cyg_user_start() function
RedBoot>
Basically i do not have any threads running. i have even tried printing
the state of these threads . It shows the states value as 0. Am I
missing out on some package? Is it possible to spawn more threads from
the redboot prompt if NO how do we have more than one thread running? I
require the redboot prompt and a server running on another thread in the
background. Could any one suggest me the right approach?
thanks and regards
sai naidu
[-- Attachment #2: main.c --]
[-- Type: application/octet-stream, Size: 23788 bytes --]
//==========================================================================
//
// 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 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
#include <cyg/hal/hal_tables.h>
#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
#include <cyg/kernel/kapi.h> // Kernel API.
// GDB interfaces
extern void breakpoint(void);
#endif
// Builtin Self Test (BIST)
externC void bist(void);
// Return path for code run from a go command
static void return_to_redboot(int status);
#define THREAD_STACK_SIZE ( 8192 / sizeof(int) )
#define THREAD_PRIORITY 1
int thread_a_stack[ THREAD_STACK_SIZE ];
cyg_thread thread_a_obj;
cyg_handle_t thread_a_hdl;
// 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
);
RedBoot_cmd("go",
"Execute code at a location",
"[-w <timeout>] [entry]",
do_go
);
RedBoot_cmd("start",
"start application from flash",
"[-w <timeout>] [entry]",
do_start
);
#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
void
do_version(int argc, char *argv[])
{
#ifdef CYGPKG_IO_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, %p-%p available\n",
(void*)ram_start, (void*)ram_end,
(void*)user_ram_start, (void *)user_ram_end);
#ifdef CYGPKG_IO_FLASH
_flash_info();
#endif
}
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);
}
void thread_a( cyg_addrword_t data )
{
int res = 0, count = 0;
bool prompt = true;
static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
char *command;
struct cmd *cmd;
int cur, one_time = 0;
struct init_tab_entry *init_entry;
extern char RedBoot_version[];
cyg_uint32 load_buf[512/sizeof(cyg_uint32)];
diag_printf("thread a entering");
while (true)
{
if (prompt) {
diag_printf("BNABootloader_100>");
#ifdef SIMUL_REGRESS
read_sec(0x1002, (cyg_uint32*)load_buf, 1);
diag_printf(" %x \n",load_buf[0]);
#endif
prompt = false;
}
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
cmd_history = true; // Enable history collection
#endif
res = _rb_gets(line, sizeof(line), 100/*CYGNUM_REDBOOT_CLI_IDLE_TIMEOUT*/);
#if CYGNUM_REDBOOT_CMD_LINE_EDITING != 0
cmd_history = false; // Enable history collection
#endif
#if 0
if (res == _GETS_TIMEOUT) {
if(!one_time)
{
res = _GETS_OK;
one_time = 1;
}
}
#endif
if (res == _GETS_TIMEOUT) {
#ifdef SIMUL_REGRESS
CYGACC_CALL_IF_DELAY_US(2*1000000);
load_buf[0]++;
write_sec(0x1002, (cyg_uint32*)load_buf, 1);
do_auto_load(0,NULL);
CYGACC_CALL_IF_DELAY_US(10*1000000);
do_reset(0, NULL);
#endif
// No input arrived
} else {
#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);
#ifdef HAL_ARCH_PROGRAM_NEW_STACK
HAL_ARCH_PROGRAM_NEW_STACK(breakpoint);
#else
breakpoint(); // Get GDB stubs started, with a proper environment, etc.
#endif
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 {
if(strlen(command) <= 0)
{
diag_printf("User Commanded\n");
//do_start(0, NULL);
}
while (strlen(command) > 0) {
if ((cmd = parse(&command, &argc, &argv[0])) != (struct cmd *)0) {
(cmd->fun)(argc, argv);
} else {
diag_printf("** Error: Illegal command: \"%s\"\n", argv[0]);
// do_start(0, NULL);
}
}
}
prompt = true;
}
}
}
}
//
// This is the main entry point for RedBoot
//
void
cyg_user_start(void)
{
int res = 0, count = 0;
bool prompt = true;
static char line[CYGPKG_REDBOOT_MAX_CMD_LINE];
char *command;
struct cmd *cmd;
int cur, one_time = 0;
struct init_tab_entry *init_entry;
extern char RedBoot_version[];
cyg_uint32 load_buf[512/sizeof(cyg_uint32)];
memset(load_buf, 0 ,sizeof(load_buf));
diag_init_putc(_mon_write_char);
hal_if_diag_init();
diag_printf("Cyg user start created");
cyg_thread_create(
THREAD_PRIORITY,
thread_a,
(cyg_addrword_t) 75,
"Thread A",
(void *)thread_a_stack,
THREAD_STACK_SIZE,
&thread_a_hdl,
&thread_a_obj );
diag_printf("thread created");
cyg_thread_resume( thread_a_hdl );
diag_printf("thread resumed dummy");
// Export version information
CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);
CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);
#if 0
// Make sure the channels are properly initialized.
diag_init_putc(_mon_write_char);
hal_if_diag_init();
#endif
// 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;
}
bist();
#ifdef CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER
fis_zlib_common_buffer =
workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE;
#endif
for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__; init_entry++) {
(*init_entry->fun)();
}
user_ram_start = workspace_start;
user_ram_end = workspace_end;
do_version(0,0);
#ifdef CYGFUN_REDBOOT_BOOT_SCRIPT
# ifdef CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT
if (!script) {
script = CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT;
# ifndef CYGSEM_REDBOOT_FLASH_CONFIG
script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT;
# endif
}
# 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
diag_printf("CYG start terminating");
}
#if 0
void
cyg_user_start(void)
{
// Make sure the channels are properly initialized.
diag_init_putc(_mon_write_char);
hal_if_diag_init();
diag_printf("Cyg user start created");
cyg_thread_create(
THREAD_PRIORITY,
thread_a,
(cyg_addrword_t) 75,
"Thread A",
(void *)thread_a_stack,
THREAD_STACK_SIZE,
&thread_a_hdl,
&thread_a_obj );
diag_printf("thread created");
cyg_thread_resume( thread_a_hdl );
diag_printf("thread resumed dummy");
}
#endif
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 * go_saved_context;
static int go_return_status;
static void
go_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
}
static void
return_to_redboot(int status)
{
CYGARC_HAL_SAVE_GP();
go_return_status = status;
HAL_THREAD_LOAD_CONTEXT(&go_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[])
{
unsigned long entry;
unsigned long oldints;
bool wait_time_set;
int wait_time, res;
bool cache_enabled = false;
struct option_info opts[2];
char line[8];
hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
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");
if (!scan_opts(argc, argv, 1, opts, 2, (void *)&entry, OPTION_ARG_TYPE_NUM, "starting address"))
{
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;
}
}
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
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, go_trampoline, 0);
// switch context to trampoline
HAL_THREAD_SWITCH_CONTEXT(&go_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", go_return_status);
}
void
do_start(int argc, char *argv[])
{
unsigned long entry;
unsigned long oldints;
bool wait_time_set;
int wait_time, res;
bool cache_enabled = false;
struct option_info opts[2];
char line[8];
hal_virtual_comm_table_t *__chan = CYGACC_CALL_IF_CONSOLE_PROCS();
entry_address = 0x108000;
diag_printf("Entry address: %x\n",entry_address);
read_sec(0x200, (cyg_uint32*)entry_address, 255);
entry = entry_address; // Default from last 'load' operation
CYGACC_COMM_IF_CONTROL(*__chan, __COMMCTL_ENABLE_LINE_FLUSH);
HAL_DISABLE_INTERRUPTS(oldints);
HAL_DCACHE_SYNC();
if (!cache_enabled) {
diag_printf("cache");
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, go_trampoline, 0);
diag_printf("After init : WS: %x EN: %x go_tr: %x go_save: %x \n", workspace_end, entry, go_trampoline, go_saved_context);
diag_printf("After next : go_save: %x WS: %x \n", &workspace_end , &go_saved_context);
// switch context to trampoline
HAL_THREAD_SWITCH_CONTEXT(&go_saved_context, &workspace_end);
diag_printf("After switch context");
// 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", go_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_SETBAUD, rate);
if (rate != current_rate)
return CYGACC_COMM_IF_CONTROL(*chan, __COMMCTL_SETBAUD, rate);
return 0;
}
int
set_console_baud_rate(int rate)
{
int ret;
#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
}
old_rate = ret;
// 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
//
// [Null] Builtin [Power On] Self Test
//
void bist(void) CYGBLD_ATTRIB_WEAK;
void
bist(void)
{
}
[-- Attachment #3: Type: text/plain, Size: 148 bytes --]
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-04-30 13:59 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-30 14:20 [ECOS] RE: twothread example in redboot Vedaraman Sethuraman (IE10)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).