📄 pcanap_2.inc
字号:
MOV R7, #C_DRIVER_ID
CALL _os_send_signal
MOV R7, #K_SIG
CALL _os_wait
;Returnwert retten
MOV DPTR, #C_ORDER_BUF_PARAM
MOVX A, @DPTR
PUSH ACC
CALL C_LEAVE_DRIVER
POP ACC
MOV R7, A
RET
CST_1: MOV R7, #C_CAN_FAILURE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C A N _ S E N D
;*---------------------------------------------------------------------*
;* Funktion:
;* Senden eines vorher mit CAN_DEF_OBJ definierten Objektes 乥er
;* den CAN-Bus.
;*
;* BEGIN
;* R3 := HIGH(MSG_PTR);
;* R4 := LOW(MSG_PTR);
;* IF C_ENTER_DRIVER THEN
;* C_ORDER_BUF.ORDER := CAN_SEND_ORDER;
;* C_ORDER_BUF.PARAM[0] := R3;
;* C_ORDER_BUF.PARAM[1] := R4;
;* C_ORDER_BUF.TASK_ID := os_running_task_id ();
;* os_send_signal an CAN-Task;
;* os_wait (K_SIG,0FFH,0);
;* PUSH(C_ORDER_BUF.PARAM[0]); (* Returnwert auf Stack pushen *)
;* C_LEAVE_DRIVER;
;* POP(ACC); (* Returnwert in Akku *)
;* RETURN;
;* ELSE
;* RETURN C_CAN_FAILURE;
;* END IF;
;* END CAN_SEND;
;*
;*---------------------------------------------------------------------*
;* Parameter :
;*
;* R6/R7 : MSG_PTR Pointer zu einer Struktur vom Typ
;*
;*
;* Returnwert in R7 :
;*
;* C_OK Objekt wird gesendet
;* C_OBJ_ERROR Das Objekt mit der angegebenen
;* Identifikation ist nicht bekannt oder
;* das Objekt kann nicht gesendet werden
;* (OBJECT_TYP in CAN_DEF_OBJ ist nur auf
;* Empfang)
;* C_BUS_OFF CAN-Controller ist im Bus-Off Zustand
;* C_CAN_FAILURE CAN-Error
;*
;*---------------------------------------------------------------------*/
?CAN?_can_send?PCANAPIF SEGMENT CODE
RSEG ?CAN?_can_send?PCANAPIF
_can_send:
MOV A, R6
MOV R3, A
MOV A, R7
MOV R4, A
; Testen ob CAN-Task besetzt
CALL C_ENTER_DRIVER
CJNE A, #TRUE, CSE_1
; Befehle an CAN-Task aufsetzen
SETUP_ORDER CAN_SEND_ORDER, 2
; Der Rest des Codes ist f乺 CAN_WRITE und CAN_SEND
; gemeinsam
JMP COMMON_WRITE_SEND
CSE_1: MOV R7, #C_CAN_FAILURE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C A N _ W R I T E
;*---------------------------------------------------------------------*
;* Funktion:
;* Mit CAN_SEND wird ein Objekt direkt 乥er den CAN-Bus gesendet.
;* Mit CAN_WRITE k攏nen neue Daten in ein Objekt geschrieben werden,
;* ohne es sofort zu Senden. Falls dieses Objekt auf Remote-Frames
;* antworten kann (wird mit CAN_DEF_OBJ festgelegt), werden beim
;* Eintreffen eines entsprechenden Remote-Frames von einem anderen
;* Knoten, diese neuen Daten ausgesendet.
;*
;* BEGIN
;* R3 := HIGH(MSG_PTR);
;* R4 := LOW(MSG_PTR);
;* IF C_ENTER_DRIVER THEN
;* C_ORDER_BUF.ORDER := CAN_WRITE_ORDER;
;* C_ORDER_BUF.PARAM[0] := R3;
;* C_ORDER_BUF.PARAM[1] := R4;
;* C_ORDER_BUF.TASK_ID := os_running_task_id ();
;* os_send_signal an CAN-Task;
;* os_wait (K_SIG,0FFH,0);
;* PUSH(C_ORDER_BUF.PARAM[0]); (* Returnwert auf Stack pushen *)
;* C_LEAVE_DRIVER;
;* POP(ACC); (* Returnwert in Akku *)
;* RETURN;
;* ELSE
;* RETURN C_CAN_FAILURE;
;* END IF;
;* END CAN_WRITE;
;*
;*---------------------------------------------------------------------*
;* Parameter :
;*
;* R6/R7 : MSG_PTR Pointer zu einer Struktur vom Typ
;*
;*
;* Returnwert in R7 :
;*
;* C_OK Objekt wurde neu beschrieben
;* C_OBJ_ERROR Das Objekt mit der angegebenen
;* Identifikation ist nicht bekannt oder das
;* Objekt kann nicht gesendet werden
;* (OBJECT_TYP in CAN_DEF_OBJ ist nur
;* auf Empfang)
;* C_CAN_FAILURE CAN-Error
;*
;*---------------------------------------------------------------------*/
?CAN?_can_write?PCANAPIF SEGMENT CODE
RSEG ?CAN?_can_write?PCANAPIF
_can_write:
MOV A, R6
MOV R3, A
MOV A, R7
MOV R4, A
; Testen ob CAN-Task besetzt
CALL C_ENTER_DRIVER
CJNE A, #TRUE, CWR_1
; Befehle an CAN-Task aufsetzen
SETUP_ORDER CAN_WRITE_ORDER, 2
; Der Rest des Codes ist f乺 CAN_WRITE und CAN_SEND
; gemeinsam
; CAN-Task starten
COMMON_WRITE_SEND:
MOV R7, #C_DRIVER_ID
CALL _os_send_signal
MOV R7, #K_SIG
CALL _os_wait
;Returnwert retten
MOV DPTR, #C_ORDER_BUF_PARAM
MOVX A, @DPTR
PUSH ACC
CALL C_LEAVE_DRIVER
POP ACC
MOV R7, A
RET
CWR_1: MOV R7, #C_CAN_FAILURE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C A N _ R E C E I V E
;*---------------------------------------------------------------------*
;* Funktion:
;* Empfangen aller normalen Objekte (alle die nicht mit
;* CAN_BIND_OBJ einem bestimmten Task zugeordnet sind). Die
;* empfangenen Meldungen werden in einer Mailbox
;* zwischengespeichert. Es k攏nen maximal 8 Objekte zwischengespeichert
;* werden. Falls der Applikationstask die Objekte nicht aus
;* der Mailbox liest gehen alle weiteren Objekte verloren
;* (sie werden dem Applikationstask nicht 乥ermittelt).
;*
;* BEGIN
;* R3 := TIMEOUT;
;* R4 := HIGH(BUFFER_PTR);
;* R5 := LOW(BUFFER_PTR);
;* PUSH R4;
;* PUSH R5;
;* ret = os_wait (K_TMO + K_MBX + 7, R3, BUFFER_PTR (* R4 und R5 *));
;* POP R5;
;* POP R4;
;* IF ret = TMO_EVENT THEN
;* RETURN C_TIMEOUT;
;* END;
;* IF C_ENTER_DRIVER THEN
;* C_ORDER_BUF.ORDER := CAN_READ_W_IND_ORDER;
;* C_ORDER_BUF.PARAM[0] := R4;
;* C_ORDER_BUF.PARAM[1] := R5;
;* C_ORDER_BUF.PARAM[2] := Wert an der Adresse BUFFER_PTR+1 (* R4,R5 *)
;* (* Der CAN-Task sendet 乥er die Mailbox den Index des empfangenen *)
;* (* Objektes, dieser Index wird an die Adresse BUFFER_PTR *)
;* (* abgespeichert -> BUFFER_PTR als Argument bei RTX_WAIT *)
;* C_ORDER_BUF.TASK_ID := os_running_task_id ();
;* os_send_signal an CAN-Task;
;* os_wait (K_SIG,0FFH,0);
;* PUSH(C_ORDER_BUF.PARAM[0]); (* Returnwert auf Stack pushen *)
;* C_LEAVE_DRIVER;
;* POP(ACC); (* Returnwert in Akku *)
;* RETURN;
;* ELSE
;* RETURN C_CAN_FAILURE;
;* END;
;* END CAN_RECEIVE;
;*
;*---------------------------------------------------------------------*
;* Parameter :
;*
;* R7 : TIMEOUT Timeout falls in einer bestimmten Zeit
;* kein Objekt empfangen wurde. Definition
;* analog RTX-51;
;* 0 : Kein Timeout, falls kein
;* Objekt vorhanden ist, l剈ft
;* der Applikations-Task weiter
;* ohne zu warten
;* 1..254 : Anzahl RTX-51 Systemticks
;* die der Applikations-Task
;* auf ein Objekt warten soll
;* 255 : Warten bis ein Objekt
;* empfangen wurde
;* (wait forever)
;*
;* R4/R5 : BUFFER_PTR Pointer zu einer Struktur von Typ
;* CAN_MESSAGE_STRUCT im externen RAM.
;* Der CAN-Treiber kopiert das empfangene
;* Objekt in diese Variable.
;*
;*
;* Returnwert in R7 :
;*
;* C_OK Es wurde ein Objekt empfangen
;* C_TIMEOUT Es wurde innerhalb der mit TIMEOUT
;* angegebenen Zeit kein Objekt empfangen
;* C_BUS_OFF CAN-Controller ist im Bus-Off Zustand
;* C_CAN_FAILURE CAN-Error
;*
;*---------------------------------------------------------------------*/
?CAN?_can_receive?PCANAPIF SEGMENT CODE
RSEG ?CAN?_can_receive?PCANAPIF
_can_receive:
MOV A, R7
MOV R3, A
MOV A, R4
PUSH ACC
MOV A, R5
PUSH ACC
MOV R7, #(K_MBX+K_TMO+7)
MOV B, R3
MOV A, R4
MOV R2, A
MOV A, R5
MOV R3, A
MOV R5, B
CALL _os_wait
POP ACC
MOV R5, A
POP ACC
MOV R4, A
; Test ob Timeout
CJNE R7, #TMO_EVENT, CRE_1
MOV R7, #C_TIMEOUT
RET
; Testen ob CAN-Task besetzt
CRE_1: CALL C_ENTER_DRIVER
CJNE A, #TRUE, CRE_2
; Befehle an CAN-Task aufsetzen
MOV DPTR, #C_ORDER_BUF_ORDER
MOV A, #CAN_READ_W_IND_ORDER
MOVX @DPTR, A
INC DPL
INC DPL
MOV A, R4
MOVX @DPTR, A
INC DPL
MOV A, R5
MOVX @DPTR, A
MOV DPH, R4
MOV DPL, R5
INC DPTR ; Nur Low-Byte nehmen
MOVX A, @DPTR
MOV DPTR, #C_ORDER_BUF_PARAM+2
MOVX @DPTR, A
CALL os_running_task_id
MOV DPTR, #C_ORDER_BUF_ID
MOV A, R7
MOVX @DPTR, A
; CAN-Task starten
MOV R7, #C_DRIVER_ID
CALL _os_send_signal
MOV R7, #K_SIG
CALL _os_wait
;Returnwert retten
MOV DPTR, #C_ORDER_BUF_PARAM
MOVX A, @DPTR
PUSH ACC
CALL C_LEAVE_DRIVER
POP ACC
MOV R7, A
RET
CRE_2: MOV R7, #C_CAN_FAILURE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C A N _ B I N D _ O B J
;*---------------------------------------------------------------------*
;* Funktion:
;* Bindet ein bestimmtes (mit CAN_DEF_OBJ) definiertes Objekt an
;* einen bestimmten Task. Beim Empfang dieses Objekts wird dieser
;* Task gestartet (er muss mit CAN_WAIT auf dieses Objekt warten).
;* Diese Funktion implementiert einen besonders schnellen Empfang
;* eines bestimmten, besonders wichtigen Objektes. Ein Task kann mit
;* CAN_BIND_OBJ an mehrere Objekte gekoppelt werden (mehrfacher
;* Aufruf von CAN_BIND_OBJ). Beim Empfang eines dieser Objekte wird
;* der Task gestartet (wenn er mit CAN_WAIT wartet).
;*
;* BEGIN
;* R3 := HIGH(IDENTIFIER);
;* R4 := LOW(IDENTIFIER);
;* IF C_ENTER_DRIVER THEN
;* C_ORDER_BUF.ORDER := CAN_BIND_ORDER;
;* C_ORDER_BUF.PARAM[0] := R3;
;* C_ORDER_BUF.PARAM[1] := R4;
;* C_ORDER_BUF.PARAM[2] := os_running_task_id ();
;* C_ORDER_BUF.TASK_ID := os_running_task_id ();
;* os_send_signal an CAN-Task;
;* os_wait (K_SIG,0FFH,0);
;* PUSH(C_ORDER_BUF.PARAM[0]); (* Returnwert auf Stack pushen *)
;* C_LEAVE_DRIVER;
;* POP(ACC); (* Returnwert in Akku *)
;* RETURN;
;* ELSE
;* RETURN C_CAN_FAILURE;
;* END IF;
;* END CAN_BIND_OBJ;
;*
;*---------------------------------------------------------------------*
;* Parameter :
;*
;* R6/R7: IDENTIFIER Identifikation des Objekts das fest an
;* den aufrufenden Task gebunden werden soll
;*
;* Returnwert in R7 :
;*
;* C_OK Das Objekt IDENTIFIER wurde an den Task
;* gebunden
;* C_OBJ_ERROR Das Objekt mit der angegebenen Identifikation
;* ist nicht bekannt oder das Objekt kann nicht
;* empfangen werden
;* C_MEM_FULL Es wurden bereits acht CAN_BIND_OBJ
;* durchgef乭rt (mit CAN_UNBIND_OBJ kann wieder
;* eine Bindung frei gemacht werden)
;* C_OBJ_REBIND Warnung : Das Objekt mit dem angegebenen
;* Identifier war bereits an einen Task gebunden.
;* Die alte Verbindung wurde gel攕t und die neue
;* aufgebaut.
;*
;*---------------------------------------------------------------------*/
?CAN?_can_bind_obj?PCANAPIF SEGMENT CODE
RSEG ?CAN?_can_bind_obj?PCANAPIF
_can_bind_obj:
MOV A, R6
MOV R3, A
MOV A, R7
MOV R4, A
; Testen ob CAN-Task besetzt
CALL C_ENTER_DRIVER
CJNE A, #TRUE, CBO_1
; Befehle an CAN-Task aufsetzen
SETUP_ORDER CAN_BIND_OBJ_ORDER, 2
MOV DPTR, #C_ORDER_BUF_ID
MOVX A, @DPTR
MOV DPTR, #C_ORDER_BUF_PARAM+2
MOVX @DPTR, A
; CAN-Task starten
MOV R7, #C_DRIVER_ID
CALL _os_send_signal
MOV R7, #K_SIG
CALL _os_wait
;Returnwert retten
MOV DPTR, #C_ORDER_BUF_PARAM
MOVX A, @DPTR
PUSH ACC
CALL C_LEAVE_DRIVER
POP ACC
MOV R7, A
RET
CBO_1: MOV R7, #C_CAN_FAILURE
RET
$EJECT
;*---------------------------------------------------------------------*
;* C A N _ U N B I N D _ O B J
;*---------------------------------------------------------------------*
;* Funktion:
;* L攕t eine mit CAN_BIND_OBJ aufgebaute Verbindung zwischen
;* dem Task und dem Objekt IDENTIFIER. Ab sofort kann dieses
;* Objekt wieder mit CAN_RECEIVE empfangen werden.
;*
;* BEGIN
;* R3 := HIGH(IDENTIFIER);
;* R4 := LOW(IDENTIFIER);
;* IF C_ENTER_DRIVER THEN
;* C_ORDER_BUF.ORDER := CAN_UNBIND_ORDER;
;* C_ORDER_BUF.PARAM[0] := R3;
;* C_ORDER_BUF.PARAM[1] := R4;
;* C_ORDER_BUF.TASK_ID := os_running_task_id ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -