📄 os_q.s43
字号:
EINT
; 362. OS_Sched(); /* Find next highest priority task ready to run */
CALL #OS_Sched
; 363. OS_ENTER_CRITICAL();
DINT
; 364. msg = OSTCBCur->OSTCBMsg;
MOV &OSTCBCur,R13
MOV 20(R13),R12
; 365. if (msg != (void *)0) { /* Did we get a message? */
CMP #0,R12
JEQ (?0115)
; 366. OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
MOV &OSTCBCur,R13
MOV #0,20(R13)
; 367. OSTCBCur->OSTCBStat = OS_STAT_RDY;
MOV &OSTCBCur,R13
MOV.B #0,28(R13)
; 368. OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
MOV &OSTCBCur,R13
MOV #0,18(R13)
; 369. OS_EXIT_CRITICAL();
EINT
; 370. *err = OS_NO_ERR;
MOV.B #0,0(R11)
; 371. return (msg); /* Return message received */
; 372. }
JMP (?0116)
?0115:
; 373. OS_EventTO(pevent); /* Timed out */
MOV R10,R12
CALL #OS_EventTO
; 374. OS_EXIT_CRITICAL();
EINT
; 375. *err = OS_TIMEOUT; /* Indicate a timeout occured */
MOV.B #10,0(R11)
; 376. return ((void *)0); /* No message received */
MOV #0,R12
; 377. }
?0116:
POP R11
POP R10
RET
OSQPost:
; 378. /*$PAGE*/
; 379. /*
; 380. *********************************************************************************************************
; 381. * POST MESSAGE TO A QUEUE
; 382. *
; 383. * Description: This function sends a message to a queue
; 384. *
; 385. * Arguments : pevent is a pointer to the event control block associated with the desired queue
; 386. *
; 387. * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; 388. *
; 389. * Returns : OS_NO_ERR The call was successful and the message was sent
; 390. * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; 391. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; 392. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; 393. * OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
; 394. *********************************************************************************************************
; 395. */
; 396.
; 397. #if OS_Q_POST_EN > 0
; 398. INT8U OSQPost (OS_EVENT *pevent, void *msg)
; 399. {
; 400. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 401. OS_CPU_SR cpu_sr;
; 402. #endif
; 403. OS_Q *pq;
; 404.
; 405.
; 406. #if OS_ARG_CHK_EN > 0
; 407. if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
CMP #0,R12
JNE (?0118)
; 408. return (OS_ERR_PEVENT_NULL);
MOV.B #4,R12
; 409. }
RET
?0118:
; 410. if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */
CMP #0,R14
JNE (?0120)
; 411. return (OS_ERR_POST_NULL_PTR);
MOV.B #3,R12
; 412. }
RET
?0120:
; 413. if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
MOV.B #2,R13
CMP.B @R12,R13
JEQ (?0122)
; 414. return (OS_ERR_EVENT_TYPE);
MOV.B #1,R12
; 415. }
RET
?0122:
; 416. #endif
; 417. OS_ENTER_CRITICAL();
DINT
; 418. if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */
CMP.B #0,1(R12)
JEQ (?0124)
; 419. OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
PUSH.B #4
CALL #OS_EventTaskRdy
ADD #2,SP
; 420. OS_EXIT_CRITICAL();
EINT
; 421. OS_Sched(); /* Find highest priority task ready to run */
CALL #OS_Sched
; 422. return (OS_NO_ERR);
MOV.B #0,R12
; 423. }
RET
?0124:
; 424. pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
MOV 4(R12),R13
; 425. if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
CMP 10(R13),12(R13)
JNC (?0126)
; 426. OS_EXIT_CRITICAL();
EINT
; 427. return (OS_Q_FULL);
MOV.B #30,R12
; 428. }
RET
?0126:
; 429. *pq->OSQIn++ = msg; /* Insert message into queue */
MOV 6(R13),R12
ADD #2,6(R13)
MOV R14,0(R12)
; 430. pq->OSQEntries++; /* Update the nbr of entries in the queue */
ADD #1,12(R13)
; 431. if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
CMP 6(R13),4(R13)
JNE (?0128)
; 432. pq->OSQIn = pq->OSQStart;
MOV 2(R13),6(R13)
?0128:
; 433. }
; 434. OS_EXIT_CRITICAL();
EINT
; 435. return (OS_NO_ERR);
MOV.B #0,R12
; 436. }
RET
OSQPostFront:
; 437. #endif
; 438. /*$PAGE*/
; 439. /*
; 440. *********************************************************************************************************
; 441. * POST MESSAGE TO THE FRONT OF A QUEUE
; 442. *
; 443. * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
; 444. * the front instead of the end of the queue. Using OSQPostFront() allows you to send
; 445. * 'priority' messages.
; 446. *
; 447. * Arguments : pevent is a pointer to the event control block associated with the desired queue
; 448. *
; 449. * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; 450. *
; 451. * Returns : OS_NO_ERR The call was successful and the message was sent
; 452. * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; 453. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; 454. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; 455. * OS_ERR_POST_NULL_PTR If you are attempting to post to a non queue.
; 456. *********************************************************************************************************
; 457. */
; 458.
; 459. #if OS_Q_POST_FRONT_EN > 0
; 460. INT8U OSQPostFront (OS_EVENT *pevent, void *msg)
; 461. {
; 462. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 463. OS_CPU_SR cpu_sr;
; 464. #endif
; 465. OS_Q *pq;
; 466.
; 467.
; 468. #if OS_ARG_CHK_EN > 0
; 469. if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
CMP #0,R12
JNE (?0131)
; 470. return (OS_ERR_PEVENT_NULL);
MOV.B #4,R12
; 471. }
RET
?0131:
; 472. if (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */
CMP #0,R14
JNE (?0133)
; 473. return (OS_ERR_POST_NULL_PTR);
MOV.B #3,R12
; 474. }
RET
?0133:
; 475. if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
MOV.B #2,R13
CMP.B @R12,R13
JEQ (?0135)
; 476. return (OS_ERR_EVENT_TYPE);
MOV.B #1,R12
; 477. }
RET
?0135:
; 478. #endif
; 479. OS_ENTER_CRITICAL();
DINT
; 480. if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */
CMP.B #0,1(R12)
JEQ (?0137)
; 481. OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
PUSH.B #4
CALL #OS_EventTaskRdy
ADD #2,SP
; 482. OS_EXIT_CRITICAL();
EINT
; 483. OS_Sched(); /* Find highest priority task ready to run */
CALL #OS_Sched
; 484. return (OS_NO_ERR);
MOV.B #0,R12
; 485. }
RET
?0137:
; 486. pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
MOV 4(R12),R13
; 487. if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
CMP 10(R13),12(R13)
JNC (?0139)
; 488. OS_EXIT_CRITICAL();
EINT
; 489. return (OS_Q_FULL);
MOV.B #30,R12
; 490. }
RET
?0139:
; 491. if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */
CMP 8(R13),2(R13)
JNE (?0141)
; 492. pq->OSQOut = pq->OSQEnd;
MOV 4(R13),8(R13)
?0141:
; 493. }
; 494. pq->OSQOut--;
ADD #-2,8(R13)
; 495. *pq->OSQOut = msg; /* Insert message into queue */
MOV 8(R13),R12
MOV R14,0(R12)
; 496. pq->OSQEntries++; /* Update the nbr of entries in the queue */
ADD #1,12(R13)
; 497. OS_EXIT_CRITICAL();
EINT
; 498. return (OS_NO_ERR);
MOV.B #0,R12
; 499. }
RET
OSQPostOpt:
; 500. #endif
; 501. /*$PAGE*/
; 502. /*
; 503. *********************************************************************************************************
; 504. * POST MESSAGE TO A QUEUE
; 505. *
; 506. * Description: This function sends a message to a queue. This call has been added to reduce code size
; 507. * since it can replace both OSQPost() and OSQPostFront(). Also, this function adds the
; 508. * capability to broadcast a message to ALL tasks waiting on the message queue.
; 509. *
; 510. * Arguments : pevent is a pointer to the event control block associated with the desired queue
; 511. *
; 512. * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; 513. *
; 514. * opt determines the type of POST performed:
; 515. * OS_POST_OPT_NONE POST to a single waiting task
; 516. * (Identical to OSQPost())
; 517. * OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the queue
; 518. * OS_POST_OPT_FRONT POST as LIFO (Simulates OSQPostFront())
; 519. *
; 520. * Below is a list of ALL the possible combination of these flags:
; 521. *
; 522. * 1) OS_POST_OPT_NONE
; 523. * identical to OSQPost()
; 524. *
; 525. * 2) OS_POST_OPT_FRONT
; 526. * identical to OSQPostFront()
; 527. *
; 528. * 3) OS_POST_OPT_BROADCAST
; 529. * identical to OSQPost() but will broadcast 'msg' to ALL waiting tasks
; 530. *
; 531. * 4) OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST is identical to
; 532. * OSQPostFront() except that will broadcast 'msg' to ALL waiting tasks
; 533. *
; 534. * Returns : OS_NO_ERR The call was successful and the message was sent
; 535. * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; 536. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; 537. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; 538. * OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
; 539. *
; 540. * Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
; 541. * interrupt disable time is proportional to the number of tasks waiting on the queue.
; 542. *********************************************************************************************************
; 543. */
; 544.
; 545. #if OS_Q_POST_OPT_EN > 0
; 546. INT8U OSQPostOpt (OS_EVENT *pevent, void *msg, INT8U opt)
; 547. {
PUSH R10
PUSH R11
MOV R12,R11
MOV R14,R10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -