?? monitor.c
字號:
/* =================================================================
*
* monitor.c
*
* An HTTP system monitor
*
* =================================================================
* ####ECOSGPLCOPYRIGHTBEGIN####
* -------------------------------------------
* This file is part of eCos, the Embedded Configurable Operating
* System.
* Copyright (C) 2002 Nick Garnett.
*
* 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.
*
* -------------------------------------------
* ####ECOSGPLCOPYRIGHTEND####
* =================================================================
* #####DESCRIPTIONBEGIN####
*
* Author(s): nickg@calivar.com
* Contributors: nickg@calivar.com
* Date: 2002-10-14
* Purpose:
* Description:
*
* ####DESCRIPTIONEND####
*
* =================================================================
*/
#include <pkgconf/system.h>
#include <pkgconf/isoinfra.h>
#include <pkgconf/net.h>
#include <pkgconf/httpd.h>
#include <pkgconf/kernel.h>
#include <cyg/infra/cyg_trac.h> /* tracing macros */
#include <cyg/infra/cyg_ass.h> /* assertion macros */
#include <cyg/httpd/httpd.h>
#include <cyg/kernel/kapi.h>
#ifdef CYGPKG_KERNEL_INSTRUMENT
#include <cyg/kernel/instrmnt.h>
#include <cyg/kernel/instrument_desc.h>
#endif
#include <unistd.h>
#include <ctype.h>
/* ================================================================= */
/* Include all the necessary network headers by hand. We need to do
* this so that _KERNEL is correctly defined, or not, for specific
* headers so we can use both the external API and get at internal
* kernel structures.
*/
#define _KERNEL
#include <sys/param.h>
#undef _KERNEL
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/time.h>
#define _KERNEL
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <sys/protosw.h>
#include <netinet/in_pcb.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/tcp_timer.h>
#include <netinet/ip_var.h>
#include <netinet/icmp_var.h>
#include <netinet/udp_var.h>
#include <netinet/tcp_var.h>
#include <cyg/io/eth/eth_drv_stats.h>
/* ================================================================= */
/* Use this when a thread appears to have no name.
*/
#define NULL_THREAD_NAME "----------"
/* ================================================================= */
/* Draw navigation bar
*
* This draws a simple table containing links to the various monitor
* pages at the current position in the HTML stream.
*/
static void draw_navbar( FILE *client )
{
html_para_begin( client, "" );
html_table_begin( client, "border cellpadding=\"4\"" );
{
html_table_row_begin(client, "" );
{
html_table_data_begin( client, "" );
html_image( client, "/monitor/ecos.gif", "eCos logo", "" );
html_table_data_begin( client, "" );
html_url( client, "Threads", "/monitor/threads.html");
html_table_data_begin( client, "" );
html_url( client, "Interrupts", "/monitor/interrupts.html");
html_table_data_begin( client, "" );
html_url( client, "Memory", "/monitor/memory.html");
html_table_data_begin( client, "" );
html_url( client, "Network", "/monitor/network.html");
#ifdef CYGPKG_KERNEL_INSTRUMENT
html_table_data_begin( client, "" );
html_url( client, "Instrumentation", "/monitor/instrument.html");
#endif
}
html_table_row_end( client );
}
html_table_end( client );
}
/* ================================================================= */
/* Index page
*
* A simple introductory page matching "/monitor" and
* "/monitor/index.html".
*/
static char monitor_index_blurb[] =
"<p>This is the eCos System Monitor. It presents a simple web monitor
and control interface for eCos systems.\n"
"<p>Use the navigation bar at the bottom of each page to explore."
;
static cyg_bool cyg_monitor_index( FILE * client, char *filename,
char *formdata, void *arg )
{
html_begin(client);
html_head(client,"eCos System Monitor", "");
html_body_begin(client,"");
{
html_heading(client, 2, "eCos System Monitor" );
fputs( monitor_index_blurb, client );
draw_navbar(client);
}
html_body_end(client);
html_end(client);
return 1;
}
CYG_HTTPD_TABLE_ENTRY( cyg_monitor_entry,
"/monitor",
cyg_monitor_index,
NULL );
CYG_HTTPD_TABLE_ENTRY( cyg_monitor_index_entry,
"/monitor/index.html",
cyg_monitor_index,
NULL );
/* ================================================================= */
/* Thread Monitor
*
* Uses the kapi thread info API to enumerate all the current threads
* and generate a table showing their state.
*/
static cyg_bool cyg_monitor_threads( FILE * client, char *filename,
char *formdata, void *arg )
{
html_begin(client);
/* html_head(client,"Thread Monitor", "<meta http-equiv=\"refresh\" content=\"10\">"); */
html_head(client,"eCos Thread Monitor", "");
html_body_begin(client,"");
{
html_heading(client, 2, "Thread Monitor" );
html_table_begin( client, "border" );
{
cyg_handle_t thread = 0;
cyg_uint16 id = 0;
html_table_header( client, "Id", "" );
html_table_header( client, "State", "" );
html_table_header( client, "Set<br>Priority", "" );
html_table_header( client, "Current<br>Priority", "" );
html_table_header( client, "Name", "" );
html_table_header( client, "Stack Base", "" );
html_table_header( client, "Stack Size", "" );
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
html_table_header( client, "Stack Used", "" );
#endif
/* Loop over the threads, and generate a table row for
* each.
*/
while( cyg_thread_get_next( &thread, &id ) )
{
cyg_thread_info info;
char *state_string;
cyg_thread_get_info( thread, id, &info );
if( info.name == NULL )
info.name = NULL_THREAD_NAME;
/* Translate the state into a string.
*/
if( info.state == 0 )
state_string = "RUN";
else if( info.state & 0x04 )
state_string = "SUSP";
else switch( info.state & 0x1b )
{
case 0x01: state_string = "SLEEP"; break;
case 0x02: state_string = "CNTSLEEP"; break;
case 0x08: state_string = "CREATE"; break;
case 0x10: state_string = "EXIT"; break;
default: state_string = "????"; break;
}
/* Now generate the row.
*/
html_table_row_begin(client, "" );
{
html_table_data_begin( client, "" );
fprintf( client, "<a href=\"/monitor/thread-%04x.html\">%04x</a>\n", id,id);
html_table_data_begin( client, "" );
fprintf( client, "%s", state_string);
html_table_data_begin( client, "" );
fprintf( client, "%d", info.set_pri);
html_table_data_begin( client, "" );
fprintf( client, "%d", info.cur_pri);
html_table_data_begin( client, "" );
fputs( info.name, client );
html_table_data_begin( client, "" );
fprintf( client, "%08x", info.stack_base );
html_table_data_begin( client, "" );
fprintf( client, "%d", info.stack_size );
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
html_table_data_begin( client, "" );
fprintf( client, "%d", info.stack_used );
#endif
}
html_table_row_end(client);
}
}
html_table_end( client );
draw_navbar(client);
}
html_body_end(client);
html_end(client);
return 1;
}
CYG_HTTPD_TABLE_ENTRY( cyg_monitor_show_threads,
"/monitor/threads.htm*",
cyg_monitor_threads,
NULL );
/* ================================================================= */
/* Thread edit page
*
* A page on which the thread's state may be edited. This tests forms
* handling.
*/
static char thread_edit_blurb[] =
"<p>This table contains an entry for each property of the thread
that you can edit. The properties are:\n"
"<p><b>State:</b> Change thread's state. The <em>Suspend</em> button
will suspend the thread. The <em>Run</em> button will undo any previous
suspends. The <em>Release</em> button will release the thread out of
any sleep it is currently in.\n"
"<p><b>Priority:</b> Change the thread's priority.\n"
"<p>Once the new state has been selected, press the <em>Submit</em>
button to make the change, or <em>Reset</em> to clear it."
;
static cyg_bool cyg_monitor_thread_edit( FILE * client, char *filename,
char *formdata, void *arg )
{
/* If any form data has been supplied, then change the thread's
* state accordingly.
*/
if( formdata != NULL )
{
char *formlist[6];
char *state;
char *pri_string;
char *id_string;
cyg_handle_t thread = 0;
cyg_uint16 id;
/* Parse the data */
cyg_formdata_parse( formdata, formlist, 6 );
/* Get the thread id from the hidden control */
id_string = cyg_formlist_find( formlist, "thread");
sscanf( id_string, "%04hx", &id );
thread = cyg_thread_find( id );
/* If there is a pri field, change the priority */
pri_string = cyg_formlist_find( formlist, "pri");
if( pri_string != NULL )
{
cyg_priority_t pri;
sscanf( pri_string, "%d", &pri );
cyg_thread_set_priority( thread, pri );
}
/* If there is a state field, change the thread state */
state = cyg_formlist_find( formlist, "state");
if( state != NULL )
{
if( strcmp( state, "run" ) == 0 )
cyg_thread_resume( thread );
if( strcmp( state, "suspend" ) == 0 )
cyg_thread_suspend( thread );
if( strcmp( state, "release" ) == 0 )
cyg_thread_release( thread );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -