📄 os_sem.s43
字号:
MOV #0,R12
; 204.
; 205. default:
JMP (?0090)
?0089:
; 206. OS_EXIT_CRITICAL();
EINT
; 207. *err = OS_ERR_INVALID_OPT;
MOV.B #7,0(R8)
; 208. return (pevent);
MOV R11,R12
; 209. }
?0090:
POP R8
POP R11
POP R10
RET
?0079:
; 210. }
OSSemPend:
; 211. #endif
; 212.
; 213. /*$PAGE*/
; 214. /*
; 215. *********************************************************************************************************
; 216. * PEND ON SEMAPHORE
; 217. *
; 218. * Description: This function waits for a semaphore.
; 219. *
; 220. * Arguments : pevent is a pointer to the event control block associated with the desired
; 221. * semaphore.
; 222. *
; 223. * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
; 224. * wait for the resource up to the amount of time specified by this argument.
; 225. * If you specify 0, however, your task will wait forever at the specified
; 226. * semaphore or, until the resource becomes available (or the event occurs).
; 227. *
; 228. * err is a pointer to where an error message will be deposited. Possible error
; 229. * messages are:
; 230. *
; 231. * OS_NO_ERR The call was successful and your task owns the resource
; 232. * or, the event you are waiting for occurred.
; 233. * OS_TIMEOUT The semaphore was not received within the specified
; 234. * timeout.
; 235. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
; 236. * OS_ERR_PEND_ISR If you called this function from an ISR and the result
; 237. * would lead to a suspension.
; 238. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
; 239. *
; 240. * Returns : none
; 241. *********************************************************************************************************
; 242. */
; 243.
; 244. void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
; 245. {
PUSH R10
PUSH R11
MOV R12,R10
MOV 6(SP),R11
; 246. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 247. OS_CPU_SR cpu_sr;
; 248. #endif
; 249.
; 250.
; 251. if (OSIntNesting > 0) { /* See if called from ISR ... */
CMP.B #0,&OSIntNesting
JEQ (?0092)
; 252. *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
MOV.B #2,0(R11)
; 253. return;
; 254. }
JMP (?0101)
?0092:
; 255. #if OS_ARG_CHK_EN > 0
; 256. if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
CMP #0,R10
JNE (?0094)
; 257. *err = OS_ERR_PEVENT_NULL;
MOV.B #4,0(R11)
; 258. return;
; 259. }
JMP (?0101)
?0094:
; 260. if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
MOV.B #3,R12
CMP.B @R10,R12
JEQ (?0096)
; 261. *err = OS_ERR_EVENT_TYPE;
MOV.B #1,0(R11)
; 262. return;
; 263. }
JMP (?0101)
?0096:
; 264. #endif
; 265. OS_ENTER_CRITICAL();
DINT
; 266. if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
CMP #0,2(R10)
JEQ (?0098)
; 267. pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
ADD #-1,2(R10)
; 268. OS_EXIT_CRITICAL();
EINT
; 269. *err = OS_NO_ERR;
MOV.B #0,0(R11)
; 270. return;
; 271. }
JMP (?0101)
?0098:
; 272. /* Otherwise, must wait until event occurs */
; 273. OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
MOV &OSTCBCur,R12
BIS.B #1,28(R12)
; 274. OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
MOV &OSTCBCur,R12
MOV R14,26(R12)
; 275. OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
MOV R10,R12
CALL #OS_EventTaskWait
; 276. OS_EXIT_CRITICAL();
EINT
; 277. OS_Sched(); /* Find next highest priority task ready */
CALL #OS_Sched
; 278. OS_ENTER_CRITICAL();
DINT
; 279. if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { /* Must have timed out if still waiting for event*/
MOV &OSTCBCur,R12
BIT.B #1,28(R12)
JEQ (?0100)
; 280. OS_EventTO(pevent);
MOV R10,R12
CALL #OS_EventTO
; 281. OS_EXIT_CRITICAL();
EINT
; 282. *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */
MOV.B #10,0(R11)
; 283. return;
; 284. }
JMP (?0101)
?0100:
; 285. OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
MOV &OSTCBCur,R12
MOV #0,18(R12)
; 286. OS_EXIT_CRITICAL();
EINT
; 287. *err = OS_NO_ERR;
MOV.B #0,0(R11)
; 288. }
?0101:
POP R11
POP R10
RET
OSSemPost:
; 289. /*$PAGE*/
; 290. /*
; 291. *********************************************************************************************************
; 292. * POST TO A SEMAPHORE
; 293. *
; 294. * Description: This function signals a semaphore
; 295. *
; 296. * Arguments : pevent is a pointer to the event control block associated with the desired
; 297. * semaphore.
; 298. *
; 299. * Returns : OS_NO_ERR The call was successful and the semaphore was signaled.
; 300. * OS_SEM_OVF If the semaphore count exceeded its limit. In other words, you have
; 301. * signalled the semaphore more often than you waited on it with either
; 302. * OSSemAccept() or OSSemPend().
; 303. * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
; 304. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
; 305. *********************************************************************************************************
; 306. */
; 307.
; 308. INT8U OSSemPost (OS_EVENT *pevent)
; 309. {
; 310. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 311. OS_CPU_SR cpu_sr;
; 312. #endif
; 313.
; 314.
; 315. #if OS_ARG_CHK_EN > 0
; 316. if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
CMP #0,R12
JNE (?0103)
; 317. return (OS_ERR_PEVENT_NULL);
MOV.B #4,R12
; 318. }
RET
?0103:
; 319. if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
MOV.B #3,R13
CMP.B @R12,R13
JEQ (?0105)
; 320. return (OS_ERR_EVENT_TYPE);
MOV.B #1,R12
; 321. }
RET
?0105:
; 322. #endif
; 323. OS_ENTER_CRITICAL();
DINT
; 324. if (pevent->OSEventGrp != 0x00) { /* See if any task waiting for semaphore */
CMP.B #0,1(R12)
JEQ (?0107)
; 325. OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready highest prio task waiting on event */
PUSH.B #1
MOV #0,R14
CALL #OS_EventTaskRdy
ADD #2,SP
; 326. OS_EXIT_CRITICAL();
EINT
; 327. OS_Sched(); /* Find highest priority task ready to run */
CALL #OS_Sched
; 328. return (OS_NO_ERR);
MOV.B #0,R12
; 329. }
RET
?0107:
; 330. if (pevent->OSEventCnt < 65535) { /* Make sure semaphore will not overflow */
CMP #65535,2(R12)
JC (?0109)
; 331. pevent->OSEventCnt++; /* Increment semaphore count to register event */
ADD #1,2(R12)
; 332. OS_EXIT_CRITICAL();
EINT
; 333. return (OS_NO_ERR);
MOV.B #0,R12
; 334. }
RET
?0109:
; 335. OS_EXIT_CRITICAL(); /* Semaphore value has reached its maximum */
EINT
; 336. return (OS_SEM_OVF);
MOV.B #50,R12
; 337. }
RET
OSSemQuery:
; 338. /*$PAGE*/
; 339. /*
; 340. *********************************************************************************************************
; 341. * QUERY A SEMAPHORE
; 342. *
; 343. * Description: This function obtains information about a semaphore
; 344. *
; 345. * Arguments : pevent is a pointer to the event control block associated with the desired
; 346. * semaphore
; 347. *
; 348. * pdata is a pointer to a structure that will contain information about the
; 349. * semaphore.
; 350. *
; 351. * Returns : OS_NO_ERR The call was successful and the message was sent
; 352. * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore.
; 353. * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
; 354. *********************************************************************************************************
; 355. */
; 356.
; 357. #if OS_SEM_QUERY_EN > 0
; 358. INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
; 359. {
; 360. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 361. OS_CPU_SR cpu_sr;
; 362. #endif
; 363. INT8U *psrc;
; 364. INT8U *pdest;
; 365.
; 366.
; 367. #if OS_ARG_CHK_EN > 0
; 368. if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
CMP #0,R12
JNE (?0112)
; 369. return (OS_ERR_PEVENT_NULL);
MOV.B #4,R12
; 370. }
RET
?0112:
; 371. if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
MOV.B #3,R13
CMP.B @R12,R13
JEQ (?0114)
; 372. return (OS_ERR_EVENT_TYPE);
MOV.B #1,R12
; 373. }
RET
?0114:
; 374. #endif
; 375. OS_ENTER_CRITICAL();
DINT
; 376. pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
MOV.B 1(R12),4(R14)
; 377. psrc = &pevent->OSEventTbl[0];
MOV R12,R15
ADD #6,R15
; 378. pdest = &pdata->OSEventTbl[0];
MOV R14,R13
ADD #2,R13
; 379. #if OS_EVENT_TBL_SIZE > 0
; 380. *pdest++ = *psrc++;
MOV.B @R15+,0(R13)
ADD #1,R13
; 381. #endif
; 382.
; 383. #if OS_EVENT_TBL_SIZE > 1
; 384. *pdest++ = *psrc++;
MOV.B @R15+,0(R13)
; 385. #endif
; 386.
; 387. #if OS_EVENT_TBL_SIZE > 2
; 388. *pdest++ = *psrc++;
; 389. #endif
; 390.
; 391. #if OS_EVENT_TBL_SIZE > 3
; 392. *pdest++ = *psrc++;
; 393. #endif
; 394.
; 395. #if OS_EVENT_TBL_SIZE > 4
; 396. *pdest++ = *psrc++;
; 397. #endif
; 398.
; 399. #if OS_EVENT_TBL_SIZE > 5
; 400. *pdest++ = *psrc++;
; 401. #endif
; 402.
; 403. #if OS_EVENT_TBL_SIZE > 6
; 404. *pdest++ = *psrc++;
; 405. #endif
; 406.
; 407. #if OS_EVENT_TBL_SIZE > 7
; 408. *pdest = *psrc;
; 409. #endif
; 410. pdata->OSCnt = pevent->OSEventCnt; /* Get semaphore count */
MOV 2(R12),0(R14)
; 411. OS_EXIT_CRITICAL();
EINT
; 412. return (OS_NO_ERR);
MOV.B #0,R12
; 413. }
RET
; 414. #endif /* OS_SEM_QUERY_EN */
; 415. #endif /* OS_SEM_EN */
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -