Professional Documents
Culture Documents
: 5
Title
TH
NOVEMBER 1989
CONFIDENTIAL
(ContainsEngineering
confidential(Computer)
information under the Official Secret
Bachelor of Electrical
Act 1972)*
RESTRICTED
OPEN ACCESS
Signature
________________________
Certified by :
Name of Supervisor
SIGNATURE
Date
200707M10019
SIGNATURE OF SUPERVISOR
NOTES :
If the thesis is CONFIDENTAL or RESTRICTED, please attach with the letter from
the organization with period and reasons for confidentiality or restriction.
Signature
_______________________
Supervisors Name
Date
JULY 2012
ii
I declare that this thesis entitled Master/Slave Controller using Encrypted Serial
Communication Protocol is the result of my own research except as cited in the
references. The thesis has not been accepted for any degree and is not concurrently
submitted in candidature of any other degree.
Signature
....................................................
Name
Date
iii
iv
ACKNOWLEDGEMENT
ABSTRACT
vi
ABSTRAK
vii
TABLE OF CONTENT
CHAPTER
TITLE
PAGE
DECLARATION
ii
DEDICATION
iii
ACKNOWLEDGEMENTS
iv
ABSTRACT
ABSTRAK
vi
TABLE OF CONTENTS
vii
LIST OF TABLES
LIST OF FIGURES
xi
LIST OF ABBREVIATIONS
xiii
LIST OF SYMBOLS
xv
LIST OF APPENDICES
xvi
INTRODUCTION
1.1
Project Background
1.2
Problem Statement
1.3
Objectives of Project
1.4
Scope of Project
1.5
Project Schedule
LITERATURE REVIEW
2.1
2.2
Serial Communication
2.1.1
Synchronous Format
2.1.2
Asynchronous Format
viii
2.3
Modbus-RTU
2.3.1
10
2.4
12
2.5
Microcontroller
14
2.5.1
14
2.5.2
Pin Configuration
18
2.5.3
Block Diagram
19
2.6
Message Framing
RS-232 Interface
20
METHODOLOGY
22
3.1
Project Flow
22
3.2
25
3.3
Modbus-RTU Protocol
27
3.3.1
29
3.3.2
Transceiver State
30
3.3.3
31
3.4
32
3.5
34
Protocol
3.6
36
DEVELOPMENT PROCESS
38
4.1
38
4.2
Modbus-RTU Development
41
4.3
48
4.3.1
AVR Studio 6
48
4.3.2
Modular Programming
49
4.4
Programming Interface
Hardware Programming
51
54
5.1
Simulation Result
54
5.2
Experimental Result
56
ix
6
61
6.1
Conclusion
61
6.2
Recommendations
62
REFERENCES
64
APPENDICES
66
LIST OF TABLES
TABLE NO.
TITLE
PAGE
5.1
58
5.2
59
5.3
60
xi
LIST OF FIGURES
FIGURE NO.
TITLE
PAGE
1.1
1.2
2.1
2.2
2.3
2.4
2.5
2.6
2.7
Modbus-RTU Network
10
2.8
11
2.9
11
2.10
12
2.11
13
2.12
18
2.13
19
2.14
20
2.15
21
3.1
23
3.2
25
3.3
26
3.4
27
3.5
28
3.6
29
xii
FIGURE NO.
TITLE
PAGE
3.7
30
3.8
31
3.9
32
3.10
33
3.11
34
3.12
35
3.13
36
3.14
USBtiny Device
36
3.15
37
4.1
Simulation Procedure
39
4.2
40
4.3
41
4.4
43
4.5
45
4.6
47
4.7
48
4.8
50
4.9
52
4.10
52
5.1
55
5.2
56
5.3
57
5.4
59
5.5
60
xiii
LIST OF ABBREVIATIONS
ADC
Analog-to-Digital Converter
AES
ALU
CISC
CMOS
CPU
CRC
DES
EEPROM
GCC
GND
Ground
GUI
I/O
Input-Output
IC
Integrated Circuit
ISP
In-System Programming
ISR
IEEE
JTAG
LLD
LSB
MIPS
MSB
PC
Personal Computer
PDIP
PLC
xiv
PWM
RISC
RTC
Real-Time Clock
RTOS
RTU
SDK
SoC
System on Chip
SPI
SRAM
TEA
USART
USB
VCC
Voltage Input
XTAL
External Crystal
xv
LIST OF SYMBOLS
KB
Kilo Bytes
KHz
mA
mili-Ampere
MHz
Voltage
xvi
LIST OF APPENDICES
APPENDIX
TITLE
PAGE
66
73
75
CHAPTER 1
INTRODUCTION
1.1.
Project Background
devices
(slave)
with
different
communication
media
(serial
2
In this project, serial communication is used as a main data transmission to
connect master device with several slave devices using Modbus as standard
communication protocol. A different approach in developing master device using
microcontroller will also be introduced as a basis hardware platform.
1.2.
Problem Statement
1.3.
Objective of Project
1.4.
Scope of Project
3
1.5.
Project Schedule
Thesis Preparation
12
Hardware Prototyping
Supervisor Meeting
Literature Review
Task
October
8
March
6
Week
9
10
April
February
11
12
13
May
12
November
Week
9
10
11
Supervisor Meeting
Brief Project Idea
Literature Review
Design & Analysis Hardware Specification
Hardware Schematic Design
Hardware PCB Layout Design
Order Hardware Parts
Seminar
Report Preparation
Task
1
2
3
4
5
6
7
8
9
10
11
No
1
2
3
4
5
6
7
8
9
No
September
14
13
15
14
16
16
17
June
15
December
18
CHAPTER 2
LITERATURE REVIEW
2.1.
Serial Communication
6
2.1.1
Synchronous Format
Synchronous formats use a variety of ways to signal the start and end of a
transmission, including Start and Stop bits. Synchronous interface is useful for short
links, with cables of 15 feet or less or even between components on a single circuit
board. For longer links, synchronous format is less practical due to the need of
transmitting the clock signal which requires extra line and subject to noise.
7
2.1.2
Asynchronous Format
In asynchronous transmission, the link does not include a clock line because
each end of the link provides its own clock. Each end must agree on the clocks
frequency and all of the clocks must match. Each transmitted byte includes a Start bit
to synchronize the clocks, and one or more Stop bit to signal the end of a transmitted
signal.
The N in 8-N-1 indicates that the transmissions do not use a parity bit. Parity
can be Even, Odd, Mark, or Space. With Even parity, the parity bit is set or cleared
so that the data bits plus the parity bit contain an even number of 1s. With Odd
parity, the bit is set or cleared so that these bits contain an odd number of 1s. Mark
and Space parity are forms of Sticky parity: with Mark parity, the parity bit is always
1, and with Space parity it is always 0.
8
2.2.
The PLC is designed for multiple inputs and outputs interface, extended temperature
ranges, immunity to electrical noise, and resistance to vibration and impact. PLC is
also armored to withstand severe conditions such as dust, moisture, heat, and cold.
The feature of multiple I/O allows PLC to have extensive input/output arrangements
as well.
2.3.
Modbus-RTU
Modbus-RTU (Remote Terminal Unit) means that the Modbus protocol is used on a
serial line with RS-232 port as the interface. The original Modbus-RTU scheme runs
over RS-232, however it is possible to adapt RS-485 to gain faster speed, longer
distance, and multi-drop network. It is possible to connect multi-master (usually only
10
2 master devices) on Modbus-RTU network, however the prior master should be
defined that only one master can initiate communication within the network.
Device Address
Function Code
Data
Error Check
The device address can be defined in a number range of 0 to 247, address number 1
to 247 are addresses of specific slave device and address number 0 is for broadcast
messages which will be received by all slave devices. Hence, if the master sends data
to slave address 1 only relevant address will respond the request while the rest of
slave devices will remain on standby for further communication.
11
The function code defines the command that the slave device is to execute,
such as read data, accept data, and report status. Function codes are in a number
range of 1 to 255 where some function code have sub-function code and the function
is depend on device specification.
12
2.4.
13
Input: Plaintext
Output: Ciphertext
Figure 2.11 TEA Feistel Cycle
The input of plaintext/ciphertext is divided into two 32-bits value and then mixed
with key schedule and constant value which is
Furthermore,
each input vector text then will be processed through shifting, adding, and XOR as
shown on Figure 2.10. Adding operation will be commenced by using resulting data
through algebraic process from the respected input vector to generate ciphertext, the
routine iteration will be performed 32 times.
14
#include <stdint.h>
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i;
uint32_t delta=0x9e3779b9;
/* set up */
/* a key schedule constant */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
/* end cycle */
v[0]=v0; v[1]=v1;
}
/* end cycle */
v[0]=v0; v[1]=v1;}
15
2.5.
Microcontroller
16
i.
ii.
1K Bytes EEPROM
iii.
iv.
Peripheral Features
17
v.
vi.
vii.
viii.
ix.
Operating Voltages
1.8V 5.5V
2.7V 5.5V
Speed Grades
Active: 0.4 mA
18
2.5.2. Pin Configurations
Moreover, each Port has different supplementary extended feature and alternate pin
configurations function, such Port A serves as analog inputs to the Analog-to-digital
Converter. Port B has alternate function as Serial Peripheral Interface (SPI) and I/O
analog comparator. Port C also serves the function of the JTAG interface along with
special function as timer oscillator and 2-wire serial interface. In addition, Port D has
USART interface, timer/counter, and external interrupt pins.
19
2.5.3. Block Diagram
The AVR core of ATmega324P combines a rich instruction set with 32 general
purpose working registers. All the 32 registers are directly connected to the
Arithmetic Logic Unit (ALU), allowing two independent registers to be accessed in
one single instruction executed in one clock cycle. The resulting architecture is more
code efficient while achieving throughputs up to ten times faster than conventional
CISC microcontrollers.
20
2.6.
RS-232 Interface
A DB-9 has 9 pin connectors where each pin has different purpose. Figure
2.13 shows DB-9 pinout connection as generally used for serial communication
standard RS-232. Pin number 2 (receive data), 3 (transmit data) and 5 (ground) are
the most frequent used in establishing communication protocol through RS-232
interface. It is the most fundamental connection to perform transmission and
reception data as described on Figure 2.14
21
There are specifically nine pins connectors on DB-9 serial port, however on
the practical implementation not all pins are used through serial communication line.
For the data exchange of reception and transmission only three pins out of nine
connections are required. The other pins are specifically for particular development
purpose of serial communication interface. A model to describe usage of RS-232
Interface is introduced on Figure 2.15.
RS-232 Interface
PC
2
3
5
3
2
PLC
22
CHAPTER 3
METHODOLOGY
3.1.
Project Flow
The projects development planning process adopts divide & conquer method
which is breaking down a problem into two segments sub-process of the related type.
The solutions of the sub-processes are then combined to give a proposed solution of
the project. In general, the projects process flow consists of five phases which is
shown on Figure 3.1. Master/slave controller design is the first phase of project
which subsequently develop master/slave controller device. Divide & conquer
method starts at phase two where the work is divided into two sub-processes,
Modbus development and TEA implementation. Third phase is test & verification for
both sub-processes which is performed concurrently and independently. The outcome
from both solutions of Phase 2 and Phase 3 then are combined as a proposed
solution is the fourth phase of the project. The final phase or fifth phase is test &
verification of proposed solution to check whether the output of solution
accomplishes projects objectives.
23
Modbus RTU
Development
TEA Implementation
Secured Modbus
The first phase is hardware design for master/slave controller device. The
main objective of this phase is to design master/slave controller PLC based system
using AVR microcontroller as hardware platform. This phase comprises two subprocesses, primary task and secondary task. The primary task is to propose an AVR
based platform controller device while secondary task is to use existing AVR based
software development kit which has serial communication feature to run-through
Modbus-RTU protocol. The primary process of this phase requires adequate
understanding of circuitry design and implementation before fabricating the design to
manufacturer. In the event of insufficient time to fabricate proposed design,
secondary task works as alternative plan to overcome unavailability of proposed
device and use existing AVR based SDK instead. The device outcome of this phase,
whether accomplishing primary or secondary procedure, is used as a baseline
platform for further phases.
24
Second phase is Modbus-RTU and Tiny Encryption Algorithm (TEA)
development and implementation by using controller device as the product of first
phase. From this point onward, the process is fragmented into two different tasks,
first task is Modbus-RTU development and second task is TEA implementation. The
Modbus-RTU and TEA implementation are constructed in concurrent work such that
Modbus protocol is applied on the hardware controller and TEA is developed on
simulation software environment.
Third phase is test and verification for both Modbus and TEA
implementation. Since the development process is handled in different workplace
framework, test and verification is performed in different environment as well. For
Modbus development, test and verification is executed in microcontroller and
monitor the data transmission from PC through serial interface. The data send and
received by microcontroller is analyzed to ensure its correctness. Meanwhile, TEA
implementation is monitored on output data run-through program compiled on
Borland C through command line interface. Debugging process then is done in
advanced for any incorrect output result.
Finally, the fifth phase is test and verification for secured Modbus
communication to ensure the encryption and decryption process generates correct
data according to algorithm and desired outcome.
25
3.2.
26
In addition, Wise-SDK has unique system architecture which differs from
other microcontroller software development kit board. Some I/O peripheral devices
are connected to the same data bus. The usage of sharing bus saves pin connection
thus maximizes provision of features and I/O peripheral devices. As shown on Figure
3.2, standard programmable I/O peripheral devices cover LEDs, DIP switch, push
button, and 7-segment display.
architecture shows on Figure 3.3 with related peripheral devices used in this project.
As shown on the architecture diagram, the LEDs and four 7-segment displays, which
is connected to latches, are connected to same port.
PA3
Latch 0
PA4
Latch 1
PA5
Latch 2
RS-232
PD0 (RX)
PD1 (TX)
PORT B
PORT B
PORTB
8 LEDs
PA6
Latch 3
27
3.3.
Modbus-RTU Protocol
Start
Initialization
Idle
No
Event?
Yes
Process
As shown on the abovementioned figure, the process starts with device initialization.
This state executes initialization module on software part in slave device. After
setting up the device, next process is Idle state where slave device will continuously
remain in the respective state up until communication event occurred.
28
In order the slave device to decide current and upcoming process status, the
routine program is designed to be dependence to each other. This design appears to
be more effective due to less decision statement on the program. The whole Process
State depends on the Transceiver State while Interrupt Service Routine (ISR) triggers
Transceiver State. Figure 3.5 shows state dependencies diagram of the slave
controller device. It is shown on the direction of arrow that Transceiver State triggers
Process State and then Transceiver State is driven by ISR.
ISR
Transceiver State
Process State
29
3.3.1
Process State
Process?
Frame
Received
Idle
Execute
Frame Sent
Return
30
3.3.2
Transceiver State
Receiver State
RX_Init
RX_Idle
Transmitter State
RX_Receive
TX_Idle
TX_Transmit
The Transmitter State includes two transmitter process stages, TX_Idle and
TX_transmit. It depends on the status of Receiver State. The transmitter only
activated after data is completely received by slave device. In other words,
Transmitter State is activated as a response of reception status. Since it has lesser
precedence than Receiver State, Transmitter State is always in idle state.
31
3.3.3
TIMER1_COMPA
ISR
USART0_RX
USART0_UDRE
32
3.4.
Encrypted
The new content of secured Modbus frame appears to be seamlessly safe and
effective to protect communication transmission from unauthorized access. In the
case of unauthorized party intercepted communication transmission, the message
data is encrypted with 128-bit length key and it is not easily to be cracked. This
proposed secured communication design must be implemented on both host and
target device in order to establish data exchange. If Tiny Encryption Algorithm is
implemented on one-sided device, other remote devices could not recognize content
of Modbus protocol when received packet data. Once Tiny Encryption Algorithm is
embedded on host and remote devices, a secured communication between two or
more devices is established. Figure 3.10 shows the proposed design of secured
Modbus-RTU over serial line communication flow. However, the secured
communication flow is achieved only while both host and remote device share
identical Tiny Encryption Algorithm cipherkey.
33
Master
Address
Slave
Encrypt
Error Check
Send Request
Identify Address
Begin Transmission
Pointed
Address?
Idle
Yes
Address
Decrypt
No
Ignored
Error Check
Process Information
Function
Function
Address
Data
Decrypt
Data
Respond
Error Check
Reply Request
Address
Encrypt
Error Check
34
3.5.
TEA Implementation
on PC
TEA Implementation
on Microcontroller
End
35
More detail of elaborated process steps from Figure 3.11 is described on
Figure 3.12. As explained earlier, Tiny Encryption Algorithm implementation is
performed at the first place specifically on Borland C for this project. The source
code composed on Borland C then is simulated to check for error. If error exists on
constructed source code, the process goes through debugging stage of software
development to fix bugs and errors. Debugging process is recursively performed
while the source code still has errors. Once errors have been fixed, the output result
from simulation is tested and verified. In addition, if output result is incorrect
debugging process is repeated up until simulation output generates correct result.
Moreover, as outcome of implementation on PC has been tested and verified the
process advances to TEA integration process on microcontroller. The steps on
integration process are identical with implementation on PC. It comprises of error
check, debugging process, and test & verification of output result for correct data
output.
Start
TEA Implementation
On Borland C
Debugging
Error?
TEA Implementation
On Microcontroller
Debugging
Error?
Output Result
Output Result
Correct?
Correct?
End
36
3.6.
Programming Interface
.hex File
USBtiny
AVR
37
3.7.
Terminal Emulator
CHAPTER 4
DEVELOPMENT PROCESS
4.1
39
Start
Set Cipherkey
Debugging
Encrypt
Output Ciphertext
Cross Reference
0
Valid?
1
Input Ciphertext
Decrypt
Output Plaintext
0
Compare with
Original Plaintext
Valid?
1
End
40
To perform a cross reference check, the simulation stage referred to previous
related project executed by using same encryption algorithm. Moreover, to validate
the output result of simulation process input plaintext and cipher text have to be
exactly match with referred project. The reference of output result is cited from the
project entitled The Implementation of Tiny Encryption Algorithm (TEA) on
PIC18F4550 Microcontroller. The referred project implemented same encryption
technique which is Tiny Encryption Algorithm. Even though the implementation
platform is different, the essential point here is to compare whether TEA result from
simulation generates equal ciphertext with identical input text and cipherkey as to
refer project. Figure 4.2 shows the referred project output result of TEA
implementation on PIC microcontroller.
41
4.2
Modbus-RTU Development
Idle
Frame Received
Execute
Frame Sent
Get Modbus
frame
Process = Idle
Check target
address
Compatible?
True?
No
Yes
Process = Execute
No
Yes
Call respective
function code
Write exception
code
Exception?
Yes
Process = Idle
No
Call transmit
function
Return
Exception data
frame
42
In the other hand, Frame Received and Execute state perform more detail
operations. Slave devices state changes when data reception is occurred in serial
communication interface. It is triggered by interrupt corresponding to USART0_RX
interrupt. The data received from serial interface then stored into buffer array on
slave device. Once the state is changed to Frame Received, the program will get
Modbus frame previously stored in buffer and check target address within the packet
message. If the target address is correct to corresponding slave device, the process
state then is changed to Execute and return to the main routine otherwise back to Idle
state.
On the next polling cycle, since the process state is changed to Execute thus
slave device will call functions within Execute state tree. In this process, the Modbus
function protocol will be performed. Initially, slave device will get function code
from data buffer and then analyze whether requested function is implemented or
compatible on slave controller device. In accordance of function availability, slave
device will call respective function code on the Modbus protocol routine. On the
other hand, if the requested function code is not compatible slave device will write
exception code. Exception code is a Modbus protocol code where the requested
function code is not compatible or not available on respective slave device. Next
process is checking whether exception code is exist on slave device routine status.
Slave device then will prepare for data transmission over serial interface to reply
request message from master device. At this point, regardless the status of exception
code on Modbus program, slave device will transmit both conditions whether
exception code is exist or not. This condition is shown on decision making process
within Execute tree functions. Moreover, the difference between true or false status
of exception code is the content within Modbus frame. In accordance of false
exception status slave device will send function code and respected data function
code otherwise data transmitted is exception code response.
43
Furthermore, the interrupt service routines which affects directly to the flow
of process state will be introduced from this point onward. The first interrupt which
is set as highest precedence is USART0_RX. This interrupt is driven by the time
receiver in serial interface received data transmission. While main routine performs
polling cycle, the moment data is received by serial interface current main routine
process is suspended and USART0_RX interrupt is called.
USART0_RX
Set TX_Idle
Check receiver
status
RX_Init?
No
RX_Idle?
No
RX_Receive?
Yes
Yes
Index = 0
Index++
Set RX_Receive
Yes
Enable timer
Return
44
The first process of this interrupt is setting the transmitter status to idle. As
explained earlier based on Figure 4.3, once data is received by serial interface slave
device store it to buffer. Next process is to get data received from data buffer.
Afterwards, the program checks receiver current status. The checking is essential for
slave device to remain within interrupt function where incoming data is still
transmitted to construct one Modbus frame package. There are three decision
condition regarding receiver status. First is RX_Init, at this state interrupt program
will perform no operation and return to the main routine. Second state is RX_Idle,
this state is when receiver is waiting for data reception through serial interface line, if
this condition is true interrupt program will set data index to 0 to prepare receiving
incoming message and stored it to data buffer. After data is received, it is directly
stored to data buffer and then set receiver state to RX_Receive for the next cycle,
before exiting the routine timer is enabled to count time interval between receiving
packet data. The third condition is when receiver in RX_Receive, at this condition in
accordance of triggered interrupt the program will increment current data index by
one and stored data received in the respective buffer position and the process returns
back to the main routine. In addition, by the time program leaves interrupt routine,
the timer still counting up until reaches defined value. At this time, once the timer
reached it maximum threshold value Timer1_CompA interrupt will be driven.
45
TIMER1_COMPA
Check receiver
status
RX_Init?
Yes
Process = Idle
No
RX_Receive?
Yes
No
Disable timer
Set RX_Idle
Return
By the time corresponding interrupt is called, the system program checks the
receiver status. Slave device then analyze current receiver state and process next
function according to its condition. The abovementioned figure shows a setting to
Idle process state when receiver at initialization state otherwise slave device
advances to analyze next condition. Afterwards, the program checks whether receiver
in RX_Receive state, if the state is true the program will change current process state
to Frame Received otherwise the process moves to next instruction. Subsequently,
the timer will be disabled and set receiver status to idle then return to the main
routine indicates that interrupt routine is completely executed.
46
The third and last interrupt implemented on slave device is USART0_UDRE.
This interrupt implicitly functions to transmit data as a response event in accordance
of request data from master. USART0_UDRE interrupt is driven by the time serial
interface data register is empty. In the other hand, if the receiver of serial interface is
disabled it will flush data held within USART Data Register (UDRE) and then
corresponding
interrupt
is
driven.
Figure
4.6
shows
detail
process
of
USART0_UDRE routine.
47
USART0_UDRE
Set RX_Idle
Check transmitter
status
Yes
TX_Idle
No
Enable receiver
TX_Transmit?
Yes
Check Send
Buffer Index
Index = 0?
Yes
No
Send data
Enable receiver
Buffer++
Index--
Set TX_Idle
Return
No
48
4.3
4.3.1
AVR Studio 6
49
4.3.2
Modular Programming
50
Rtufunccoils.c
Deviceinit.c
Devicetimer.c
Deviceport.h
Main.h
Modbus.h
Deviceserial.c
Main.c
Modbus.c
Tea.h
Rtucrc.h
Avrwise.h
Tea.c
Rtucrc.c
Avrwise.c
51
Parting code files not only organize software development process into
structured and well managed project but also construct effective and efficient work.
Most compilers work on one file at a time, thus any changes on one line coding will
result the compiler has to recompile the whole linen of code. On the other hand, if the
file is fragmented into several files, any changes on line coding in one file will only
require the respective file to be compiled while rest of the files will not need
compiling. Thus, it speeds up compilation process. Splitting source code along
logical lines also makes it easier for the programmer to find variable, function,
declaration, and other definitions. It also reduces amount of code needed to read in
order to find specific line coding which increases file organization. Moreover,
creating several modules facilitate code reuse within the project file. While the
source code is split up into sections which operate essentially independent of each
other, it allows the code to be reused which saving time or rewriting over. Hence,
splitting source code into several files will give significant advantages in software
development process.
4.4
Hardware Programming
52
Compiler
.hex File
WinAVR
USBtiny
AVR
53
To perform hardware programming, first of all run command prompt on
windows. Next step is change the directory where .hex file is located. The above
figured used ls instruction on command prompt to display files within directory on
list view. It is noticed within the black rectangle that .hex file is inside the target
directory. The next instruction line is to run WinAVR by using avrdude instruction
as within purple rectangle box followed by programmer device. In this case the
project used USBtiny as programmer device and ATmega324P as microcontroller
device, the instruction is within red rectangle. Lastly, flash instruction along with
.hex file target as within brown box. Afterwards, once WinAVR has successfully
connected with programmer device, as in this project, the rest of operation will be
handled by USBtiny. Detail descriptions are listed on Figure 4.10 after WinAVR is
executed.
CHAPTER 5
5.1
Simulation Result
The simulation process of the project was done using Borland C compiler to
test and verify whether Tiny Encryption Algorithm routine is correctly implemented.
The expected outcome of simulation result is a correct ciphertext as the product of
encryption process and then acquires same input plaintext in the decryption process.
Additionally, the point of interest in the simulation is whether the generated
ciphertext is correct with associated cipherkey even though decryption process
obtains original input plaintext. A cross reference was performed with other related
project using similar input plaintext and cipherkey.
(a)
(b)
Figure 5.1 TEA Simulation Result (a) Cipherkey = 0x112233 44556677 8899AABB
CCDDEEFF (b) Cipherkey = 0x1F54EC0A B8EA73C9 ACRD561F A3C96E0F
The above mentioned figure shows two distinct results of TEA operation
performed with different cipherkey. Resulting output of segment (a) shown on Figure
5.1 was the first simulation process as the cross reference performed to ensure correct
output result. The outcome of cross reference in simulation process indicated that the
constructed TEA routine on Borland C is valid and verified.
5.2
Experimental Result
The first phase experimental result captured by terminal emulator showed that
the slave device sent message frame based on Modbus-RTU format. Figure 5.3
shows data transmission from PC to slave device and its respond back to PC. Before
commencing data transmission, slave device address is set to 0x31 and source code
of modbus transmission is set to reply received address. When receives incoming
data from master device, slave device analyzes the first segment of message data
whether it is sent to corresponding slave device. In other words, when slave device
received a message which is sent to address other than 0x31, as configured earlier,
the slave device will not respond to the request. As can be observed on the captured
transmission, the first line of data transmission sent address data of 0x32, 0x33, 0x34,
0x35, 0x36, and x37, which is indicated within red rectangular shape, to the slave
device where no responses sent by slave device.
Furthermore, the next transmission line captured that slave device respond to
the request data form PC recognizing address data was sent for address 0x31 which is
correct corresponding slave device. As a response, the receiving message from PC
indicated several data segment of modbus message protocol. Table 5.1 shows
summary of data transmission captured on terminal emulator. In addition, all
numbers listed on further tables are represented in hexadecimal numeric system
Transmission
Address
Function
Data
CRC
Lo
Hi
N/A
N/A
N/A
N/A
N/A
31
31
00
80
E1
F0
31, 31, 31
31
00
80
40
41
31, 32, 31
31
00
80
E1
F0
According to the data log summary table, transmission column shows distinct
separator from transmisision line 1 with the rest of data log. The data separated with
semicolon indicates the data was sent one-by-one, meaning that it was a single data
transmission from PC to slave device. On the other hand, line transmission 3 and 4
separated by comma indicates continous data transmission from one packet to
another. In other word, transmission line 3 and 4 sent three packet based on modbusRTU data frame format to slave device. As a response for transmission line 2 through
line 3, slave device sent error message to the request data. It is shown from function
column on reception segment that the data sent was 0x00 which indicates incorrect
function request sent by the PC. In response of incorrect function code, slave device
sent exception response code indicates that error received request on data column.
Transmission
Address
Function
Data
CRC
Lo
Hi
N/A
N/A
N/A
N/A
N/A
31
97
E9
80
E1
F0
31, 31, 31
7D
8B
69
81
1E
31, 32, 31
03
13
0B
81
F7
However, as
transmitted from host PC the slaved device performed decryption process for
receiving data. The result of decryption process modified received data by slave
device. As shown on Figure 5.5, slave device did not respond to host PC even though
correct corresponding request address was sent. The received data was modified thus
it was no longer represent corresponding slave device address. Therefore, it was
considered as different target address and slave device ignored the request. Table 5.3
shows detail summary of data transmission captured by emulator. It can be
concluded that transmission process was failed. To overcome this problem, correct
encryption routine should be performed on host PC.
Transmission
Address
Function
Data
CRC
Lo
Hi
N/A
N/A
N/A
N/A
N/A
31
N/A
N/A
N/A
N/A
N/A
31, 31, 31
N/A
N/A
N/A
N/A
N/A
31, 32, 31
N/A
N/A
N/A
N/A
N/A
CHAPTER 6
6.1
Conclusion
In the other hand, the resulting outcome of the project still does not reach a
complete system of Modbus protocol. Some improvements need to be performed to
fix current drawbacks of the proposed system. The function handler of Modbus-RTU
protocol and integration system with Tiny Encryption Algorithm are required to
improve
62
6.2
Recommendations
63
REFERENCES
1.
2.
3.
4.
Axelson, J. (1998). Serial Port Complete: Programming and Circuits for RS232 and RS-485 Links and Networks. Madison, W. I.: Lakeview Research.
5.
6.
7.
8.
9.
Liao, G. Y., Chen, Y. J., Lu, W. C., and Cheng, T. C. (2008). Toward
Authenticating the Master in the Modbus Protocol. IEEE Journal.
64
10.
11.
12.
13.
Modbus
Organization
(2006).
MODBUS
Application
Protocol.
14.
15.
16.
17.
18.
65
APPENDIX A
66
67
68
69
70
71
72
APPENDIX B
B.1
TEA.C
#include <conio.h>
#include <stdio.h>
void encipher(unsigned long *const v,unsigned long *const w,const unsigned long
*const k)
{
register unsigned long
y=v[0],z=v[1],sum=0,delta=0x9E3779B9,
a=k[0],b=k[1],c=k[2],d=k[3],n=32;
while(n-->0){
sum += delta;
y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
}
w[0]=y; w[1]=z;
}
73
void decipher(unsigned long *const v, unsigned long *const w, const unsigned long
*const k){
register unsigned long
y=w[0],z=w[1],sum=0xC6EF3720,delta=0x9E3779B9,
a=k[0],b=k[1],c=k[2],d=k[3],n=32;
while(n-->0){
z -= ((y << 4)+c) ^ (y+sum) ^ ((y >> 5)+d);
y -= ((z << 4)+a) ^ (z+sum) ^ ((z >> 5)+b);
sum -= delta;
}
w[0]=y; w[1]=z;
}
int main(){
unsigned long v[] = {0x01234567, 0x89abcdef};
unsigned long key[] = {0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff};
unsigned long res[2];
74
APPENDIX C
C.1
Main.h
#ifndef MAIN_H_
#define MAIN_H_
#endif MAIN_H_
75
C.2
Main.c
ISR(USART0_UDRE_vect)
{
vRTUTransmitBuffer();
PORTB ^= (1<<5);
_delay_ms(100);
PORTB ^= (1<<5);
}
76
ISR(TIMER1_COMPA_vect)
{
_delay_ms(100);
PORTB ^= (1<<7);
vTimerT35Expired();
}
uint8_t BufferTest;
while(1)
{
//TODO:: Please write your application code
vRTUPoll();
//usPollCycles++;
}
}
77
C.3
Modbus.h
#ifndef MODBUS_H_
#define MODBUS_H_
#include <stdint.h>
/*******************************************************************/
/* ----------------------- MODBUS TYPE DEFINITIONS --------------------------------*/
/*******************************************************************/
/* ----------------------- RTU Exception Codes ---------------------------------------------*/
typedef enum
{
RTU_EX_NONE = 0x00,
RTU_EX_ILLEGAL_FUNCTION = 0x01,
RTU_EX_ILLEGAL_DATA_ADDRESS = 0x02,
RTU_EX_ILLEGAL_DATA_VALUE = 0x03,
RTU_EX_SLAVE_DEVICE_FAILURE = 0x04,
} eRTUException;
/*******************************************************************/
/* ----------------------- MODBUS FRAME -------------------------------------------------*/
/*******************************************************************/
/* ----------------------- Defines ---------------------------------------------------------------*/
#define MASTER_ADDRESS
256
// Function Code
#define RTU_PDU_SIZE_MIN
253
78
#define RTU_SER_PDU_SIZE_CRC
#define RTU_SER_PDU_SIZE_ADDR
/*******************************************************************/
/* ----------------------- MODBUS PROTOTYPE ------------------------------------------*/
/*******************************************************************/
/* ----------------------- Defines -----------------------------------------*/
#define RTU_READ_COILS
#define RTU_READ_DI
#define RTU_READ_HOLD_REG
#define RTU_READ_IR
#define RTU_WRITE_COIL
#define RTU_WRITE_REG
#define RTU_READ_EXCEPTION
#define RTU_EXCEPTION
0x80
79
/* Modbus PDU
RTU_REQ_PDU(uint8_t ucFuncCode, uint8_t
ucDataFrame[RTU_PDU_SIZE_MAX] );
RTU_RSP_PDU(uint8_t ucFuncCode, uint8_t
ucDataFrame[RTU_PDU_SIZE_MAX]);*/
/* ----------------------- Modbus Initialization -----------------------------------------------*/
void vRTU_INIT(uint8_t ucSlaveAddress);
//void vRTUEnable(void);
void vRTUPoll(void);
#endif /* MODBUS_H_ */
80
C.4
Modbus.c
*/
RX_IDLE,
*/
RX_RECEIVE
*/
} eRTUReceiveState;
typedef enum
{
TX_IDLE,
TX_TRANSMIT
} eRTUSendState;
typedef enum
{
RTU_IDLE,
RTU_FRAME_RECEIVED,
RTU_PROCESSING,
RTU_FRAME_SENT
}eRTUProcess;
*/
81
/* ----------------------- Static variables ------------------------------------------------------*/
static volatile eRTUReceiveState
eReceiveState;
eSendState;
volatile uint8_t
ucRTUBuffer[RTU_SER_PDU_SIZE_MAX];
gusRcvBufferIndex;
*pucSendBuffer;
gusSendBufferIndex;
static eRTUProcess
eProcess;
static uint8_t
ucRTUSlaveAddress;
static uint32_t
sei();
}
82
void vRTUReceiveBuffer()
{
uint8_t ucBuffer;
/* Set transmitter to Idle Mode */
eSendState = TX_IDLE;
/* Get data received from USART */
vRTUGetChar(&ucBuffer);
switch(eReceiveState)
{
case RX_INIT:
vTimerEnable();
break;
case RX_IDLE:
/* Initialize buffer index value */
gusRcvBufferIndex = 0;
/* Received first character */
ucRTUBuffer[gusRcvBufferIndex] = ucBuffer;
/* Set next state to receiving process */
eReceiveState = RX_RECEIVE;
/* Enable t3.5 char timer */
vTimerEnable();
break;
case RX_RECEIVE:
/* Receiving data stream */
ucRTUBuffer[gusRcvBufferIndex++] = ucBuffer;
vTimerEnable();
break;
}
}
83
void vRTUReceive(uint8_t *pucAddress, uint8_t **pucDataFrame, uint16_t
*pusDataLength)
{
cli();
volatile uint32_t
TEABuffer[3];
uint16_t
usCRCBuf;
uint8_t
Buffer=24;
uint8_t
Counter;
int8_t
index;
/* CRC Check */
usCRCBuf = usRTUCRC(*ucRTUBuffer, gusRcvBufferIndex);
Decryptor(TEABuffer[0], TEAKey);
Counter = pusDataLength;
Buffer = 0;
index = -1;
84
while(Counter > -1)
{
ucRTUBuffer[index++] = (uint8_t)((TEABuffer[0]>>Buffer)& 0x000000FF);
Buffer += 8;
Counter--;
PORTB ^= (1<<6);
_delay_ms(50);
}
//if((gusRcvBufferIndex >= 2) && (usCRCBuf == 0))
//{
/* Get address value within serial PDU */
*pucAddress = ucRTUBuffer[RTU_SER_ADDRESS_OFF];
sei();
}
85
void vRTUTransmitBuffer(void)
{
/* Set receiver to idle state */
eReceiveState = RX_IDLE;
switch(eSendState)
{
case TX_IDLE:
/* Enable reception */
vRTUSerialPort(ENABLE, DISABLE);
break;
case TX_TRANSMIT:
if(gusSendBufferIndex != 0)
{
/* Send character over serial line*/
vRTUPutChar(*pucSendBuffer);
/* Point to next data in buffer */
pucSendBuffer++;
/* Estimate current data length */
gusSendBufferIndex--;
}
else
{
/* Update current process */
eProcess = RTU_FRAME_SENT;
/* Enable reception in serial port */
vRTUSerialPort(ENABLE, DISABLE);
/* Set transmitter to idle state */
eSendState = TX_IDLE;
}
break;
}
}
86
void vRTUTransmit(uint8_t ucSlaveAddress, const uint8_t *pucDataFrame, uint16_t
usDataLength)
{
uint32_t TEABuffer[3];
uint16_t usCRC;
uint8_t Buffer=0;
int8_t Counter;
int8_t index;
TEABuffer[0] = 0x00000000;
TEABuffer[1] = 0x00000000;
cli();
if(eReceiveState == RX_IDLE)
{
pucSendBuffer = (uint8_t *)pucDataFrame-1;
gusSendBufferIndex = 1;
Counter = 0;
87
while(Counter < usDataLength)
{
TEABuffer[0] |= ucRTUBuffer[Counter];
TEABuffer[0] = (TEABuffer[0]<<8);
Counter++;
PORTB ^= (1<<7);
_delay_ms(50);
}
Encryptor(TEABuffer, TEAKey);
index = -1;
Buffer = 0;
Counter = usDataLength;
88
void vTimerT35Expired()
{
/* Check current receiver's state */
switch(eReceiveState)
{
case RX_INIT:
/* Set event process to idle after initialization */
eProcess = RTU_IDLE;
break;
case RX_RECEIVE:
/* Report when whole frame is completely received */
eProcess = RTU_FRAME_RECEIVED;
break;
default:
break;
}
vTimerDisable();
eReceiveState = RX_IDLE;
}
void vRTUPoll()
{
static uint8_t
ucSlaveAddress;
static uint8_t
ucFunctionCode;
static uint8_t
*pucDataBuffer;
static uint16_t
usLengthBuffer;
static
eRTUException
eException;
89
switch (eProcess)
{
case RTU_IDLE:
PORTB ^= (1<<0);
_delay_ms(100);
//eReceiveState = RX_IDLE;
//vTimerEnable();
break;
case RTU_FRAME_RECEIVED:
PORTB ^= (1<<1);
case RTU_PROCESSING:
/* Get function code from data buffer */
ucFunctionCode = pucDataBuffer[RTU_PDU_FUNC_OFF];
90
/* Check function code */
switch(ucFunctionCode)
{
//case RTU_READ_COILS:
case 0x31:
eException = eRTUReadCoil(pucDataBuffer, usLengthBuffer);
break;
case RTU_WRITE_COIL:
//eException = eRTUWriteCoil();
break;
default:
/* If function is not supported send exception code */
eException = RTU_EX_ILLEGAL_FUNCTION;
break;
}
if(eException == RTU_EX_NONE)
{
vRTUTransmit(ucSlaveAddress, pucDataBuffer, usLengthBuffer);
}
else
{
/* Prepare exception code data frame */
PORTB ^= (1<<2);
usLengthBuffer = 0;
pucDataBuffer[usLengthBuffer++] = ucFunctionCode;
pucDataBuffer[usLengthBuffer++] = (ucFunctionCode + RTU_EXCEPTION);
vRTUTransmit(ucSlaveAddress, pucDataBuffer, usLengthBuffer);
}
_delay_ms(100);
PORTB ^= (1<<2);
break;
91
case RTU_FRAME_SENT:
/* Do nothing when transmit is completed */
eProcess = RTU_IDLE;
break;
}
}
C.5
Avrwise.h
#ifndef AVRWISE_H
#define AVRWISE_H
#include <stdint.h>
92
C.6
Avrwise.c
#include "main.h"
#include "avrwise.h"
uint8_t Dec7Seg[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uint8_t
Hex7Seg[16]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,
0xC6,0xA1,0x86,0x8E};
uint8_t n[3];
sbi(PORTA,(row+3));
PORTB = val;
cbi(PORTA,(row+3));
93
void Clr7Seg(uint8_t row)
{
DDRB = 0xFF; // Set direction to output
sbi(PORTA,(row+3));
PORTB = 0xFF;
cbi(PORTA,(row+3));
}
void ClrAll7Seg()
{
DDRB = 0xFF;
PORTA = 0x78;
PORTB = 0xFF;
PORTA = 0;
}
sbi(PORTA,(row+3));
PORTB = 0;
cbi(PORTA,(row+3));
}
void Idle7Seg()
{
DDRB = 0xFF;
sbi(PORTA,3);
94
uint8_t ReadDIP()
{
uint8_t buffer;
uint8_t ReadPB()
{
uint8_t buffer, adder, rShift;
rShift = 0;
adder = 0;
DDRB = 0;
cbi(PORTD,7);
//Turn on Buffer1
_delay_ms(1);
buffer = PINB;
sbi(PORTD,7);
95
else if ((buffer > 8) && (buffer != 0xFF)){
adder = 6;
rShift = 3;
}
return (buffer);
}
void Init_Board()
{
DDRA = 0x78;
PORTA = 0;
DDRB = 0xFF;
PORTB = 0;
96
C.7
Rtucrc.h
#ifndef RTUCRC_H_
#define RTUCRC_H_
#include <stdint.h>
uint16_t usRTUCRC(uint8_t *pucDataFrame, uint16_t usDataLength);
#endif RTUCRC_H_
C.8
Rtucrc.c
#include "rtucrc.h"
97
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
98
uint16_t usRTUCRC(uint8_t *pucDataFrame, uint16_t usDataLength)
{
uint8_t ucCRCHi = 0xFF;
uint8_t ucCRCLo = 0xFF;
int8_t iIndex;
while(usDataLength--)
{
iIndex = ucCRCLo ^ *pucDataFrame++;
ucCRCLo = (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);
ucCRCHi = aucCRCLo[iIndex];
}
return (uint16_t)((ucCRCHi << 8) | ucCRCLo);
}
C.9
TEA.h
#ifndef TEA_H_
#define TEA_H_
#include <stdint.h>
void Encryptor(uint32_t *const ulPlaintext, /*uint32_t *const ulCiphertext,*/
uint32_t *const Cipherkey);
void Decryptor(/*uint32_t *const ulCiphertext,*/ uint32_t *const ulPlaintext,
uint32_t *const Cipherkey);
#endif TEA_H_
99
C.10
TEA.c
MSB = ulPlaintext[0];
LSB = ulPlaintext[1];
sum = 0;
delta = 0x9E3779B9;
a = Cipherkey[0], b = Cipherkey[1], c = Cipherkey[2], d = Cipherkey[3];
while(n-->0)
{
sum += delta;
MSB += (LSB << 4)+a ^ (LSB+sum) ^ (LSB >> 5)+b;
LSB += (MSB << 4)+c ^ (MSB+sum) ^ (MSB >> 5)+d;
}
100
while(n-->0)
{
LSB -= ((MSB << 4)+c) ^ (MSB+sum) ^ ((MSB >> 5)+d);
MSB -= ((LSB << 4)+a) ^ (LSB+sum) ^ ((LSB >> 5)+b);
sum -= delta;
}
C.11
Deviceport.h
#ifndef DEVICEPORT_H_
#define DEVICEPORT_H_
1
0
UDR0
#define RXEN
(1<<RXEN0)
#define TXEN
(1<<TXEN0)
#define RXCIE
(1<<RXCIE0)
#define TXCIE
(1<<TXCIE0)
#define UDRIE
(1<<UDRIE0)
#define UDRE
(1<<UDRE0)
#endif DEVICEPORT_H_
101
C.12
Deviceinit.c
void UART_Init(void)
{
// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 9600
UCSR0A=0x00;
UCSR0B = 0;
UCSR0B |= (RXCIE)|(UDRIE)|(RXEN)|(TXEN);
UCSR0C =0x06;
UBRR0H=0x00;
UBRR0L=0x81;
102
void Device_Init(void)
{
cli();
Port_Init();
UART_Init();
MCUCR = 0;
sei();
}
C.13
Deviceserial.c
103
if(TXEnable == 1)
{
UCSR0B |= TXEN|UDRIE;
}
else
{
UCSR0B &= ~(UDRIE);
}
}
104
C.14
Devicetimer.c
// In second
#define TIMER_MS
1000
#define TIMER_PRESCALER
1024UL
#define TIMER_CLOCK
(F_CPU/TIMER_PRESCALER)
usTimerCount = (TIMER_CLOCK*TIMER_DELAY/TIMER_MS)-1;
TCCR1A = 0x00;
TCCR1B = 0x00;
TCCR1C = 0x00;
TIFR1 |= (0<<OCF1A);
TIMSK1 = (0<<OCIE1A);
}
105
void vTimerEnable()
{
TCNT1 = 0x0000;
void vTimerDisable()
{
/* Clear flag timer compare interrupt */
TIFR1 |= (0<<OCF1A);
106
C.15
Rtufunccoils.c
RTU_SER_PDU_DATA_OFF
#define RTU_PDU_FREAD_COIL_OFF
RTU_SER_PDU_DATA_OFF+2
#define RTU_PDU_FREAD_SIZE
#define RTU_PDU_FREAD_COIL_MAX
0xFF
#define RTU_PDU_FWRITE_ADDR_OFF
RTU_SER_PDU_DATA_OFF
#define RTU_PDU_FWRITE_VAL_OFF
RTU_SER_PDU_DATA_OFF+2
#define RTU_PDU_FWRITE_SIZE
ucCoilAddress[6];
usRegisterAddress;
uint16_t
usCoilIndex;
uint8_t
ucData;
uint8_t
*pucFrameBuffer;
eRTUException
eXStatus = RTU_EX_NONE;
107
if(*pusDataLength == (RTU_PDU_FREAD_SIZE + RTU_PDU_SIZE_MIN))
{
/* Get target address */
usRegisterAddress =
(uint16_t)(pucDataFrame[RTU_PDU_FREAD_ADDR_OFF]<<8);
usRegisterAddress |=
(uint16_t)pucDataFrame[RTU_PDU_FREAD_ADDR_OFF+1];
usRegisterAddress++;
usCoilIndex =
(uint16_t)(pucDataFrame[RTU_PDU_FREAD_COIL_OFF]<<8);
usCoilIndex |=
(uint16_t)(pucDataFrame[RTU_PDU_FREAD_COIL_OFF+1]);
}
}
108
}
else
{
/* Set exception status for invalid data */
eXStatus = RTU_EX_ILLEGAL_DATA_VALUE;
}
return eXStatus;
}
usRegisterAddress;
uint8_t
ucBuffer[2];