DATA_BLOCK DB 1 STRUCT Value : INT VAR0 : INT END_STRUCT BEGIN Value := 8290 VAR0 := 0 END_DATA_BLOCK FUNCTION_BLOCK FB 1 BEGIN L W#16#4321 T MW 0 END_FUNCTION_BLOCK FUNCTION FC 1 : VOID BEGIN L W#16#1234 T MW 0 CALL FC 2 END_FUNCTION FUNCTION FC 2 : VOID BEGIN L W#16#6789 T MW 0 L 10 T LB 0 END_FUNCTION FUNCTION FC 3 : VOID BEGIN L 1 T LB 0 CALL FC 2 __ASSERT== LB 0, 1 END_FUNCTION FUNCTION FC 4 : VOID VAR_INPUT INPVAR : INT INPVAR3 : BOOL INPVAR4 : BOOL END_VAR VAR_IN_OUT INOUT0 : INT INOUT1 : INT END_VAR BEGIN L #INPVAR __ASSERT== __ACCU 1, 9976 U #INPVAR3 __ASSERT== __STW VKE, 0 U #INPVAR4 __ASSERT== __STW VKE, 1 L #INOUT0 __ASSERT== __ACCU 1, 84 L #INOUT1 __ASSERT== __ACCU 1, 984 L 42 T #INOUT0 L 942 T #INOUT1 END_FUNCTION FUNCTION FC 5 : VOID VAR_INPUT INPVAR2 : INT INPVAR3 : BOOL INPVAR4 : BOOL END_VAR VAR_IN_OUT INOUT0 : INT INOUT1 : INT END_VAR BEGIN L #INOUT0 __ASSERT== __ACCU 1, 84 L #INOUT1 __ASSERT== __ACCU 1, 984 CALL FC 4 ( INPVAR := #INPVAR2, // This is a parameter INPVAR3 := #INPVAR3, INPVAR4 := #INPVAR4, INOUT0 := #INOUT0, INOUT1 := #INOUT1, ) L #INOUT0 __ASSERT== __ACCU 1, 42 L 168 T #INOUT0 L #INOUT1 __ASSERT== __ACCU 1, 942 L 9168 T #INOUT1 END_FUNCTION FUNCTION FC 6 : VOID BEGIN // Only check OV and OS bits __ASSERT== __STW OV, 1 __ASSERT== __STW OS, 0 L 1 L 1 +I __ASSERT== __STW OV, 0 __ASSERT== __STW OS, 0 END_FUNCTION FUNCTION FC 7 : VOID BEGIN // Trigger an overflow __ASSERT== __STW OV, 0 __ASSERT== __STW OS, 0 L 30000 L 30000 +I __ASSERT== __STW OV, 1 __ASSERT== __STW OS, 1 END_FUNCTION FUNCTION_BLOCK FB 10 VAR_INPUT INVAR1 : BOOL INVAR2 : BYTE INVAR3 : WORD INVAR4 : DWORD INVAR5 : INT INVAR6 : DINT INVAR7 : REAL INVAR8 : S5TIME INVAR9 : TIME INVAR10 : DATE INVAR11 : CHAR END_VAR VAR_OUTPUT RETURNVALUE : INT END_VAR BEGIN // Check parameter values U #INVAR1 __ASSERT== __STW VKE, 1 L #INVAR2 __ASSERT== __ACCU 1, B#16#12 L #INVAR3 __ASSERT== __ACCU 1, W#16#3456 L #INVAR4 __ASSERT== __ACCU 1, DW#16#88776655 L #INVAR5 __ASSERT== __ACCU 1, 8290 L #INVAR6 __ASSERT== __ACCU 1, L#999999 L #INVAR7 __ASSERT== __ACCU 1, 9.876 L #INVAR8 __ASSERT== __ACCU 1, S5T#9s L #INVAR9 __ASSERT== __ACCU 1, T#9s L #INVAR10 __ASSERT== __ACCU 1, 900 L #INVAR11 __ASSERT== __ACCU 1, 'c' CALL FC 10 ( INPUTVAR1 := #INVAR1, INPUTVAR2 := #INVAR2, INPUTVAR3 := #INVAR3, INPUTVAR4 := #INVAR4, INPUTVAR5 := #INVAR5, INPUTVAR6 := #INVAR6, INPUTVAR7 := #INVAR7, INPUTVAR8 := #INVAR8, INPUTVAR9 := #INVAR9, INPUTVAR10 := #INVAR10, INPUTVAR11 := #INVAR11, INVAR_DB := DB1.DBW 0, RET_VAL := #RETURNVALUE, ) END_FUNCTION_BLOCK DATA_BLOCK DB 10 FB 10 BEGIN END_DATA_BLOCK FUNCTION FC 10 : INT VAR_INPUT INPUTVAR1 : BOOL INPUTVAR2 : BYTE INPUTVAR3 : WORD INPUTVAR4 : DWORD INPUTVAR5 : INT INPUTVAR6 : DINT INPUTVAR7 : REAL INPUTVAR8 : S5TIME INPUTVAR9 : TIME INPUTVAR10 : DATE INPUTVAR11 : CHAR INVAR_DB : INT END_VAR BEGIN // Check parameter values U #INPUTVAR1 __ASSERT== __STW VKE, 1 L #INPUTVAR2 __ASSERT== __ACCU 1, B#16#12 L #INPUTVAR3 __ASSERT== __ACCU 1, W#16#3456 L #INPUTVAR4 __ASSERT== __ACCU 1, DW#16#88776655 L #INPUTVAR5 __ASSERT== __ACCU 1, 8290 L #INPUTVAR6 __ASSERT== __ACCU 1, L#999999 L #INPUTVAR7 __ASSERT== __ACCU 1, 9.876 L #INPUTVAR8 __ASSERT== __ACCU 1, S5T#9s L #INPUTVAR9 __ASSERT== __ACCU 1, T#9s L #INPUTVAR10 __ASSERT== __ACCU 1, 900 L #INPUTVAR11 __ASSERT== __ACCU 1, 'c' L #INVAR_DB __ASSERT== __ACCU 1, 8290 // Check parameter pointers L P##INPUTVAR1 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR2 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR3 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR4 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR5 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR6 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR7 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR8 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR9 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR10 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 L P##INPUTVAR11 UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 // Handle and check return value L 99 T #RET_VAL L #RET_VAL __ASSERT== __ACCU 1, 99 L P##RET_VAL UD DW#16#FFF80000 __ASSERT== __ACCU 1, DW#16#87000000 // And another nested call CALL FC 11 ( IN1 := #INVAR_DB, ) END_FUNCTION FUNCTION FC 11 : VOID VAR_INPUT IN1 : INT END_VAR BEGIN L #IN1 __ASSERT== __ACCU 1, 8290 END_FUNCTION ORGANIZATION_BLOCK OB 1 BEGIN CALL FC 1 __ASSERT== MW 0, W#16#6789 L 0 T MW 0 __ASSERT== MW 0, 0 UC FC 1 __ASSERT== MW 0, W#16#6789 L 0 T MW 0 __ASSERT== MW 0, 0 SET CC FC 1 __ASSERT== MW 0, W#16#6789 L 0 T MW 0 __ASSERT== MW 0, 0 CLR CC FC 1 __ASSERT== MW 0, 0 // Test localdata stack L 255 T LB 0 __ASSERT== LB 0, 255 CALL FC 3 __ASSERT== LB 0, 255 // Test nested FC calls L 84 T MW 42 L 984 T DB1.DBW 2 CALL FC 5 ( INPVAR2 := 9976, INPVAR3 := FALSE, INPVAR4 := TRUE, INOUT0 := MW 42, INOUT1 := DB1.DBW 2, // DB1.VAR0 ) L MW 42 __ASSERT== __ACCU 1, 168 L DB1.DBW 2 __ASSERT== __ACCU 1, 9168 // Test OV/OS bits over call boundaries __STWRST L 30000 L 30000 +I __ASSERT== __STW OV, 1 __ASSERT== __STW OS, 1 CALL FC 6 __ASSERT== __STW OV, 0 __ASSERT== __STW OS, 0 __STWRST CALL FC 7 __ASSERT== __STW OV, 1 __ASSERT== __STW OS, 0 // Test raw FB call L 0 T MW 0 CLR UC FB 1 L MW 0 __ASSERT== __ACCU 1, W#16#4321 L 0 T MW 0 SET CC FB 1 L MW 0 __ASSERT== __ACCU 1, W#16#4321 // Test indirect calls L 0 T MW 0 L 1 T MW 50 CLR UC FC [MW 50] L MW 0 __ASSERT== __ACCU 1, W#16#6789 L 0 T MW 0 SET CC FC [MW 50] L MW 0 __ASSERT== __ACCU 1, W#16#6789 L 0 T MW 0 CLR UC FB [MW 50] L MW 0 __ASSERT== __ACCU 1, W#16#4321 L 0 T MW 0 SET CC FB [MW 50] L MW 0 __ASSERT== __ACCU 1, W#16#4321 // Test parameter forwarding (FB->FC) L 900 T MW 10 CALL FB 10, DB 10 ( INVAR1 := TRUE, INVAR2 := B#16#12, INVAR3 := W#16#3456, INVAR4 := DW#16#88776655, INVAR5 := DB1.DBW 0, INVAR6 := L#999999, INVAR7 := 9.876, INVAR8 := S5T#9s, INVAR9 := T#9s, INVAR10 := MW 10, INVAR11 := 'c', RETURNVALUE := MW 0, ) L MW 0 __ASSERT== __ACCU 1, 99 CALL SFC 46 // STOP CPU END_ORGANIZATION_BLOCK