mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-10-06 10:59:48 +08:00
The briefs of the libmisc files named a topic, not the content of the file. Four shell briefs named the wrong command. The file main_blksync.c said "RM Shell Command Implementation". The files main_id.c, main_time.c and shellconfig.c named ls and debugrfs. Four string conversion sources named the conversion, for example "Convert String to Unsigned Long". Write every brief in the style of the tree. A source brief starts with "This source file contains". A command brief names the command the file provides. A header brief starts with "This header file provides". Put @file, @ingroup and @brief in this order in every block. Updates #5717. Assisted-by: Claude:claude-opus-5 claude-code Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
341 lines
9.0 KiB
C
341 lines
9.0 KiB
C
/* SPDX-License-Identifier: BSD-2-Clause */
|
|
|
|
/**
|
|
* @file
|
|
*
|
|
* @ingroup RTEMSImplMonitor
|
|
*
|
|
* @brief This source file contains the server of the monitor.
|
|
*
|
|
* This handles requests for info from RTEMS monitors running on
|
|
* other nodes.
|
|
*/
|
|
|
|
/*
|
|
* COPYRIGHT (c) 1989-2022. On-Line Applications Research Corporation (OAR).
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <rtems.h>
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
#include <rtems/monitor.h>
|
|
#include <rtems/score/sysstate.h>
|
|
|
|
/*
|
|
* Various id's for the server
|
|
*/
|
|
|
|
rtems_id rtems_monitor_server_task_id;
|
|
rtems_id rtems_monitor_server_request_queue_id; /* our server */
|
|
rtems_id *rtems_monitor_server_request_queue_ids; /* all servers */
|
|
rtems_id rtems_monitor_server_response_queue_id; /* our server */
|
|
|
|
/*
|
|
* Send a request to a server task
|
|
*/
|
|
|
|
rtems_status_code rtems_monitor_server_request(
|
|
uint32_t server_node,
|
|
rtems_monitor_server_request_t *request,
|
|
rtems_monitor_server_response_t *response
|
|
)
|
|
{
|
|
rtems_id server_id;
|
|
rtems_status_code status;
|
|
size_t size;
|
|
|
|
/*
|
|
* What is id of monitor on target node?
|
|
* Look it up if we don't know it yet.
|
|
*/
|
|
|
|
server_id = rtems_monitor_server_request_queue_ids[ server_node ];
|
|
if ( server_id == 0 ) {
|
|
status = rtems_message_queue_ident(
|
|
RTEMS_MONITOR_QUEUE_NAME,
|
|
server_node,
|
|
&server_id
|
|
);
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "ident of remote server failed" );
|
|
goto done;
|
|
}
|
|
|
|
rtems_monitor_server_request_queue_ids[ server_node ] = server_id;
|
|
}
|
|
|
|
request->return_id = rtems_monitor_server_response_queue_id;
|
|
|
|
status = rtems_message_queue_send( server_id, request, sizeof( *request ) );
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "monitor server request send failed" );
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Await response, if requested
|
|
*/
|
|
|
|
if ( response ) {
|
|
status = rtems_message_queue_receive(
|
|
rtems_monitor_server_response_queue_id,
|
|
response,
|
|
&size,
|
|
RTEMS_WAIT,
|
|
100
|
|
);
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "server did not respond" );
|
|
|
|
/* maybe server task was restarted; look it up again next time */
|
|
rtems_monitor_server_request_queue_ids[ server_node ] = 0;
|
|
|
|
goto done;
|
|
}
|
|
|
|
if ( response->command != RTEMS_MONITOR_SERVER_RESPONSE ) {
|
|
status = RTEMS_INCORRECT_STATE;
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
done:
|
|
return status;
|
|
}
|
|
|
|
/*
|
|
* monitor server task
|
|
*/
|
|
|
|
void rtems_monitor_server_task(
|
|
rtems_task_argument monitor_flags RTEMS_UNUSED
|
|
)
|
|
{
|
|
rtems_monitor_server_request_t request;
|
|
rtems_monitor_server_response_t response;
|
|
rtems_status_code status;
|
|
size_t size;
|
|
|
|
for ( ;; ) {
|
|
status = rtems_message_queue_receive(
|
|
rtems_monitor_server_request_queue_id,
|
|
&request,
|
|
&size,
|
|
RTEMS_WAIT,
|
|
(rtems_interval) 0
|
|
);
|
|
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "monitor server msg queue receive error" );
|
|
goto failed;
|
|
}
|
|
|
|
if ( size != sizeof( request ) ) {
|
|
rtems_error( 0, "monitor server bad size on receive" );
|
|
goto failed;
|
|
}
|
|
|
|
switch ( request.command ) {
|
|
case RTEMS_MONITOR_SERVER_CANONICAL: {
|
|
rtems_monitor_object_type_t object_type;
|
|
rtems_id id;
|
|
rtems_id next_id;
|
|
|
|
object_type = (rtems_monitor_object_type_t) request.argument0;
|
|
id = (rtems_id) request.argument1;
|
|
next_id = rtems_monitor_object_canonical_get(
|
|
object_type,
|
|
id,
|
|
&response.payload,
|
|
&size
|
|
);
|
|
|
|
response.command = RTEMS_MONITOR_SERVER_RESPONSE;
|
|
response.result0 = next_id;
|
|
response.result1 = size;
|
|
|
|
#define SERVER_OVERHEAD \
|
|
( offsetof( rtems_monitor_server_response_t, payload ) )
|
|
|
|
status = rtems_message_queue_send(
|
|
request.return_id,
|
|
&response,
|
|
size + SERVER_OVERHEAD
|
|
);
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "response send failed" );
|
|
goto failed;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
rtems_error(
|
|
0,
|
|
"invalid command to monitor server: %d",
|
|
request.command
|
|
);
|
|
goto failed;
|
|
}
|
|
}
|
|
}
|
|
|
|
failed:
|
|
rtems_task_exit();
|
|
}
|
|
|
|
/*
|
|
* Kill off any old server
|
|
* Not sure if this is useful, but it doesn't help
|
|
*/
|
|
|
|
void rtems_monitor_server_kill( void )
|
|
{
|
|
if ( rtems_monitor_server_task_id ) {
|
|
rtems_task_delete( rtems_monitor_server_task_id );
|
|
}
|
|
rtems_monitor_server_task_id = 0;
|
|
|
|
if ( rtems_monitor_server_request_queue_id ) {
|
|
rtems_message_queue_delete( rtems_monitor_server_request_queue_id );
|
|
}
|
|
rtems_monitor_server_request_queue_ids = 0;
|
|
|
|
if ( rtems_monitor_server_response_queue_id ) {
|
|
rtems_message_queue_delete( rtems_monitor_server_response_queue_id );
|
|
}
|
|
rtems_monitor_server_response_queue_id = 0;
|
|
|
|
if ( rtems_monitor_server_request_queue_ids ) {
|
|
free( rtems_monitor_server_request_queue_ids );
|
|
}
|
|
rtems_monitor_server_request_queue_ids = 0;
|
|
}
|
|
|
|
void rtems_monitor_server_init( uint32_t monitor_flags RTEMS_UNUSED )
|
|
{
|
|
#if defined( RTEMS_MULTIPROCESSING )
|
|
rtems_status_code status;
|
|
|
|
if (
|
|
_System_state_Is_multiprocessing &&
|
|
( _MPCI_Configuration.maximum_nodes > 1 )
|
|
) {
|
|
uint32_t maximum_nodes = _MPCI_Configuration.maximum_nodes;
|
|
|
|
/*
|
|
* create the msg que our server will listen
|
|
* Since we only get msgs from other RTEMS monitors, we just
|
|
* need reserve space for 1 msg from each node.
|
|
*/
|
|
|
|
status = rtems_message_queue_create(
|
|
RTEMS_MONITOR_QUEUE_NAME,
|
|
maximum_nodes,
|
|
sizeof( rtems_monitor_server_request_t ),
|
|
RTEMS_GLOBAL,
|
|
&rtems_monitor_server_request_queue_id
|
|
);
|
|
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "could not create monitor server message queue" );
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* create the msg que our responses will come on
|
|
* Since monitor just does one thing at a time, we only need 1 item
|
|
* message queue.
|
|
*/
|
|
|
|
status = rtems_message_queue_create(
|
|
RTEMS_MONITOR_RESPONSE_QUEUE_NAME,
|
|
1, /* depth */
|
|
sizeof( rtems_monitor_server_response_t ),
|
|
RTEMS_GLOBAL,
|
|
&rtems_monitor_server_response_queue_id
|
|
);
|
|
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "could not create monitor response message queue" );
|
|
goto done;
|
|
}
|
|
|
|
/* need an id for queue of each other server we might talk to */
|
|
/* indexed by node, so add 1 to maximum_nodes */
|
|
rtems_monitor_server_request_queue_ids = (rtems_id *) malloc(
|
|
( maximum_nodes + 1 ) * sizeof( rtems_id )
|
|
);
|
|
(void) memset(
|
|
rtems_monitor_server_request_queue_ids,
|
|
0,
|
|
( maximum_nodes + 1 ) * sizeof( rtems_id )
|
|
);
|
|
|
|
rtems_monitor_server_request_queue_ids[ rtems_monitor_node ] =
|
|
rtems_monitor_server_request_queue_id;
|
|
|
|
/*
|
|
* create the server task
|
|
*/
|
|
status = rtems_task_create(
|
|
RTEMS_MONITOR_SERVER_NAME,
|
|
1,
|
|
0 /* default stack */,
|
|
RTEMS_INTERRUPT_LEVEL( 0 ),
|
|
RTEMS_DEFAULT_ATTRIBUTES,
|
|
&rtems_monitor_server_task_id
|
|
);
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "could not create monitor server task" );
|
|
goto done;
|
|
}
|
|
|
|
/*
|
|
* Start the server task
|
|
*/
|
|
status = rtems_task_start(
|
|
rtems_monitor_server_task_id,
|
|
rtems_monitor_server_task,
|
|
monitor_flags
|
|
);
|
|
if ( status != RTEMS_SUCCESSFUL ) {
|
|
rtems_error( status, "could not start monitor server" );
|
|
goto done;
|
|
}
|
|
}
|
|
|
|
done:
|
|
#endif
|
|
return;
|
|
}
|