?? hcanap_1.inc
字號:
$EJECT
;=======================================================================
;
; INCLUDE FILE DES MODULS HCANAPIF.A51
;
;=======================================================================
;*---------------------------------------------------------------------*
;* C _ E N T E R _ D R I V E R
;*---------------------------------------------------------------------*
;* Funktion:
;*
;* Diese Prozedur regelt den Zutritt zum CAN-Treiber.
;*
;* VAR
;* I : BYTE; (* In Register halten -> reentrant *)
;*
;* (* Diese Routine wird in Assembler implementiert und muss reentrant sein *)
;* BEGIN
;* Alle Interrupts sperren;
;* WHILE C_DRIVER_IN_USE DO
;* (* Der CAN-Treiber ist schon besetzt *)
;* (* Die Parameter aus den Registern m乻sen gesichert werden *)
;* IF NOT(C_TEMP_ORDER_BUF[0].OCCUPIED) THEN
;* I := 0;
;* ELSIF NOT(C_TEMP_ORDER_BUF[1].OCCUPIED) THEN
;* I := 1;
;* ELSIF NOT(C_TEMP_ORDER_BUF[2].OCCUPIED) THEN
;* I := 2;
;* ELSE
;* Alle Interrupts freigeben;
;* RETURN FALSE;
;* END IF;
;* (* Es wurde ein freier tempor剅er Buffer gefunden *)
;* C_TEMP_ORDER_BUF[I].OCCUPIED := TRUE;
;*
;* (* R3 bis R7 in C_TEMP_ORDER_BUF[I].DATA kopieren;
;* C_TEMP_ORDER_BUF[I].DATA[0] := R3;
;* ..
;* ..
;* C_TEMP_ORDER_BUF[I].DATA[4] := R7;
;* PUSH(I);
;* C_TEMP_ORDER_BUF[I].TASK_ID := os_get_running_task_id();
;*
;* WHILE C_DRIVER_IN_USE DO
;* Alle Interrupts freigeben;
;* os_wait (K_SIG,0xff,0);
;* Alle Interrupts sperren;
;* END;
;* Alle Interrupts freigeben;
;* POP(I);
;* os_clear_signal (C_TEMP_ORDER_BUF[I].TASK_ID);
;* (* C_TEMP_ORDER_BUF[I].DATA in R3 bis R7 kopieren *)
;* R3 := C_TEMP_ORDER_BUF[I].DATA[0];
;* ..
;* R7 := C_TEMP_ORDER_BUF[I].DATA[4];
;*
;* Alle Interrupts sperren;
;* C_TEMP_ORDER_BUF.OCCUPIED := FALSE;
;* END WHILE;
;* C_DRIVER_IN_USE := TRUE;
;* Alle Interrupts freigeben;
;* RETURN TRUE;
;* END C_ENTER_DRIVER;
;*
;*---------------------------------------------------------------------*
;* Parameter:
;*
;* Returnwert im AKKU :
;* TRUE --> Alles OK, Task darf CAN-Treiber benutzen
;* FALSE --> Fehlfunktion, zuviele Tasks warten
;* (Fatal-Error)
;*
;*---------------------------------------------------------------------*/
?CAN?C_ENTER_DRIVER?HCANAPIF SEGMENT CODE
RSEG ?CAN?C_ENTER_DRIVER?HCANAPIF
C_ENTER_DRIVER: CLR EA ; Alle Interrupts sperren
; WHILE C_DRIVER_IN_USE DO;
CE_WHILE: JB C_DRIVER_IN_USE, CE_1
JMP CE_WHILE_END
CE_1: ; freien Buffer suchen und Register R3 bis R7 sichern
MOV DPTR, #C_TEMP_BUF_0_OCC
MOVX A, @DPTR
CJNE A,#FALSE, CE_IF1
; Buffer 0
MOV R0, #0 ; Den verwendeten Buffer merken
MOV A, #TRUE ; Buffer reservieren
MOVX @DPTR, A
; Register R3 bis R7 sichern
STORE_REGS C_TEMP_BUF_0_DATA
MOV A, R0
PUSH ACC ; Buffer Index retten
CALL os_running_task_id
MOV A, R7
MOV DPTR, #C_TEMP_BUF_0_ID
MOVX @DPTR, A ; RUNNING_TASK_ID abspeichern
SETB EA ; Interrupts freigeben
JMP CE_IF_END
CE_IF1: MOV DPTR, #C_TEMP_BUF_1_OCC
MOVX A, @DPTR
CJNE A, #FALSE, CE_IF2
; Buffer 1
MOV R0, #1 ; Den verwendeten Buffer merken
MOV A, #TRUE ; Buffer reservieren
MOVX @DPTR, A
; Register R3 bis R7 sichern
STORE_REGS C_TEMP_BUF_1_DATA
MOV A, R0
PUSH ACC ; Buffer Index retten
CALL os_running_task_id
MOV A, R7
MOV DPTR, #C_TEMP_BUF_1_ID
MOVX @DPTR, A ; RUNNING_TASK_ID abspeichern
SETB EA ; Interrupts freigeben
JMP CE_IF_END
CE_IF2: MOV DPTR, #C_TEMP_BUF_2_OCC
MOVX A, @DPTR
CJNE A, #FALSE, CE_ELSE1
; Buffer 2
MOV R0, #2 ; Den verwendeten Buffer merken
MOV A, #TRUE ; Buffer reservieren
MOVX @DPTR,A
; Register R3 bis R7 sichern
STORE_REGS C_TEMP_BUF_2_DATA
MOV A, R0
PUSH ACC ; Buffer Index retten
CALL os_running_task_id
MOV A, R7
MOV DPTR, #C_TEMP_BUF_2_ID
MOVX @DPTR, A ; RUNNING_TASK_ID abspeichern
SETB EA ; Interrupts freigeben
JMP CE_IF_END
CE_ELSE1: ; Keinen Buffer gefunden --> Fatal Error
SETB EA ; Interrupts freigeben
MOV A,#FALSE
RET
CE_IF_END: ; Register gerettet, nun auf Signal warten, bis
; CAN-Treiber frei ist
CLR EA ; Alle Interrupts sperren
CE_W: JNB C_DRIVER_IN_USE, CE_E_W
SETB EA ; Interrupts freigeben
MOV R7, #K_SIG ; warten auf Signal
CALL _os_wait
CLR EA ; Alle Interrupts sperren
JMP CE_W
CE_E_W: SETB EA ; Interrupts freigeben
POP ACC
MOV R0,A
; Register aus dem verwendeten Buffer zur乧kladen
CJNE R0,#0,CE_B1
MOV DPTR, #C_TEMP_BUF_0_ID
MOVX A, @DPTR
MOV R7, A
CALL _os_clear_signal
RESTORE_REGS C_TEMP_BUF_0_DATA
MOV DPTR, #C_TEMP_BUF_0_OCC
MOV A, #FALSE
CLR EA
MOVX @DPTR, A
JMP CE_2
CE_B1: CJNE R0,#1,CE_B2
MOV DPTR, #C_TEMP_BUF_1_ID
MOVX A, @DPTR
MOV R7, A
CALL _os_clear_signal
RESTORE_REGS C_TEMP_BUF_1_DATA
MOV DPTR, #C_TEMP_BUF_1_OCC
MOV A, #FALSE
CLR EA
MOVX @DPTR, A
JMP CE_2
CE_B2: MOV DPTR, #C_TEMP_BUF_2_ID
MOVX A, @DPTR
MOV R7, A
CALL _os_clear_signal
RESTORE_REGS C_TEMP_BUF_2_DATA
MOV DPTR, #C_TEMP_BUF_2_OCC
MOV A, #FALSE
CLR EA
MOVX @DPTR, A
CE_2: JMP CE_WHILE
; END WHILE
CE_WHILE_END: ; Der CAN-Treiber darf benutzt werden
SETB C_DRIVER_IN_USE
SETB EA ; Interrupts freigeben
MOV A,#TRUE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C _ L E A V E _ D R I V E R
;*---------------------------------------------------------------------*
;* Funktion:
;*
;* Mit dieser Funktion wird der CAN-Treiber wieder freigegeben.
;*
;* (* Diese Routine wird in Assembler implementiert und muss reentrant sein *)
;* BEGIN
;* Alle Interrupts sperren;
;* C_DRIVER_IN_USE := FALSE;
;*
;* (* Wartenden Task suchen und starten *)
;* IF C_TEMP_ORDER_BUF[0].OCCUPIED THEN
;* Alle Interrupts freigeben;
;* os_send_signal (C_TEMP_ORDER_BUF[0].TASK_ID);
;* ELSIF C_TEMP_ORDER_BUF[1].OCCUPIED THEN
;* Alle Interrupts freigeben;
;* os_send_signal (C_TEMP_ORDER_BUF[1].TASK_ID);
;* ELSIF C_TEMP_ORDER_BUF[2].OCCUPIED THEN
;* Alle Interrupts freigeben;
;* os_send_signal (C_TEMP_ORDER_BUF[2].TASK_ID);
;* END IF;
;* Alle Interrupts freigeben;
;* END C_LEAVE_DRIVER;
;*
;*---------------------------------------------------------------------*
;* Parameter:
;*
;* --
;*
;*---------------------------------------------------------------------*/
?CAN?C_LEAVE_DRIVER?HCANAPIF SEGMENT CODE
RSEG ?CAN?C_LEAVE_DRIVER?HCANAPIF
C_LEAVE_DRIVER: CLR EA ; Alle Interrupts sperren
CLR C_DRIVER_IN_USE
; Wartenden Task suchen und starten
MOV DPTR, #C_TEMP_BUF_0_OCC
MOVX A, @DPTR
CJNE A, #TRUE, CL_1
MOV DPTR, #C_TEMP_BUF_0_ID
MOVX A, @DPTR
SETB EA ; Interrupts freigeben
MOV R7, A
CALL _os_send_signal
JMP CL_3
CL_1: MOV DPTR, #C_TEMP_BUF_1_OCC
MOVX A, @DPTR
CJNE A, #TRUE, CL_2
MOV DPTR, #C_TEMP_BUF_1_ID
MOVX A, @DPTR
SETB EA ; Interrupts freigeben
MOV R7, A
CALL _os_send_signal
JMP CL_3
CL_2: MOV DPTR, #C_TEMP_BUF_2_OCC
MOVX A, @DPTR
CJNE A, #TRUE, CL_3
MOV DPTR, #C_TEMP_BUF_2_ID
MOVX A, @DPTR
SETB EA ; Interrupts freigeben
MOV R7, A
CALL _os_send_signal
CL_3: SETB EA ; Interrupts freigeben
RET
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -