Note
The CODESYS Professional Developer Edition provides a tool for static code analysis. A rule set is included for automatically checking the naming convention described above.
Under some circumstances it would be necessary to deactivate a specific rule. This can be achieved with a pair of attributes.
{analysis -46}
/// ...
/// some code which does not conforme to rule SA0046
/// ...
{analysis +46}
The official PLCopen document Coding Guidelines summarises the results of the PLCopen workgroup Software Construction Guidelines Task Force Coding Guidelines. It's first official published version dates from April 20, 2016. The aim of this guidelines is to define a set of rules and to provide a PLCopen proposal how these rules can be used.
Please take a look to the homepage of the PLCopen for the related documents.
Every Rule has an classification number, as shown hereunder:
Rule |
CODESYS |
Name |
Comment |
N1 |
SA0047 |
Avoid physical addresses |
|
N2 |
Define type prefixes for Variables |
see: Naming Conventions |
|
N3 |
Define the names to avoid |
see: Forbidden Symbols |
|
N4 |
Define the use of case (capitals) |
||
N5 |
SA0013 |
Local names shall not shadow global names |
|
N6 |
SA0101 |
Define an acceptable name length |
|
N7 |
Define naming rules for namespaces |
see: Namespace |
|
N8 |
Define the acceptable character set |
see: Allow unicode characters for identifiers |
|
N9 |
SA0013, SA0027 |
Different element types should not bear the same name |
|
N10 |
Define name prefixes for user defined types |
||
C1 |
Comments shall describe the intention of the code |
||
C2 |
SA0162 |
All elements shall be commented |
|
C3 |
SA0163 |
Avoid nested comments |
|
C4 |
SA0140 |
Comments may not include code |
Exception, see: Literal Blocks |
C5 |
SA0164 |
Use single line comments |
see: LibDocContent |
C6 |
Define comments language |
Library developer employed by 3S use English for their comments |
|
CP1 |
SA0047, SA0048 |
Access to a member shall be by name |
|
CP2 |
SA0001, SA0031 |
All code shall be used in the application |
|
CP3 |
All variables shall be initialized before being used |
see: CODESYS initialize all variables with all bits zero by default |
|
CP4 |
SA0028 |
Direct addressing should not overlap |
|
CP5 |
Applications shall be well designed |
||
CP6 |
Avoid external variables in functions and function blocks |
||
CP7 |
SA0009 |
Error information shall be tested |
|
CP8 |
SA0054 |
Floating point comparison shall not be equality or inequality |
|
CP9 |
SA0150 |
Limit the complexity of POU code |
see: Static Analysis - Metrics in the OnlineHelp |
CP10 |
SA0006 |
Avoid multiple writes from multiple tasks |
|
CP11 |
Manage synchronization among tasks |
see: CAA_types.library BOLT, SEMA |
|
CP12 |
SA0004 |
Physical outputs shall be written once per PLC cycle |
|
CP13 |
SA0160 |
POUs shall not call themselves directly or indirectly |
|
CP14 |
SA0090 |
POUs shall have a single point of exit |
|
CP15 |
Read a variable written by another task only once per cycle |
||
CP16 |
SA0165 |
Tasks shall only call program POUs and not Function Blocks |
|
CP17 |
SA0009 |
Usage of parameters shall match their declaration mode |
|
CP18 |
SA0121 |
Use of global variables shall be limited |
|
CP19 |
Usage of jump and return should be avoided |
||
CP20 |
SA0105 |
Function block instances should be called only once |
|
CP21 |
SA0073 |
Use VAR_TEMP for temporary variable declaration |
|
CP22 |
SA0011, SA0033 |
Select appropriate data type |
|
CP23 |
SA0166 |
Define maximum number of input/output/in-out variables of a POU |
|
CP24 |
SA0032, SA0033, SA0035, SA0036 |
Do not declare variables that are not used |
|
CP25 |
SA0019 |
Data types conversion should be explicit |
|
CP26 |
SA0043 |
A global variable may be written only by one PROGRAM |
|
CP27 |
Avoid deprecated features |
||
CP28 |
Time and physical measures comparison shall not be equality or inequality |
||
L1 |
Define indentation |
Library developer employed by 3S use four spaces |
|
L2 |
(FBD) Avoid assignments of intermediate results within networks |
||
L3 |
(FBD) Define maximum complexity of single network |
||
L4 |
(LD) A coil should not be followed by a contact |
||
L5 |
(LD) Define maximum rung complexity |
||
L6 |
(SFC) Closing divergent paths |
||
L7 |
(SFC) Do not program an SFC action block in SFC |
||
L8 |
(SFC) Define maximum complexity |
||
L9 |
(ST) Define general formatting rules |
||
L10 |
(ST) Usage of CONTINUE and EXIT instruction should be avoided |
||
L11 |
(ST) Define the maximum line length |
||
L12 |
SA0072 |
(ST) Loop variables should not be modified inside a FOR loop |
|
L13 |
SA0073 |
(ST) FOR loop variable usage should not be used outside the FOR loop |
|
L14 |
(ST) Passing parameters should be clear |
||
L15 |
(ST) Use parenthesis to explicitly express operation precedence |
||
L16 |
(ST) Define the use of tabs |
Library developer employed by 3S don't use tabs |
|
L17 |
SA0075 |
(ST) Each IF instruction should have an ELSE clause |
|
E1 |
Dynamic memory allocation shall not be used |
||
E2 |
SA0061 |
Pointer arithmetic shall not be used |
|
E3 |
SA0061 |
Some comparator instructions shall not be used for pointers or reference manipulation |
Recommended Rules for Static Analysis
Available Rules
This table shows the set of recommended rules that should be activated or deactivated in CODESYS Static Analysis.
Rule |
PLCopen |
Description |
Active |
Reason |
SA0001 |
CP2 |
Unreachable code |
Yes |
|
SA0002 |
Empty objects |
Yes |
||
SA0003 |
Empty statements |
Yes |
||
SA0004 |
CP12 |
Multiple write access on output |
Yes |
|
SA0005 |
Check address and data type |
Yes |
||
SA0006 |
CP10 |
Write access from several tasks |
Yes |
|
SA0007 |
Address operator on constants |
Yes |
||
SA0008 |
Check subrange types |
Yes |
||
SA0009 |
CP7, CP17 |
Unused return values |
Yes |
|
SA0010 |
Arrays with only one component |
Yes |
||
SA0011 |
CP22, CP24 |
Useless declarations |
No |
|
SA0012 |
Variables which could be declared as constants |
Yes |
||
SA0013 |
N5, N9 |
Declarations with the same variable name |
not yet |
|
SA0014 |
Assignment of instances |
Yes |
||
SA0015 |
Access to global data via FB_Init |
Yes |
||
SA0016 |
Gaps in structures |
Yes |
||
SA0017 |
Non-regular assignments |
Yes |
||
SA0018 |
Unusual bit access |
Yes |
||
SA0019 |
CP25 |
Implicit pointer conversions |
not yet |
|
SA0020 |
Possibly assignment of truncated value to REAL variable |
Yes |
||
SA0021 |
Transporting the address of a temporary variable |
Yes |
||
SA0022 |
(Possibly) unassigned return value |
Warning |
||
SA0023 |
Too big return values |
Warning |
||
SA0024 |
Untyped literals / constants |
No |
||
SA0025 |
Unqualified enumeration constants |
Yes |
||
SA0026 |
Possible truncated strings |
Yes |
||
SA0027 |
N9 |
Multiple uses of identifiers |
not yet |
|
SA0028 |
CP4 |
Overlapping memory areas |
Yes |
|
SA0029 |
Notation in code different to declaration |
Yes |
||
SA0030 |
Unused objects |
No |
||
SA0031 |
CP2 |
Unused signatures |
No |
|
SA0032 |
CP24 |
Unused enumeration constants |
No |
|
SA0033 |
CP22, CP24 |
Unused variables |
Warning |
|
SA0034 |
Enumerations with incorrect assignment |
Yes |
||
SA0035 |
CP24 |
Unused input variables |
No |
|
SA0036 |
CP24 |
Unused output variables |
No |
|
SA0037 |
Write access to input variable |
No |
||
SA0038 |
Read access to output variable |
No |
||
SA0039 |
Possible null pointer dereferences |
Yes |
||
SA0040 |
Possible division by zero |
Yes |
||
SA0041 |
Detect possible loop invariant code |
Yes |
||
SA0042 |
Usage of different access paths |
No |
||
SA0043 |
CP26 |
Use of a global variable in only one POU |
Yes |
|
SA0044 |
Declarations with reference to interface |
Yes |
||
SA0045 |
Conversions |
Yes |
See: SA0019, SA0130, ..., SA0134 |
|
SA0046 |
Possible use of not initialised interface |
Yes |
||
SA0047 |
N1, CP1 |
Accesses to direct address |
Yes |
|
SA0048 |
N1, CP1 |
AT-declarations on direct addresses |
Yes |
|
SA0049 |
Usage of direct addresses |
Yes |
See: SA0005, SA0047, SA0048 |
|
SA0050 |
Rules for operators |
Yes |
See: SA0051, ..., SA0066 |
|
SA0051 |
Comparison operations on BOOL vairables |
Yes |
||
SA0052 |
Unusual shift operation |
Yes |
||
SA0053 |
Too big bitwise shift |
Yes |
||
SA0054 |
CP8 |
Comparisons of REAL/LREAL for equality / inequality |
Yes |
|
SA0055 |
Unnecessary comparisons of unsigned operands |
Yes |
||
SA0056 |
Constant out of valid range |
Yes |
||
SA0057 |
Possible loss of decimal places |
No |
||
SA0058 |
Operations on enumeration variables |
Yes |
||
SA0059 |
Comparison operations always returning TRUE or FALSE |
Yes |
||
SA0060 |
Zero used as invalid operand |
Yes |
||
SA0061 |
E2, E3 |
Unusual operation on pointer |
Yes |
|
SA0062 |
Uses of TRUE or FALSE in expressions |
Yes |
||
SA0063 |
Possibly not 16-bit-compatible operations |
Yes |
||
SA0064 |
Addition of pointer |
Yes |
||
SA0065 |
Incorrect pointer addition to base size |
Yes |
||
SA0066 |
Uses of temporary results |
Yes |
||
SA0070 |
Rules for statements |
Yes |
See: SA0071, ..., SA0090 |
|
SA0071 |
FOR statements |
Yes |
See: SA0072, SA0073, SA0080, SA0081 |
|
SA0072 |
L12 |
Invalid uses of counter variable |
Yes |
|
SA0073 |
CP21, L13 |
Uses of inadequate counter variable |
No |
|
SA0074 |
CASE statement |
Yes |
See: SA0075, ..., SA0078 |
|
SA0075 |
L17 |
Missing ELSE |
Warning |
|
SA0076 |
Missing enumeration constant |
Warning |
||
SA0077 |
Type mismatches with CASE expression |
Yes |
||
SA0078 |
Missing CASE branches |
Yes |
||
SA0080 |
Loop index variable for array index exeeds array range |
Yes |
||
SA0081 |
Upper border is not a constant |
Yes |
||
SA0090 |
CP14 |
Return statement before end of function |
Warning |
|
SA0095 |
Assignments in conditions |
Yes |
||
SA0100 |
Variables greater than 1024 bytes... |
Yes |
||
SA0101 |
N6 |
Names with invalid length |
not yet |
|
SA0102 |
Access to program/fb variables from the outside |
Yes |
||
SA0105 |
CP16, CP20 |
Multiple instance calls |
Yes |
|
SA0106 |
Virtual method calls in FB_INIT |
No |
||
SA0107 |
Missing formal parameters |
No |
||
SA0110 |
Check strict IEC rules |
No |
See: SA0111, ..., SA0123 |
|
SA0111 |
Pointer variables |
No |
||
SA0112 |
Reference variables |
No |
||
SA0113 |
Variables with data type WSTRING |
No |
||
SA0114 |
Variables with data type LTIME |
No |
||
SA0115 |
Variables with data type UNION |
No |
||
SA0117 |
Variables with data type BIT |
No |
||
SA0118 |
Initialisations not using constants |
No |
||
SA0119 |
Object-oriented features |
No |
||
SA0120 |
Program calls |
Yes |
||
SA0121 |
CP18 |
Missing VAR_EXTERNAL declarations |
Yes |
|
SA0122 |
Array index defined as expression |
No |
||
SA0123 |
Usages of INI, ADR or BITADR |
No |
||
SA0124 |
Prohibit dereference access in initialisations |
No |
||
SA0125 |
Prohibit references in initialisations |
No |
||
SA0130 |
Implicit expanding conversions |
Yes |
||
SA0131 |
Implicit narrowing conversions |
Yes |
||
SA0132 |
Implicit signed/unsigned conversions |
Yes |
||
SA0133 |
Explicit narrowing conversions |
No |
||
SA0134 |
Explicit signed/unsigned conversions |
No |
||
SA0140 |
C4 |
Statements commented out |
Yes |
|
SA0150 |
CP9 |
Violations of lower or upper limits or the metrics |
No |
|
SA0160 |
CP13 |
Recursive calls |
Yes |
|
SA0161 |
Unpacked structure in packed structure |
Yes |
||
SA0162 |
C2 |
Missing comments |
No |
|
SA0163 |
C3 |
Nested comments |
Yes |
|
SA0164 |
C5 |
Multiline comments |
Yes |
|
SA0165 |
CP16 |
Tasks calling other POUs than programs |
No |
|
SA0166 |
CP23 |
Max. number of input/output/in-out variables... |
No |
|
SA0167 |
Report Temporary FB Instances |
? |
Reasons for Exceptions
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |
( 1, ) |