1 |
27 |
unneback |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
Embedded HTTP Server
|
31 |
|
|
|
32 |
|
|
Embedded HTTP Server
|
33 |
|
|
|
34 |
|
|
|
35 |
|
|
Intrduction
|
36 |
|
|
|
37 |
|
|
The eCos HTTPD package provides a simple HTTP
|
38 |
|
|
server for use with applications in eCos. This server is specifically
|
39 |
|
|
aimed at the remote control and monitoring requirements of embedded
|
40 |
|
|
applications. For this reason the emphasis is on dynamically generated
|
41 |
|
|
content, simple forms handling and a basic CGI interface. It is
|
42 |
|
|
not intended to be a general purpose server for
|
43 |
|
|
delivering arbitrary web content. For these purposes a port of the
|
44 |
|
|
GoAhead web server is available from
|
45 |
|
|
url="www.goahead.com">www.goahead.com.
|
46 |
|
|
|
47 |
|
|
|
48 |
|
|
|
49 |
|
|
|
50 |
|
|
Server Organization
|
51 |
|
|
|
52 |
|
|
The server consists of one or more threads running in parallel to any
|
53 |
|
|
application threads and which serve web pages to clients. Apart from
|
54 |
|
|
defining content, the application does not need to do anything to
|
55 |
|
|
start the HTTP server.
|
56 |
|
|
|
57 |
|
|
|
58 |
|
|
The HTTP server is started by a static constructor. This simply
|
59 |
|
|
creates an initial thread and sets it running. Since this is called
|
60 |
|
|
before the scheduler is started, nothing will happen until the
|
61 |
|
|
application calls cyg_scheduler_start().
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
When the thread gets to run it first optionally delays for some period
|
65 |
|
|
of time. This is to allow the application to perform any
|
66 |
|
|
initialization free of any interference from the HTTP server. When the
|
67 |
|
|
thread does finally run it creates a socket, binds it to the HTTP
|
68 |
|
|
server port, and puts it into listen mode. It will then create any
|
69 |
|
|
additional HTTPD server threads that have been configured before
|
70 |
|
|
becoming a server thread itself.
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
Each HTTPD server thread simply waits for a connection to be made to
|
74 |
|
|
the server port. When the connection is made it reads the HTTP request
|
75 |
|
|
and extracts the filename being accessed. If the request also contains
|
76 |
|
|
form data, this is also preserved. The filename is then looked up in a
|
77 |
|
|
table.
|
78 |
|
|
|
79 |
|
|
|
80 |
|
|
Each table entry contains a filename pattern string, a
|
81 |
|
|
pointer to a handler function, and a user defined argument for the
|
82 |
|
|
function. Table entries are defined using the same link-time table
|
83 |
|
|
building mechanism used to generate device tables. This is all handled
|
84 |
|
|
by the CYG_HTTPD_TABLE_ENTRY() macro which has the
|
85 |
|
|
following format:
|
86 |
|
|
|
87 |
|
|
|
88 |
|
|
|
89 |
|
|
#include <cyg/httpd/httpd.h>
|
90 |
|
|
|
91 |
|
|
CYG_HTTPD_TABLE_ENTRY( __name, __pattern, __handler, __arg )
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
|
95 |
|
|
The __name argument is a variable name for the
|
96 |
|
|
table entry since C does not allow us to define anonymous data
|
97 |
|
|
structures. This name should be chosen so that it is unique and does
|
98 |
|
|
not pollute the name space. The __pattern
|
99 |
|
|
argument is the match pattern. The __handler
|
100 |
|
|
argument is a pointer to the handler function and
|
101 |
|
|
__arg the user defined value.
|
102 |
|
|
|
103 |
|
|
|
104 |
|
|
The link-time table building means that several different pieces of
|
105 |
|
|
code can define server table entries, and so long as the patterns do
|
106 |
|
|
not clash they can be totally oblivious of each other. However, note
|
107 |
|
|
also that this mechanism does not guarantee the order in which entries
|
108 |
|
|
appear, this depends on the order of object files in the link, which
|
109 |
|
|
could vary from one build to the next. So any tricky pattern matching
|
110 |
|
|
that relies on this may not always work.
|
111 |
|
|
|
112 |
|
|
|
113 |
|
|
A request filename matches an entry in the table if either it exactly
|
114 |
|
|
matches the pattern string, or if the pattern ends in an asterisk, and
|
115 |
|
|
it matches everything up to that point. So for example the pattern
|
116 |
|
|
"/monitor/threads.html" will only match that exact filename,
|
117 |
|
|
but the pattern "/monitor/thread-*" will match
|
118 |
|
|
"/monitor/thread-0040.html",
|
119 |
|
|
"/monitor/thread-0100.html" and any other filename starting
|
120 |
|
|
with "/monitor/thread-".
|
121 |
|
|
|
122 |
|
|
|
123 |
|
|
When a pattern is matched, the hander function is called. It has the
|
124 |
|
|
following prototype:
|
125 |
|
|
|
126 |
|
|
|
127 |
|
|
cyg_bool cyg_httpd_handler(FILE *client,
|
128 |
|
|
char *filename,
|
129 |
|
|
char *formdata,
|
130 |
|
|
void *arg);
|
131 |
|
|
|
132 |
|
|
|
133 |
|
|
The client argument is the TCP connection to
|
134 |
|
|
the client: anything output through this stream will be returned to
|
135 |
|
|
the browser. The filename argument is the
|
136 |
|
|
filename from the HTTP request and the formdata
|
137 |
|
|
argument is any form response data, or NULL if none was sent. The
|
138 |
|
|
arg argument is the user defined value from the
|
139 |
|
|
table entry.
|
140 |
|
|
|
141 |
|
|
|
142 |
|
|
The handler is entirely responsible for generating the response to the
|
143 |
|
|
client, both HTTP header and content. If the handler decides that it
|
144 |
|
|
does not want to generate a response it can return
|
145 |
|
|
false, in which case the table scan is resumed for
|
146 |
|
|
another match. If no match is found, or no handler returns true, then
|
147 |
|
|
a default response page is generated indicating that the requested
|
148 |
|
|
page cannot be found.
|
149 |
|
|
|
150 |
|
|
|
151 |
|
|
Finally, the server thread closes the connection to the client and
|
152 |
|
|
loops back to accept a new connection.
|
153 |
|
|
|
154 |
|
|
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
|
158 |
|
|
|
159 |
|
|
Server Configuration
|
160 |
|
|
|
161 |
|
|
The HTTP server has a number of configuration options:
|
162 |
|
|
|
163 |
|
|
|
164 |
|
|
|
165 |
|
|
CYGNUM_HTTPD_SERVER_PORT
|
166 |
|
|
|
167 |
|
|
This option defines the TCP port that the server will listen on. It
|
168 |
|
|
defaults to the standard HTTP port number 80. It may be changed to a
|
169 |
|
|
different number if, for example, another HTTP server is using the
|
170 |
|
|
main HTTP port.
|
171 |
|
|
|
172 |
|
|
|
173 |
|
|
|
174 |
|
|
|
175 |
|
|
CYGDAT_HTTPD_SERVER_ID
|
176 |
|
|
|
177 |
|
|
This is the string that is reported to the client in the
|
178 |
|
|
"Server:" field of the HTTP header.
|
179 |
|
|
|
180 |
|
|
|
181 |
|
|
|
182 |
|
|
|
183 |
|
|
CYGNUM_HTTPD_THREAD_COUNT
|
184 |
|
|
|
185 |
|
|
The HTTP server can be configured to use more than one thread to
|
186 |
|
|
service HTTP requests. If you expect to serve complex pages with many
|
187 |
|
|
images or other components that are fetched separately, or if any
|
188 |
|
|
pages may take a long time to send, then it may be useful to increase
|
189 |
|
|
the number of server threads. For most uses, however, the connection
|
190 |
|
|
queuing in the TCP/IP stack and the speed with which each page is
|
191 |
|
|
generated, means that a single thread is usually adequate.
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
|
195 |
|
|
|
196 |
|
|
CYGNUM_HTTPD_THREAD_PRIORITY
|
197 |
|
|
|
198 |
|
|
The HTTP server threads can be run at any priority. The exact priority
|
199 |
|
|
depends on the importance of the server relative to the rest of the
|
200 |
|
|
system. The default is to put them in the middle of the priority range
|
201 |
|
|
to provide reasonable response without impacting genuine high priority
|
202 |
|
|
threads.
|
203 |
|
|
|
204 |
|
|
|
205 |
|
|
|
206 |
|
|
|
207 |
|
|
CYGNUM_HTTPD_THREAD_STACK_SIZE
|
208 |
|
|
|
209 |
|
|
This is the amount of stack to be allocated for each of the HTTPD
|
210 |
|
|
threads. The actual stack size allocated will be this value plus the
|
211 |
|
|
values of CYGNUM_HAL_STACK_SIZE_MINIMUM and
|
212 |
|
|
CYGNUM_HTTPD_SERVER_BUFFER_SIZE.
|
213 |
|
|
|
214 |
|
|
|
215 |
|
|
|
216 |
|
|
|
217 |
|
|
CYGNUM_HTTPD_SERVER_BUFFER_SIZE
|
218 |
|
|
|
219 |
|
|
This defines the size of the buffer used to receive the first line of
|
220 |
|
|
each HTTP request. If you expect to use particularly long URLs or have
|
221 |
|
|
very complex forms, this should be increased.
|
222 |
|
|
|
223 |
|
|
|
224 |
|
|
|
225 |
|
|
|
226 |
|
|
CYGNUM_HTTPD_SERVER_DELAY
|
227 |
|
|
|
228 |
|
|
This defines the number of system clock ticks that the HTTP server
|
229 |
|
|
will wait before initializing itself and spawning any extra server
|
230 |
|
|
threads. This is to give the application a chance to initialize
|
231 |
|
|
properly without any interference from the HTTPD.
|
232 |
|
|
|
233 |
|
|
|
234 |
|
|
|
235 |
|
|
|
236 |
|
|
|
237 |
|
|
|
238 |
|
|
|
239 |
|
|
|
240 |
|
|
Support Functions and Macros
|
241 |
|
|
|
242 |
|
|
The emphasis of this server is on dynamically generated content,
|
243 |
|
|
rather than fetching it from a filesystem. To do this the handler
|
244 |
|
|
functions make calls to fprintf() and
|
245 |
|
|
fputs(). Such handler functions would end up a
|
246 |
|
|
mass of print calls, with the actual structure of the HTML page hidden
|
247 |
|
|
in the format strings and arguments, making maintenance and debugging
|
248 |
|
|
very difficult. Such an approach would also result in the definition
|
249 |
|
|
of many, often only slightly different, format strings, leading to
|
250 |
|
|
unnecessary bloat.
|
251 |
|
|
|
252 |
|
|
|
253 |
|
|
In an effort to expose the structure of the HTML in the structure of
|
254 |
|
|
the C code, and to maximize the sharing of string constants, the
|
255 |
|
|
cyg/httpd/httpd.h header file defines a set of
|
256 |
|
|
helper functions and macros. Most of these are wrappers for predefined
|
257 |
|
|
print calls on the client stream passed to the
|
258 |
|
|
hander function. For examples of their use, see the System Monitor
|
259 |
|
|
example.
|
260 |
|
|
|
261 |
|
|
|
262 |
|
|
|
263 |
|
|
All arguments to macros are pointers to strings, unless otherwise
|
264 |
|
|
stated. In general, wherever a function or macro has an
|
265 |
|
|
attr or __attr
|
266 |
|
|
parameter, then the contents of this string will be inserted into the
|
267 |
|
|
tag being defined as HTML attributes. If it is a NULL or empty string
|
268 |
|
|
it will be ignored.
|
269 |
|
|
|
270 |
|
|
|
271 |
|
|
|
272 |
|
|
|
273 |
|
|
HTTP Support
|
274 |
|
|
|
275 |
|
|
void cyg_http_start( FILE *client, char *content_type, int content_length );
|
276 |
|
|
void cyg_http_finish( FILE *client );
|
277 |
|
|
#define html_begin(__client)
|
278 |
|
|
#define html_end( __client )
|
279 |
|
|
|
280 |
|
|
|
281 |
|
|
The function cyg_http_start() generates a simple
|
282 |
|
|
HTTP response header containing the value of
|
283 |
|
|
CYGDAT_HTTPD_SERVER_ID in the "Server" field, and the
|
284 |
|
|
values of content_type and
|
285 |
|
|
content_length in the "Content-type"
|
286 |
|
|
and "Content-length" field respectively. The function
|
287 |
|
|
cyg_http_finish() just adds an extra newline to
|
288 |
|
|
the end of the output and then flushes it to force the data out to the
|
289 |
|
|
client.
|
290 |
|
|
|
291 |
|
|
|
292 |
|
|
The macro html_begin() generates an HTTP header
|
293 |
|
|
with a "text/html" content type followed by an opening
|
294 |
|
|
"<html>" tag. html_end() generates
|
295 |
|
|
a closing "</html>" tag and calls
|
296 |
|
|
cyg_http_finish().
|
297 |
|
|
|
298 |
|
|
|
299 |
|
|
|
300 |
|
|
|
301 |
|
|
General HTML Support
|
302 |
|
|
|
303 |
|
|
void cyg_html_tag_begin( FILE *client, char *tag, char *attr );
|
304 |
|
|
void cyg_html_tag_end( FILE *client, char *tag );
|
305 |
|
|
#define html_tag_begin( __client, __tag, __attr )
|
306 |
|
|
#define html_tag_end( __client, __tag )
|
307 |
|
|
#define html_head( __client, __title, __meta )
|
308 |
|
|
#define html_body_begin( __client, __attr )
|
309 |
|
|
#define html_body_end( __client )
|
310 |
|
|
#define html_heading( __client, __level, __heading )
|
311 |
|
|
#define html_para_begin( __client, __attr )
|
312 |
|
|
#define html_url( __client, __text, __link )
|
313 |
|
|
#define html_image( __client, __source, __alt, __attr )
|
314 |
|
|
|
315 |
|
|
|
316 |
|
|
The function cyg_html_tag_begin() generates an
|
317 |
|
|
opening tag with the given name. The function
|
318 |
|
|
cyg_html_tag_end() generates a closing tag with
|
319 |
|
|
the given name. The macros html_tag_begin() and
|
320 |
|
|
html_tag_end are just wrappers for these functions.
|
321 |
|
|
|
322 |
|
|
|
323 |
|
|
The macro html_head() generates an HTML header
|
324 |
|
|
section with __title as the title. The
|
325 |
|
|
__meta argument defines any meta tags that will
|
326 |
|
|
be inserted into the header. html_body_begin() and
|
327 |
|
|
html_body_end generate HTML body begin and end
|
328 |
|
|
tags.
|
329 |
|
|
|
330 |
|
|
|
331 |
|
|
html_heading() generates a complete HTML header
|
332 |
|
|
where __level is a numerical level, between 1
|
333 |
|
|
and 6, and __heading is the heading
|
334 |
|
|
text. html_para_begin() generates a paragraph
|
335 |
|
|
break.
|
336 |
|
|
|
337 |
|
|
|
338 |
|
|
html_url() inserts a URL where
|
339 |
|
|
__text is the displayed text and
|
340 |
|
|
__link is the URL of the linked
|
341 |
|
|
page. html_image() inserts an image tag where
|
342 |
|
|
__source is the URL of the image to be
|
343 |
|
|
included and __alt is the alternative text for
|
344 |
|
|
when the image is not displayed.
|
345 |
|
|
|
346 |
|
|
|
347 |
|
|
|
348 |
|
|
|
349 |
|
|
Table Support
|
350 |
|
|
|
351 |
|
|
#define html_table_begin( __client, __attr )
|
352 |
|
|
#define html_table_end( __client )
|
353 |
|
|
#define html_table_header( __client, __content, __attr )
|
354 |
|
|
#define html_table_row_begin( __client, __attr )
|
355 |
|
|
#define html_table_row_end( __client )
|
356 |
|
|
#define html_table_data_begin( __client, __attr )
|
357 |
|
|
#define html_table_data_end( __client )
|
358 |
|
|
|
359 |
|
|
|
360 |
|
|
html_table_begin() starts a table and
|
361 |
|
|
html_table_end() end
|
362 |
|
|
it. html_table_header() generates a simple table
|
363 |
|
|
column header containg the string __content.
|
364 |
|
|
|
365 |
|
|
|
366 |
|
|
html_table_row_begin() and
|
367 |
|
|
html_table_row_end() begin and end a table row,
|
368 |
|
|
and similarly html_table_data_begin() and
|
369 |
|
|
html_table_data_end() begin and end a table
|
370 |
|
|
entry.
|
371 |
|
|
|
372 |
|
|
|
373 |
|
|
|
374 |
|
|
|
375 |
|
|
Forms Support
|
376 |
|
|
|
377 |
|
|
#define html_form_begin( __client, __url, __attr )
|
378 |
|
|
#define html_form_end( __client )
|
379 |
|
|
#define html_form_input( __client, __type, __name, __value, __attr )
|
380 |
|
|
#define html_form_input_radio( __client, __name, __value, __checked )
|
381 |
|
|
#define html_form_input_checkbox( __client, __name, __value, __checked )
|
382 |
|
|
#define html_form_input_hidden( __client, __name, __value )
|
383 |
|
|
#define html_form_select_begin( __client, __name, __attr )
|
384 |
|
|
#define html_form_option( __client, __value, __label, __selected )
|
385 |
|
|
#define html_form_select_end( __client )
|
386 |
|
|
void cyg_formdata_parse( char *data, char *list[], int size );
|
387 |
|
|
char *cyg_formlist_find( char *list[], char *name );
|
388 |
|
|
|
389 |
|
|
|
390 |
|
|
html_form_begin() begins a form, the
|
391 |
|
|
__url argument is the value for the
|
392 |
|
|
action
|
393 |
|
|
attribute. html_form_end() ends the form.
|
394 |
|
|
|
395 |
|
|
|
396 |
|
|
html_form_input() defines a general form input
|
397 |
|
|
element with the given type, name and
|
398 |
|
|
value. html_form_input_radio creates a radio button
|
399 |
|
|
with the given name and value; the __checked
|
400 |
|
|
argument is a boolean expression that is used to determine whether the
|
401 |
|
|
checked attribute is added to the tag. Similarly
|
402 |
|
|
html_form_input_checkbox() defines a checkbox
|
403 |
|
|
element. html_form_input_hidden() defines a hidden
|
404 |
|
|
form element with the given name and value.
|
405 |
|
|
|
406 |
|
|
|
407 |
|
|
html_form_select_begin() begins a multiple choice
|
408 |
|
|
menu with the given name. html_form_select_end()
|
409 |
|
|
end it. html_form_option() defines a menu entry
|
410 |
|
|
with the given value and label; the __selected
|
411 |
|
|
argument is a boolean expression controlling whether the
|
412 |
|
|
selected attribute is added to the tag.
|
413 |
|
|
|
414 |
|
|
|
415 |
|
|
cyg_formdata_parse() converts a form response
|
416 |
|
|
string into an NULL-terminated array of
|
417 |
|
|
"name=value" entries. The data
|
418 |
|
|
argument is the string as passed to the handler function; note that
|
419 |
|
|
this string is not copied and will be updated in place to form the
|
420 |
|
|
list entries. list is a pointer to an array of
|
421 |
|
|
character pointers, and is size elements long.
|
422 |
|
|
cyg_formlist_find() searches a list generated by
|
423 |
|
|
cyg_formdata_parse() and returns a pointer to the
|
424 |
|
|
value part of the string whose name part matches
|
425 |
|
|
name; if there is no match it will return
|
426 |
|
|
NULL.
|
427 |
|
|
|
428 |
|
|
|
429 |
|
|
|
430 |
|
|
|
431 |
|
|
Predefined Handlers
|
432 |
|
|
|
433 |
|
|
|
434 |
|
|
int cyg_httpd_send_html( FILE *client, char *filename, char *request, void *arg );
|
435 |
|
|
|
436 |
|
|
typedef struct
|
437 |
|
|
{
|
438 |
|
|
char *content_type;
|
439 |
|
|
cyg_uint32 content_length;
|
440 |
|
|
cyg_uint8 *data;
|
441 |
|
|
} cyg_httpd_data;
|
442 |
|
|
#define CYG_HTTPD_DATA( __name, __type, __length, __data )
|
443 |
|
|
|
444 |
|
|
int cyg_httpd_send_data( FILE *client, char *filename, char *request, void *arg );
|
445 |
|
|
|
446 |
|
|
|
447 |
|
|
|
448 |
|
|
The HTTP server defines a couple of predefined handers to make it
|
449 |
|
|
easier to deliver simple, static content.
|
450 |
|
|
|
451 |
|
|
|
452 |
|
|
cyg_httpd_send_html() takes a
|
453 |
|
|
NULL-terminated string as the argument and sends it
|
454 |
|
|
to the client with an HTTP header indicating that it is HTML. The
|
455 |
|
|
following is an example of its use:
|
456 |
|
|
|
457 |
|
|
|
458 |
|
|
|
459 |
|
|
char cyg_html_message[] = "<head><title>Welcome</title></head>\n"
|
460 |
|
|
"<body><h2>Welcome to my Web Page</h2></body>\n"
|
461 |
|
|
|
462 |
|
|
CYG_HTTPD_TABLE_ENTRY( cyg_html_message_entry,
|
463 |
|
|
"/message.html",
|
464 |
|
|
cyg_httpd_send_html,
|
465 |
|
|
cyg_html_message );
|
466 |
|
|
|
467 |
|
|
|
468 |
|
|
|
469 |
|
|
cyg_httpd_send_data() Sends arbitrary data to the
|
470 |
|
|
client. The argument is a pointer to a cyg_httpd_data
|
471 |
|
|
structure that defines the content type and length of the data, and a
|
472 |
|
|
pointer to the data itself. The CYG_HTTPD_DATA()
|
473 |
|
|
macro automates the definition of the structure. Here is a typical
|
474 |
|
|
example of its use:
|
475 |
|
|
|
476 |
|
|
|
477 |
|
|
|
478 |
|
|
static cyg_uint8 ecos_logo_gif[] = {
|
479 |
|
|
...
|
480 |
|
|
};
|
481 |
|
|
|
482 |
|
|
CYG_HTTPD_DATA( cyg_monitor_ecos_logo_data,
|
483 |
|
|
"image/gif",
|
484 |
|
|
sizeof(ecos_logo_gif),
|
485 |
|
|
ecos_logo_gif );
|
486 |
|
|
|
487 |
|
|
CYG_HTTPD_TABLE_ENTRY( cyg_monitor_ecos_logo,
|
488 |
|
|
"/monitor/ecos.gif",
|
489 |
|
|
cyg_httpd_send_data,
|
490 |
|
|
&cyg_monitor_ecos_logo_data );
|
491 |
|
|
|
492 |
|
|
|
493 |
|
|
|
494 |
|
|
|
495 |
|
|
|
496 |
|
|
|
497 |
|
|
|
498 |
|
|
|
499 |
|
|
|
500 |
|
|
System Monitor
|
501 |
|
|
|
502 |
|
|
Included in the HTTPD package is a simple System Monitor that is
|
503 |
|
|
intended to act as a test and an example of how to produce servers.
|
504 |
|
|
It is also hoped that it might be of some use in and of itself.
|
505 |
|
|
|
506 |
|
|
|
507 |
|
|
The System Monitor is intended to work in the background of any
|
508 |
|
|
application. Adding the network stack and the HTTPD package to any
|
509 |
|
|
configuration will enable the monitor by default. It may be disabled
|
510 |
|
|
by disabling the CYGPKG_HTTPD_MONITOR option.
|
511 |
|
|
|
512 |
|
|
|
513 |
|
|
The monitor is intended to be simple and self-explanatory in use. It
|
514 |
|
|
consists of four main pages. The thread monitor page presents a table
|
515 |
|
|
of all current threads showing such things as id, state, priority,
|
516 |
|
|
name and stack dimensions. Clicking on the thread ID will link to a
|
517 |
|
|
thread edit page where the thread's state and priority may be
|
518 |
|
|
manipulated. The interrupt monitor just shows a table of the current
|
519 |
|
|
interrupts and indicates which are active. The memory monitor shows a
|
520 |
|
|
256 byte page of memory, with controls to change the base address and
|
521 |
|
|
display element size. The network monitor page shows
|
522 |
|
|
information extracted from the active network interfaces and
|
523 |
|
|
protocols. Finally, if kernel instrumentation is enabled, the
|
524 |
|
|
instrumentation page provides some controls over the instrumentation
|
525 |
|
|
mechanism, and displays the instrumentation buffer.
|
526 |
|
|
|
527 |
|
|
|
528 |
|
|
|
529 |
|
|
|
530 |
|
|
|
531 |
|
|
|
532 |
|
|
|