[ac7d5ef0] | 1 | /* |
---|
[b06e68ef] | 2 | * RTEMS monitor main body |
---|
[aed742c] | 3 | * |
---|
[ac7d5ef0] | 4 | * TODO: |
---|
[b06e68ef] | 5 | * add stuff to RTEMS api |
---|
| 6 | * rtems_get_name(id) |
---|
| 7 | * rtems_get_type(id) |
---|
| 8 | * rtems_build_id(node, type, num) |
---|
| 9 | * Add a command to dump out info about an arbitrary id when |
---|
| 10 | * types are added to id's |
---|
| 11 | * rtems> id idnum |
---|
| 12 | * idnum: node n, object: whatever, id: whatever |
---|
| 13 | * allow id's to be specified as n:t:id, where 'n:t' is optional |
---|
| 14 | * should have a separate monitor FILE stream (ala the debugger) |
---|
| 15 | * remote request/response stuff should be cleaned up |
---|
| 16 | * maybe we can use real rpc?? |
---|
[8389628] | 17 | * 'info' command to print out: |
---|
[c64e4ed4] | 18 | * interrupt stack location, direction and size |
---|
| 19 | * floating point config stuff |
---|
| 20 | * interrupt config stuff |
---|
[b06e68ef] | 21 | * |
---|
| 22 | * $Id$ |
---|
[ac7d5ef0] | 23 | */ |
---|
| 24 | |
---|
[550c3df7] | 25 | #ifdef HAVE_CONFIG_H |
---|
| 26 | #include "config.h" |
---|
| 27 | #endif |
---|
| 28 | |
---|
[ac7d5ef0] | 29 | #include <rtems.h> |
---|
| 30 | |
---|
| 31 | #include <stdio.h> |
---|
| 32 | #include <string.h> |
---|
| 33 | #include <stdlib.h> |
---|
| 34 | |
---|
[5beb562] | 35 | #include <rtems/monitor.h> |
---|
[ac7d5ef0] | 36 | |
---|
| 37 | /* set by trap handler */ |
---|
| 38 | extern rtems_tcb *debugger_interrupted_task; |
---|
| 39 | extern rtems_context *debugger_interrupted_task_context; |
---|
[3e08d4e] | 40 | extern uint32_t debugger_trap; |
---|
[ac7d5ef0] | 41 | |
---|
[b06e68ef] | 42 | /* |
---|
| 43 | * Various id's for the monitor |
---|
| 44 | * They need to be public variables for access by other agencies |
---|
| 45 | * such as debugger and remote servers' |
---|
| 46 | */ |
---|
[ac7d5ef0] | 47 | |
---|
[b06e68ef] | 48 | rtems_id rtems_monitor_task_id; |
---|
[ac7d5ef0] | 49 | |
---|
[3e08d4e] | 50 | uint32_t rtems_monitor_node; /* our node number */ |
---|
| 51 | uint32_t rtems_monitor_default_node; /* current default for commands */ |
---|
[ac7d5ef0] | 52 | |
---|
| 53 | /* |
---|
[b06e68ef] | 54 | * The rtems symbol table |
---|
[ac7d5ef0] | 55 | */ |
---|
| 56 | |
---|
[b06e68ef] | 57 | rtems_symbol_table_t *rtems_monitor_symbols; |
---|
| 58 | |
---|
[ac7d5ef0] | 59 | /* |
---|
[b06e68ef] | 60 | * The top-level commands |
---|
[ac7d5ef0] | 61 | */ |
---|
| 62 | |
---|
[eb961961] | 63 | static const rtems_monitor_command_entry_t rtems_monitor_commands[] = { |
---|
[b06e68ef] | 64 | { "config", |
---|
[32e2554] | 65 | "Show the system configuration.", |
---|
[b06e68ef] | 66 | 0, |
---|
| 67 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 68 | { RTEMS_MONITOR_OBJECT_CONFIG }, |
---|
[32e2554] | 69 | &rtems_monitor_commands[1], |
---|
[b06e68ef] | 70 | }, |
---|
| 71 | { "itask", |
---|
[32e2554] | 72 | "List init tasks for the system", |
---|
[b06e68ef] | 73 | 0, |
---|
| 74 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 75 | { RTEMS_MONITOR_OBJECT_INIT_TASK }, |
---|
[32e2554] | 76 | &rtems_monitor_commands[2], |
---|
[aed742c] | 77 | }, |
---|
[b06e68ef] | 78 | { "mpci", |
---|
[32e2554] | 79 | "Show the MPCI system configuration, if configured.", |
---|
[b06e68ef] | 80 | 0, |
---|
| 81 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 82 | { RTEMS_MONITOR_OBJECT_MPCI }, |
---|
[32e2554] | 83 | &rtems_monitor_commands[3], |
---|
[b06e68ef] | 84 | }, |
---|
| 85 | { "pause", |
---|
[32e2554] | 86 | "Monitor goes to \"sleep\" for specified ticks (default is 1). " |
---|
| 87 | "Monitor will resume at end of period or if explicitly awakened\n" |
---|
| 88 | " pause [ticks]", |
---|
[b06e68ef] | 89 | 0, |
---|
| 90 | rtems_monitor_pause_cmd, |
---|
[d4c4078] | 91 | { 0 }, |
---|
[32e2554] | 92 | &rtems_monitor_commands[4], |
---|
[b06e68ef] | 93 | }, |
---|
| 94 | { "continue", |
---|
[32e2554] | 95 | "Put the monitor to sleep waiting for an explicit wakeup from the " |
---|
| 96 | "program running.\n", |
---|
[b06e68ef] | 97 | 0, |
---|
| 98 | rtems_monitor_continue_cmd, |
---|
[d4c4078] | 99 | { 0 }, |
---|
[32e2554] | 100 | &rtems_monitor_commands[5], |
---|
[b06e68ef] | 101 | }, |
---|
| 102 | { "go", |
---|
[32e2554] | 103 | "Alias for 'continue'", |
---|
[b06e68ef] | 104 | 0, |
---|
| 105 | rtems_monitor_continue_cmd, |
---|
[d4c4078] | 106 | { 0 }, |
---|
[32e2554] | 107 | &rtems_monitor_commands[6], |
---|
[b06e68ef] | 108 | }, |
---|
| 109 | { "node", |
---|
[32e2554] | 110 | "Specify default node number for commands that take id's.\n" |
---|
| 111 | " node [ node number ]", |
---|
[b06e68ef] | 112 | 0, |
---|
| 113 | rtems_monitor_node_cmd, |
---|
[d4c4078] | 114 | { 0 }, |
---|
[32e2554] | 115 | &rtems_monitor_commands[7], |
---|
[b06e68ef] | 116 | }, |
---|
| 117 | { "symbol", |
---|
[32e2554] | 118 | "Display value associated with specified symbol. " |
---|
| 119 | "Defaults to displaying all known symbols.\n" |
---|
| 120 | " symbol [ symbolname [symbolname ... ] ]", |
---|
[b06e68ef] | 121 | 0, |
---|
| 122 | rtems_monitor_symbol_cmd, |
---|
[d4c4078] | 123 | { .symbol_table = &rtems_monitor_symbols }, |
---|
[32e2554] | 124 | &rtems_monitor_commands[8], |
---|
[b06e68ef] | 125 | }, |
---|
| 126 | { "extension", |
---|
[32e2554] | 127 | "Display information about specified extensions. " |
---|
| 128 | "Default is to display information about all extensions on this node.\n" |
---|
| 129 | " extension [id [id ...] ]", |
---|
[b06e68ef] | 130 | 0, |
---|
| 131 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 132 | { RTEMS_MONITOR_OBJECT_EXTENSION }, |
---|
[32e2554] | 133 | &rtems_monitor_commands[9], |
---|
[b06e68ef] | 134 | }, |
---|
| 135 | { "task", |
---|
[32e2554] | 136 | "Display information about the specified tasks. " |
---|
| 137 | "Default is to display information about all tasks on this node.\n" |
---|
| 138 | " task [id [id ...] ]", |
---|
[b06e68ef] | 139 | 0, |
---|
| 140 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 141 | { RTEMS_MONITOR_OBJECT_TASK }, |
---|
[32e2554] | 142 | &rtems_monitor_commands[10], |
---|
[b06e68ef] | 143 | }, |
---|
| 144 | { "queue", |
---|
[32e2554] | 145 | "Display information about the specified message queues. " |
---|
| 146 | "Default is to display information about all queues on this node.\n" |
---|
| 147 | " queue [id [id ... ] ]", |
---|
[b06e68ef] | 148 | 0, |
---|
| 149 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 150 | { RTEMS_MONITOR_OBJECT_QUEUE }, |
---|
[32e2554] | 151 | &rtems_monitor_commands[11], |
---|
[b06e68ef] | 152 | }, |
---|
[501ab691] | 153 | { "sema", |
---|
| 154 | "sema [id [id ... ] ]\n" |
---|
| 155 | " display information about the specified semaphores\n" |
---|
| 156 | " Default is to display information about all semaphores on this node\n" |
---|
| 157 | , |
---|
| 158 | 0, |
---|
| 159 | rtems_monitor_object_cmd, |
---|
[e420436] | 160 | { RTEMS_MONITOR_OBJECT_SEMAPHORE }, |
---|
[908d6ed] | 161 | &rtems_monitor_commands[12], |
---|
[501ab691] | 162 | }, |
---|
| 163 | { "region", |
---|
| 164 | "region [id [id ... ] ]\n" |
---|
| 165 | " display information about the specified regions\n" |
---|
| 166 | " Default is to display information about all regions on this node\n" |
---|
| 167 | , |
---|
| 168 | 0, |
---|
| 169 | rtems_monitor_object_cmd, |
---|
[e420436] | 170 | { RTEMS_MONITOR_OBJECT_REGION }, |
---|
[908d6ed] | 171 | &rtems_monitor_commands[13], |
---|
[501ab691] | 172 | }, |
---|
| 173 | { "part", |
---|
| 174 | "part [id [id ... ] ]\n" |
---|
| 175 | " display information about the specified partitions\n" |
---|
| 176 | " Default is to display information about all partitions on this node\n" |
---|
| 177 | , |
---|
| 178 | 0, |
---|
| 179 | rtems_monitor_object_cmd, |
---|
[e420436] | 180 | { RTEMS_MONITOR_OBJECT_PARTITION }, |
---|
[908d6ed] | 181 | &rtems_monitor_commands[14], |
---|
[501ab691] | 182 | }, |
---|
[b06e68ef] | 183 | { "object", |
---|
[32e2554] | 184 | "Display information about specified RTEMS objects. " |
---|
| 185 | "Object id's must include 'type' information. " |
---|
| 186 | "(which may normally be defaulted)\n" |
---|
| 187 | " object [id [id ...] ]", |
---|
[b06e68ef] | 188 | 0, |
---|
| 189 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 190 | { RTEMS_MONITOR_OBJECT_INVALID }, |
---|
[908d6ed] | 191 | &rtems_monitor_commands[15], |
---|
[b06e68ef] | 192 | }, |
---|
| 193 | { "driver", |
---|
[32e2554] | 194 | "Display the RTEMS device driver table.\n" |
---|
| 195 | " driver [ major [ major ... ] ]", |
---|
[b06e68ef] | 196 | 0, |
---|
| 197 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 198 | { RTEMS_MONITOR_OBJECT_DRIVER }, |
---|
[908d6ed] | 199 | &rtems_monitor_commands[16], |
---|
[b06e68ef] | 200 | }, |
---|
| 201 | { "dname", |
---|
[32e2554] | 202 | "Displays information about named drivers.\n", |
---|
[b06e68ef] | 203 | 0, |
---|
| 204 | rtems_monitor_object_cmd, |
---|
[d4c4078] | 205 | { RTEMS_MONITOR_OBJECT_DNAME }, |
---|
[908d6ed] | 206 | &rtems_monitor_commands[17], |
---|
[b06e68ef] | 207 | }, |
---|
| 208 | { "exit", |
---|
[32e2554] | 209 | "Invoke 'rtems_fatal_error_occurred' with 'status' " |
---|
| 210 | "(default is RTEMS_SUCCESSFUL)\n" |
---|
| 211 | " exit [status]", |
---|
[b06e68ef] | 212 | 0, |
---|
| 213 | rtems_monitor_fatal_cmd, |
---|
[d4c4078] | 214 | { .status_code = RTEMS_SUCCESSFUL }, |
---|
[908d6ed] | 215 | &rtems_monitor_commands[18], |
---|
[b06e68ef] | 216 | }, |
---|
| 217 | { "fatal", |
---|
[32e2554] | 218 | "'exit' with fatal error; default error is RTEMS_TASK_EXITTED\n" |
---|
| 219 | " fatal [status]", |
---|
[b06e68ef] | 220 | 0, |
---|
| 221 | rtems_monitor_fatal_cmd, |
---|
[d4c4078] | 222 | { .status_code = RTEMS_TASK_EXITTED }, /* exit value */ |
---|
[908d6ed] | 223 | &rtems_monitor_commands[19], |
---|
[b06e68ef] | 224 | }, |
---|
| 225 | { "quit", |
---|
[32e2554] | 226 | "Alias for 'exit'\n", |
---|
[b06e68ef] | 227 | 0, |
---|
| 228 | rtems_monitor_fatal_cmd, |
---|
[d4c4078] | 229 | { .status_code = RTEMS_SUCCESSFUL }, /* exit value */ |
---|
[908d6ed] | 230 | &rtems_monitor_commands[20], |
---|
[b06e68ef] | 231 | }, |
---|
[00a2d366] | 232 | #ifdef RTEMS_POSIX_API |
---|
| 233 | { "pthread", |
---|
| 234 | "Display information about the specified pthreads. " |
---|
| 235 | "Default is to display information about all pthreads on this node.\n" |
---|
| 236 | " pthread [id [id ...] ]", |
---|
| 237 | 0, |
---|
| 238 | rtems_monitor_object_cmd, |
---|
| 239 | { RTEMS_MONITOR_OBJECT_PTHREAD }, |
---|
[e41eaa88] | 240 | &rtems_monitor_commands[21], |
---|
[00a2d366] | 241 | }, |
---|
[e41eaa88] | 242 | #define RTEMS_MONITOR_DEBUGGER_NEXT 22 |
---|
| 243 | #else |
---|
| 244 | #define RTEMS_MONITOR_DEBUGGER_NEXT 21 |
---|
[00a2d366] | 245 | #endif |
---|
[b06e68ef] | 246 | #ifdef CPU_INVOKE_DEBUGGER |
---|
| 247 | { "debugger", |
---|
[32e2554] | 248 | "Enter the debugger, if possible. " |
---|
| 249 | "A continue from the debugger will return to the monitor.\n", |
---|
[b06e68ef] | 250 | 0, |
---|
[c64e4ed4] | 251 | rtems_monitor_debugger_cmd, |
---|
[d4c4078] | 252 | { 0 }, |
---|
[e41eaa88] | 253 | &rtems_monitor_commands[RTEMS_MONITOR_DEBUGGER_NEXT], |
---|
[b06e68ef] | 254 | }, |
---|
[aed742c] | 255 | #endif |
---|
[e41eaa88] | 256 | { "help", |
---|
| 257 | "Provide information about commands. " |
---|
| 258 | "Default is show basic command summary.\n" |
---|
| 259 | "help [ command [ command ] ]", |
---|
| 260 | 0, |
---|
| 261 | rtems_monitor_help_cmd, |
---|
| 262 | { .monitor_command_entry = rtems_monitor_commands }, |
---|
| 263 | NULL |
---|
| 264 | } |
---|
[b06e68ef] | 265 | }; |
---|
[ac7d5ef0] | 266 | |
---|
[e41eaa88] | 267 | /* |
---|
| 268 | * All registered commands. |
---|
| 269 | */ |
---|
| 270 | |
---|
| 271 | static const rtems_monitor_command_entry_t *rtems_monitor_registered_commands = |
---|
| 272 | &rtems_monitor_commands [0]; |
---|
| 273 | |
---|
[ac7d5ef0] | 274 | |
---|
| 275 | rtems_status_code |
---|
| 276 | rtems_monitor_suspend(rtems_interval timeout) |
---|
| 277 | { |
---|
| 278 | rtems_event_set event_set; |
---|
| 279 | rtems_status_code status; |
---|
[aed742c] | 280 | |
---|
[b06e68ef] | 281 | status = rtems_event_receive(MONITOR_WAKEUP_EVENT, |
---|
| 282 | RTEMS_DEFAULT_OPTIONS, |
---|
| 283 | timeout, |
---|
| 284 | &event_set); |
---|
[ac7d5ef0] | 285 | return status; |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | void |
---|
| 289 | rtems_monitor_wakeup(void) |
---|
| 290 | { |
---|
| 291 | rtems_status_code status; |
---|
[aed742c] | 292 | |
---|
[ac7d5ef0] | 293 | status = rtems_event_send(rtems_monitor_task_id, MONITOR_WAKEUP_EVENT); |
---|
| 294 | } |
---|
| 295 | |
---|
[e41eaa88] | 296 | void rtems_monitor_debugger_cmd( |
---|
[031deada] | 297 | int argc __attribute__((unused)), |
---|
| 298 | char **argv __attribute__((unused)), |
---|
| 299 | const rtems_monitor_command_arg_t *command_arg __attribute__((unused)), |
---|
| 300 | bool verbose __attribute__((unused)) |
---|
[8389628] | 301 | ) |
---|
| 302 | { |
---|
| 303 | #ifdef CPU_INVOKE_DEBUGGER |
---|
| 304 | CPU_INVOKE_DEBUGGER; |
---|
| 305 | #endif |
---|
| 306 | } |
---|
[ac7d5ef0] | 307 | |
---|
[e41eaa88] | 308 | void rtems_monitor_pause_cmd( |
---|
| 309 | int argc, |
---|
| 310 | char **argv, |
---|
[031deada] | 311 | const rtems_monitor_command_arg_t *command_arg __attribute__((unused)), |
---|
| 312 | bool verbose __attribute__((unused)) |
---|
[b06e68ef] | 313 | ) |
---|
| 314 | { |
---|
| 315 | if (argc == 1) |
---|
| 316 | rtems_monitor_suspend(1); |
---|
| 317 | else |
---|
| 318 | rtems_monitor_suspend(strtoul(argv[1], 0, 0)); |
---|
| 319 | } |
---|
[ac7d5ef0] | 320 | |
---|
[e41eaa88] | 321 | void rtems_monitor_fatal_cmd( |
---|
| 322 | int argc, |
---|
| 323 | char **argv, |
---|
| 324 | const rtems_monitor_command_arg_t *command_arg, |
---|
[031deada] | 325 | bool verbose __attribute__((unused)) |
---|
[b06e68ef] | 326 | ) |
---|
[ac7d5ef0] | 327 | { |
---|
[b06e68ef] | 328 | if (argc == 1) |
---|
[d4c4078] | 329 | rtems_fatal_error_occurred(command_arg->status_code); |
---|
[b06e68ef] | 330 | else |
---|
| 331 | rtems_fatal_error_occurred(strtoul(argv[1], 0, 0)); |
---|
[ac7d5ef0] | 332 | } |
---|
| 333 | |
---|
[e41eaa88] | 334 | void rtems_monitor_continue_cmd( |
---|
[031deada] | 335 | int argc __attribute__((unused)), |
---|
| 336 | char **argv __attribute__((unused)), |
---|
| 337 | const rtems_monitor_command_arg_t *command_arg __attribute__((unused)), |
---|
| 338 | bool verbose __attribute__((unused)) |
---|
[b06e68ef] | 339 | ) |
---|
[ac7d5ef0] | 340 | { |
---|
[b06e68ef] | 341 | rtems_monitor_suspend(RTEMS_NO_TIMEOUT); |
---|
| 342 | } |
---|
[ac7d5ef0] | 343 | |
---|
[e41eaa88] | 344 | void rtems_monitor_node_cmd( |
---|
| 345 | int argc, |
---|
| 346 | char **argv, |
---|
[031deada] | 347 | const rtems_monitor_command_arg_t *command_arg __attribute__((unused)), |
---|
| 348 | bool verbose __attribute__((unused)) |
---|
[b06e68ef] | 349 | ) |
---|
| 350 | { |
---|
[3e08d4e] | 351 | uint32_t new_node = rtems_monitor_default_node; |
---|
[aed742c] | 352 | |
---|
[b06e68ef] | 353 | switch (argc) |
---|
[ac7d5ef0] | 354 | { |
---|
[b06e68ef] | 355 | case 1: /* no node, just set back to ours */ |
---|
| 356 | new_node = rtems_monitor_node; |
---|
| 357 | break; |
---|
[ac7d5ef0] | 358 | |
---|
[b06e68ef] | 359 | case 2: |
---|
| 360 | new_node = strtoul(argv[1], 0, 0); |
---|
| 361 | break; |
---|
[ac7d5ef0] | 362 | |
---|
[b06e68ef] | 363 | default: |
---|
[714f06c] | 364 | fprintf(stdout,"invalid syntax, try 'help node'\n"); |
---|
[b06e68ef] | 365 | break; |
---|
[ac7d5ef0] | 366 | } |
---|
[b06e68ef] | 367 | |
---|
[361457db] | 368 | #if defined(RTEMS_MULTIPROCESSING) |
---|
| 369 | if ((new_node >= 1) && |
---|
[8389628] | 370 | _Configuration_MP_table && |
---|
| 371 | (new_node <= _Configuration_MP_table->maximum_nodes)) |
---|
| 372 | rtems_monitor_default_node = new_node; |
---|
[361457db] | 373 | #endif |
---|
[ac7d5ef0] | 374 | } |
---|
| 375 | |
---|
[b06e68ef] | 376 | |
---|
[ac7d5ef0] | 377 | /* |
---|
| 378 | * Function: rtems_monitor_symbols_loadup |
---|
| 379 | * |
---|
| 380 | * Description: |
---|
| 381 | * Create and load the monitor's symbol table. |
---|
| 382 | * We are reading the output format of 'gnm' which looks like this: |
---|
| 383 | * |
---|
| 384 | * 400a7068 ? _Rate_monotonic_Information |
---|
| 385 | * 400a708c ? _Thread_Dispatch_disable_level |
---|
| 386 | * 400a7090 ? _Configuration_Table |
---|
| 387 | * |
---|
| 388 | * We ignore the type field. |
---|
| 389 | * |
---|
| 390 | * Side Effects: |
---|
| 391 | * Creates and fills in 'rtems_monitor_symbols' table |
---|
| 392 | * |
---|
[c64e4ed4] | 393 | * TODO |
---|
| 394 | * there should be a BSP #define or something like that |
---|
| 395 | * to do this; Assuming stdio is crazy. |
---|
[ac7d5ef0] | 396 | * Someday this should know BFD |
---|
| 397 | * Maybe we could get objcopy to just copy the symbol areas |
---|
| 398 | * and copy that down. |
---|
| 399 | * |
---|
| 400 | */ |
---|
| 401 | |
---|
| 402 | void |
---|
| 403 | rtems_monitor_symbols_loadup(void) |
---|
| 404 | { |
---|
| 405 | FILE *fp; |
---|
| 406 | char buffer[128]; |
---|
| 407 | |
---|
[b06e68ef] | 408 | if (rtems_monitor_symbols) |
---|
| 409 | rtems_symbol_table_destroy(rtems_monitor_symbols); |
---|
[aed742c] | 410 | |
---|
[2b643609] | 411 | rtems_monitor_symbols = rtems_symbol_table_create(); |
---|
[ac7d5ef0] | 412 | if (rtems_monitor_symbols == 0) |
---|
| 413 | return; |
---|
| 414 | |
---|
[b06e68ef] | 415 | fp = fopen("symbols", "r"); |
---|
[aed742c] | 416 | |
---|
[ac7d5ef0] | 417 | if (fp == 0) |
---|
| 418 | return; |
---|
| 419 | |
---|
| 420 | while (fgets(buffer, sizeof(buffer) - 1, fp)) |
---|
| 421 | { |
---|
| 422 | char *symbol; |
---|
| 423 | char *value; |
---|
| 424 | char *ignored_type; |
---|
| 425 | |
---|
| 426 | value = strtok(buffer, " \t\n"); |
---|
| 427 | ignored_type = strtok(0, " \t\n"); |
---|
| 428 | symbol = strtok(0, " \t\n"); |
---|
| 429 | |
---|
| 430 | if (symbol && ignored_type && value) |
---|
| 431 | { |
---|
| 432 | rtems_symbol_t *sp; |
---|
| 433 | sp = rtems_symbol_create(rtems_monitor_symbols, |
---|
| 434 | symbol, |
---|
[a5b6cdd] | 435 | (uint32_t) strtoul(value, 0, 16)); |
---|
[ac7d5ef0] | 436 | if (sp == 0) |
---|
| 437 | { |
---|
[714f06c] | 438 | fprintf(stdout,"could not define symbol '%s'\n", symbol); |
---|
[ac7d5ef0] | 439 | goto done; |
---|
| 440 | } |
---|
| 441 | } |
---|
| 442 | else |
---|
| 443 | { |
---|
[714f06c] | 444 | fprintf(stdout,"parsing error on '%s'\n", buffer); |
---|
[ac7d5ef0] | 445 | goto done; |
---|
| 446 | } |
---|
| 447 | } |
---|
| 448 | |
---|
| 449 | done: |
---|
[be95da0] | 450 | return; |
---|
[ac7d5ef0] | 451 | } |
---|
[b06e68ef] | 452 | |
---|
[32e2554] | 453 | /* |
---|
| 454 | * User registered commands. |
---|
| 455 | */ |
---|
| 456 | |
---|
| 457 | int |
---|
| 458 | rtems_monitor_insert_cmd ( |
---|
[e41eaa88] | 459 | rtems_monitor_command_entry_t *command |
---|
[32e2554] | 460 | ) |
---|
| 461 | { |
---|
[e41eaa88] | 462 | const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands; |
---|
[aed742c] | 463 | |
---|
[e41eaa88] | 464 | /* Reject empty commands */ |
---|
| 465 | if (command->command == NULL) { |
---|
[32e2554] | 466 | return 0; |
---|
[e41eaa88] | 467 | } |
---|
[2d99235e] | 468 | |
---|
[e41eaa88] | 469 | /* Reject command if already present */ |
---|
| 470 | while (e->next != NULL) { |
---|
| 471 | if (e->command != NULL && strcmp(command->command, e->command) == 0) { |
---|
| 472 | return 0; |
---|
[32e2554] | 473 | } |
---|
[e41eaa88] | 474 | e = e->next; |
---|
| 475 | } |
---|
[b06e68ef] | 476 | |
---|
[e41eaa88] | 477 | /* Prepend new command */ |
---|
| 478 | command->next = rtems_monitor_registered_commands; |
---|
| 479 | rtems_monitor_registered_commands = command; |
---|
[b06e68ef] | 480 | |
---|
[e41eaa88] | 481 | return 1; |
---|
[b06e68ef] | 482 | } |
---|
[eb961961] | 483 | |
---|
| 484 | /** |
---|
| 485 | * @brief Iterates through all registerd commands. |
---|
| 486 | * |
---|
| 487 | * For each command the interation routine @a routine is called with the |
---|
| 488 | * command entry and the user provided argument @a arg. It is guaranteed that |
---|
| 489 | * the command name and function are not NULL. |
---|
| 490 | */ |
---|
| 491 | void rtems_monitor_command_iterate( |
---|
| 492 | rtems_monitor_per_command_routine routine, |
---|
| 493 | void *arg |
---|
| 494 | ) |
---|
| 495 | { |
---|
| 496 | const rtems_monitor_command_entry_t *e = rtems_monitor_registered_commands; |
---|
| 497 | |
---|
| 498 | while (e != NULL) { |
---|
| 499 | if (e->command != NULL && e->command_function != NULL) { |
---|
| 500 | if (!routine(e, arg)) { |
---|
| 501 | break; |
---|
| 502 | } |
---|
| 503 | } |
---|
| 504 | e = e->next; |
---|
| 505 | } |
---|
| 506 | } |
---|