File indexing completed on 2025-05-11 08:24:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include <rtems.h>
0056 #include <rtems/rtems/messageimpl.h>
0057 #include <rtems/rtems/statusimpl.h>
0058 #include <rtems/score/coremsgimpl.h>
0059
0060 #include "../validation/tx-support.h"
0061
0062 #include <rtems/test.h>
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 #define MAXIMUM_PENDING_MESSAGES 2
0105 #define MAXIMUM_MESSAGE_SIZE 3
0106
0107 static void WorkerTask( rtems_task_argument argument );
0108
0109
0110
0111
0112 typedef struct {
0113
0114
0115
0116 rtems_id message_queue_id;
0117
0118
0119
0120
0121 RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
0122 storage_area[ MAXIMUM_PENDING_MESSAGES];
0123
0124
0125
0126
0127 rtems_id worker_id;
0128
0129
0130
0131
0132
0133
0134 bool is_worker_working;
0135
0136
0137
0138
0139
0140 rtems_status_code send_status;
0141 } ScoreMsgqUnitMsgq_Context;
0142
0143 static ScoreMsgqUnitMsgq_Context
0144 ScoreMsgqUnitMsgq_Instance;
0145
0146 #define EVENT_SEND RTEMS_EVENT_17
0147 #define MESSAGE_CONTENT_LOW { 1, 2, 3 }
0148 #define MESSAGE_CONTENT_HIGH { 4, 5 }
0149 #define MESSAGE_PRIORITY_LOW 5
0150 #define MESSAGE_PRIORITY_HIGH 7
0151 #define DO_WAIT true
0152
0153 typedef ScoreMsgqUnitMsgq_Context Context;
0154
0155
0156
0157
0158
0159
0160 static rtems_status_code SubmitMessage(
0161 rtems_id id,
0162 uint8_t *message,
0163 size_t message_size,
0164 unsigned int posix_piority
0165 )
0166 {
0167 rtems_status_code status;
0168 Thread_queue_Context queue_context;
0169 Message_queue_Control *the_message_queue;
0170
0171 T_assert_lt_uint( posix_piority, MQ_PRIO_MAX );
0172
0173 the_message_queue = _Message_queue_Get(
0174 id,
0175 &queue_context
0176 );
0177 T_assert_not_null( the_message_queue );
0178
0179
0180 _Thread_queue_Context_set_enqueue_callout(
0181 &queue_context,
0182 _Thread_queue_Enqueue_do_nothing_extra
0183 );
0184 _Thread_queue_Context_set_timeout_argument( &queue_context, NULL, true );
0185
0186 _CORE_message_queue_Acquire_critical(
0187 &the_message_queue->message_queue,
0188 &queue_context
0189 );
0190
0191 status = _CORE_message_queue_Submit(
0192 &the_message_queue->message_queue,
0193 _Thread_Executing,
0194 message,
0195 message_size,
0196 (CORE_message_queue_Submit_types) ( posix_piority * -1 ),
0197 DO_WAIT,
0198 &queue_context
0199 );
0200
0201 return _Status_Get( status );
0202 }
0203
0204 static rtems_status_code ReceiveMessage(
0205 rtems_id id,
0206 void *buffer,
0207 size_t *size
0208 )
0209 {
0210 return rtems_message_queue_receive(
0211 id,
0212 buffer,
0213 size,
0214 RTEMS_LOCAL | RTEMS_NO_WAIT,
0215 RTEMS_NO_TIMEOUT
0216 );
0217 }
0218
0219 static rtems_status_code ReceiveOneMessages( Context *ctx )
0220 {
0221 uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
0222 size_t message_size;
0223
0224 return ReceiveMessage(
0225 ctx->message_queue_id,
0226 &message_buffer,
0227 &message_size
0228 );
0229 }
0230
0231 static void SendMessage( Context *ctx )
0232 {
0233 uint8_t message[] = { 100, 101, 102 };
0234 ctx->send_status = SubmitMessage(
0235 ctx->message_queue_id,
0236 message,
0237 sizeof( message ),
0238 MESSAGE_PRIORITY_LOW
0239 );
0240 }
0241
0242 static void WorkerTask( rtems_task_argument argument )
0243 {
0244 Context *ctx = (Context *) argument;
0245
0246 while ( true ) {
0247 ctx->is_worker_working = false;
0248 ReceiveAnyEvents();
0249 ctx->is_worker_working = true;
0250 SendMessage( ctx );
0251 T_assert_rsc_success( ctx->send_status );
0252 }
0253 }
0254
0255 static void WorkerSendMessage( Context *ctx )
0256 {
0257 SendEvents( ctx->worker_id, EVENT_SEND );
0258 }
0259
0260 static void ScoreMsgqUnitMsgq_Setup( ScoreMsgqUnitMsgq_Context *ctx )
0261 {
0262 rtems_status_code status;
0263 rtems_message_queue_config config = {
0264 .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
0265 .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
0266 .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
0267 .storage_area = ctx->storage_area,
0268 .storage_size = sizeof( ctx->storage_area ),
0269 .storage_free = NULL,
0270 .attributes = RTEMS_DEFAULT_ATTRIBUTES
0271 };
0272
0273 status = rtems_message_queue_construct(
0274 &config,
0275 &ctx->message_queue_id
0276 );
0277 T_rsc_success( status );
0278
0279 SetSelfPriority( PRIO_NORMAL );
0280
0281 ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0282 StartTask( ctx->worker_id, WorkerTask, ctx );
0283 }
0284
0285 static void ScoreMsgqUnitMsgq_Setup_Wrap( void *arg )
0286 {
0287 ScoreMsgqUnitMsgq_Context *ctx;
0288
0289 ctx = arg;
0290 ScoreMsgqUnitMsgq_Setup( ctx );
0291 }
0292
0293 static void ScoreMsgqUnitMsgq_Teardown( ScoreMsgqUnitMsgq_Context *ctx )
0294 {
0295 DeleteTask( ctx->worker_id );
0296 RestoreRunnerPriority();
0297 T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
0298 }
0299
0300 static void ScoreMsgqUnitMsgq_Teardown_Wrap( void *arg )
0301 {
0302 ScoreMsgqUnitMsgq_Context *ctx;
0303
0304 ctx = arg;
0305 ScoreMsgqUnitMsgq_Teardown( ctx );
0306 }
0307
0308 static T_fixture ScoreMsgqUnitMsgq_Fixture = {
0309 .setup = ScoreMsgqUnitMsgq_Setup_Wrap,
0310 .stop = NULL,
0311 .teardown = ScoreMsgqUnitMsgq_Teardown_Wrap,
0312 .scope = NULL,
0313 .initial_context = &ScoreMsgqUnitMsgq_Instance
0314 };
0315
0316
0317
0318
0319
0320
0321 static void ScoreMsgqUnitMsgq_Action_0( ScoreMsgqUnitMsgq_Context *ctx )
0322 {
0323 rtems_status_code status_submit_low;
0324 rtems_status_code status_submit_high;
0325 rtems_status_code status_receive_low;
0326 rtems_status_code status_receive_high;
0327 uint8_t message_low[] = MESSAGE_CONTENT_LOW;
0328 uint8_t message_high[] = MESSAGE_CONTENT_HIGH;
0329 uint8_t message_buffer_low[ MAXIMUM_MESSAGE_SIZE ];
0330 uint8_t message_buffer_high[ MAXIMUM_MESSAGE_SIZE ];
0331 size_t message_size_low;
0332 size_t message_size_high;
0333
0334 status_submit_low = SubmitMessage(
0335 ctx->message_queue_id,
0336 message_low,
0337 sizeof( message_low ),
0338 MESSAGE_PRIORITY_LOW
0339 );
0340
0341 status_submit_high = SubmitMessage(
0342 ctx->message_queue_id,
0343 message_high,
0344 sizeof( message_high ),
0345 MESSAGE_PRIORITY_HIGH
0346 );
0347
0348 status_receive_high = ReceiveMessage(
0349 ctx->message_queue_id,
0350 &message_buffer_high,
0351 &message_size_high
0352 );
0353
0354 status_receive_low = ReceiveMessage(
0355 ctx->message_queue_id,
0356 &message_buffer_low,
0357 &message_size_low
0358 );
0359
0360
0361
0362
0363 T_rsc_success( status_submit_low );
0364 T_rsc_success( status_submit_high );
0365
0366
0367
0368
0369 T_rsc_success( status_receive_high );
0370 T_eq_sz( message_size_high, sizeof( message_high ) );
0371 T_eq_mem( message_buffer_high, message_high, message_size_high );
0372
0373 T_rsc_success( status_receive_low );
0374 T_eq_sz( message_size_low, sizeof( message_low ) );
0375 T_eq_mem( message_buffer_low, message_low, message_size_low );
0376 }
0377
0378
0379
0380
0381
0382 static void ScoreMsgqUnitMsgq_Action_1( ScoreMsgqUnitMsgq_Context *ctx )
0383 {
0384 bool is_worker_blocked_after_third_send;
0385 bool is_worker_blocked_after_first_receive;
0386
0387 WorkerSendMessage( ctx );
0388 WorkerSendMessage( ctx );
0389 WorkerSendMessage( ctx );
0390 is_worker_blocked_after_third_send = ctx->is_worker_working;
0391
0392 T_rsc_success( ReceiveOneMessages( ctx ) );
0393 is_worker_blocked_after_first_receive = ctx->is_worker_working;
0394
0395 T_rsc_success( ReceiveOneMessages( ctx ) );
0396 T_rsc_success( ReceiveOneMessages( ctx ) );
0397
0398
0399
0400
0401
0402 T_true( is_worker_blocked_after_third_send );
0403 T_true( !is_worker_blocked_after_first_receive );
0404 }
0405
0406
0407
0408
0409 static void ScoreMsgqUnitMsgq_Action_2( ScoreMsgqUnitMsgq_Context *ctx )
0410 {
0411 rtems_status_code status_send_first_message;
0412 rtems_status_code status_send_second_message;
0413 rtems_status_code status_send_third_message;
0414
0415 CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
0416 status_send_first_message = ctx->send_status;
0417 CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
0418 status_send_second_message = ctx->send_status;
0419 CallWithinISR( ( void (*)(void*) ) SendMessage, ctx );
0420 status_send_third_message = ctx->send_status;
0421
0422 T_rsc_success( ReceiveOneMessages( ctx ) );
0423 T_rsc_success( ReceiveOneMessages( ctx ) );
0424
0425
0426
0427
0428 T_assert_rsc_success( status_send_first_message );
0429 T_assert_rsc_success( status_send_second_message );
0430
0431
0432
0433
0434
0435 T_rsc( status_send_third_message, STATUS_CLASSIC_INTERNAL_ERROR );
0436 }
0437
0438
0439
0440
0441 T_TEST_CASE_FIXTURE( ScoreMsgqUnitMsgq, &ScoreMsgqUnitMsgq_Fixture )
0442 {
0443 ScoreMsgqUnitMsgq_Context *ctx;
0444
0445 ctx = T_fixture_context();
0446
0447 ScoreMsgqUnitMsgq_Action_0( ctx );
0448 ScoreMsgqUnitMsgq_Action_1( ctx );
0449 ScoreMsgqUnitMsgq_Action_2( ctx );
0450 }
0451
0452