Beruflich Dokumente
Kultur Dokumente
Professor: Jia Xu
TA: Navid Mohaghegh
by: Dusan Putnikovic & Zhou Wu
Student #: 211078664, 212613931
Date: April 4, 2017
!
Table of Contents
A. Describe the key hardware and software components of the real-time embedded system application
using the MicroC/OS-II real-time multitasking operating system kernel, the MC9S12DP256B
microcontroller, within the CodeWarrior IDE environment, that you have designed and implemented in
A2.
Software: OS-Probe-LCD application source code. Some extra functions which are newly
Function list:
B. Describe how to set up and operate the key hardware components, and how to setup, compile,load,
execute, and debug the key software components that constitutes the real-time embedded system
application using the MicroC/OS-II real-time multitasking operating system kernel, the MC9S12DP256B
microcontroller, within the CodeWarrior IDE environment, that you have designed and implemented in
A2 above step-by-step. You should include screen-shots and photos to illustrate each step. For each major
step, you should explain what should be a valid result for that step, how to determine that the result for
1 of 18
1 Setup and Key Hardware Operation
Plug in the dragon board, connect the servo motor with the board through port PP7. Open the
OS-Probe-LCD application through CodeWarrior IDE environment. There are some extra
functions implemented based on the existing application. There are two major parts of the
dragon board involved, including LCD display screen, keypad input. LCD screen is used for
Compile, load and execute: When user open the modified OS-Probe-LCD application through
CodeWarrior, he/she click the make button ! which resides on the top and pick the HCS12
Then the application will start compiling. After compiling, user can proceed the application by
clicking start button ! . Then the compiled program will be uploaded to the board. If it is
the first time you are running the program you may need to setup the PC’s serial port as shown
below. To figure out what the port you should use, user need to go to control panel and check
the port number associated with the board. Once the right port is picked, user can run the
2 of 18
!
The implemented application contains two extra functionalities, including authentication, degree
2 Authentication
In order to use the Dragon 12 board, our group implemented an authentication method as part
of our project. The one-step password authentication runs when the application code is
executed and prompts the user for a password. The authentication has three components that
are used for successful and unsuccessful attempts. The three components for authentication
that are utilized are Seven segment display, LCD display and Keypad. Firstly an LCD message
is displayed asking the user to enter their password, with the option to reset their entry by
pressing * or submit with # key on the Keypad. The user enters their password one character at
a time using the keypad which activates after the password instructions are displayed on the
3 of 18
LCD screen. The instructions take six seconds to display after which the keypad read task is
enabled in order to read user entry. The LCD screen is still active at this time, displaying a
! ! !
Pictured above left to right: The enter password prompt, user entered B, user entry is masked
in the top row. Once a key is pressed the bottom row shows a message with user entered key.
“You entered %c”. This is displayed for half a second, after which the key entered is masked
with the message “You entered *.” in order to improve security by not allowing the whole or parts
Upon entering the password, which consists of a series of keypad values [0-9, A-D], the user
submits the password with pressing the ‘#’ key. A message saying “Successful” appears,
followed by the welcome screen describing the second part of our project. At the point when the
# key is pressed, and the user is successfully authenticated the keypad is briefly disabled for the
scrolling welcome message. Finally the keypad is re-enabled in order to allow for the user entry
4 of 18
!
In the case that a user enters an incorrect password, we display a message “Bad password”
for half a second on the LCD screen, and reset the password entered field in order to allow the
user to enter a new password attempt. In order to prevent unauthorized access to the board, by
stalling further password entering attempts, upon entering five incorrect passwords, a system
message on the LCD says “System locked.” and locks the keypad, thus preventing further
entries. With the keypad disabled, the seven segment displays the number of seconds
remaining until the keypad is unlocked giving another five attempts. This is a very low level
intrusion prevention that can be enhanced much further with few modifications. For example:
upon five incorrect entries the keypad could be disabled permanently, requiring a system reset
a longer delay time, of several hours could be displayed on the seven segment, while the
a method could be called that uses Internet connectivity to notify a monitor that a user is
! !
Left: If a bad password is entered we display. Right: After five unsuccessful attempts, the
on Seven Segment.
5 of 18
2.3 Authentication background
Authentication process consists of several important functions in the app.c code that work in
addition to the KeypadRdTask. These functions are BadPasswordBlock(int n), that unblocks the
seven segment display and prompts it to show a countdown timer of seconds specified by the
length and whether or not the password is correct. As well as PasswordReset(CPU_INT08U *p)
that takes the password entered so far and resets it upon user entering the * key on the Dragon
12 board keypad.
For the degree entry for changing servo motor, if the authentication is passed, user can enter a
degree to make servo motor rotate certain amount of degrees by entering ‘*’ on the keypad. As
shown below. By pressing ‘*’, the old degree will be cleared, and user can start entering the new
degree.
6 of 18
!
If “#” key is pressed, the application will stop reading any value from keypad and the function
will convert the array that stores the digits into an integer value. Then the servo motor will start
rotating.
If neither “*” nor “#” is pressed, any number that user press from the keypad will be stored into
an array. The array will be converted into an integer value for rotating servo motor. As shown
below
7 of 18
!
C. Explain the methods and techniques that are used in the design and implementation of your real-time
embedded system application in order for the system to match its requirements.
4 Our Functions
password resetting, and servo angle rotation selection we implemented the following functions:
4.1 WelcomeAndRotateServo
8 of 18
"to a powerful servo engine "
"that can rotates 90 degrees"
"to a servo motor. "
"To rotate the servo, please "
"enter * to start inputting the "
"degree you want the servo to rotate "
"and enter # to make the servo start "
"rotating." };
(2)CPU_INT08U *aboutStrPtr;
(3)CPU_INT08U key;
(4)CPU_INT08U out_str[17];
(5)CPU_INT08U degree[17];
(6)int angular = 180;
(7)int count;
(8)CPU_INT08S i;
(9)CPU_INT08U err;
(10)aboutStrPtr = aboutStr;
(11)for (i = 15; i >= 0; i--) {
if (*aboutStrPtr != '\0') {
DispStr(0, i, aboutStrPtr);
OSTimeDlyHMSM(0, 0, 0, 100);
}
}
(12)while ((aboutStr + sizeof(aboutStr) - aboutStrPtr) > 16) {
DispStr(0, 0, aboutStrPtr++);
OSTimeDlyHMSM(0, 0, 0, 100);
}
(13)for (i = 15; i >= 0; i--) {
if (*aboutStrPtr != '\0') {
DispStr(0, 0, aboutStrPtr++);
DispChar(0, i, ' ');
OSTimeDlyHMSM(0, 0, 0, 100);
}
}
9 of 18
(35) err = sprintf(out_str, "You entered %c ", p[key]);
(36) DispStr(1, 0, out_str);
(37) OSTimeDlyHMSM(0, 0, 0, 500);
(38) degree[count] = p[key];
(39) count = count + 1;
(40) OSTimeDlyHMSM(0, 0, 0, 500);
(41) }
(42) OSTimeDlyHMSM(0, 0, 0, 500);
(43) }
(44) return 0;
(45) }
(1)This function firstly triggers the dragon board LCD screen to display a introduction message--
The dragon board is connected to a powerful servo engine that can rotates 90 degrees to a
servo motor. To rotate the servo, please enter * to start inputting a degree you want the servo to
rotate and enter # to make the servo start rotating. The message will show up once.
(5) Declare a char array, this char array stores the degree value that user enters
(6) Declare an int variable named angular, which stores the degree that servo motor going to
(7) Declare an int variable named index. It is the index of degree array.
(12)If there are greater than 16 characters left to display, display them till there are 16
characters left
10 of 18
(18) If nothing is entered, then LCD displays that keypad is idle.
(22) LCD screen displays that the old degree array is cleared and enter a new degree
(30) Apply modulo operation on angular by 20 since servo only spins within 20 degrees.
(31) Increase angular by 175 since servo only start spinning between 175 and 195.
(34 - 39) If neither “*” nor “#” is pressed, the number value user entered will be put into degree
4.2 PasswordReset
4.3 BadPasswordBlock
static int BadPasswordBlock(int num){
(1) OSTaskResume(6);
(2) SevenSegDisp_Init();
(3) while (num >= 0) {
(4) SevenSegWrite(num);
(5) OSTimeDlyHMSM(0, 0, 1, 0);
(6) num = (num - 1);
(7) }
(8) return 0;
(9) }
11 of 18
(1) Resume the Seven Segment task that is responsible for seven segment display
(2) Initialize the display
(3) While the number passed to BadPasswordBlock is not less than 0
(4) Write the number
(5) & (6) Decrement the number by one each second
(6) Returns 0, this return is not used by our app.c
4.4 PassVerify
static int PassVerify(CPU_INT08U *p){
(1) CPU_INT08U passcode[4] = {"4352"};
(2) int i = 0;
(3) for(; i < 4; i++){
(4) if(p[i] != passcode[i]){
(5) return 0;
(6) }
(7) }
(8) if(p[i] != 0){
(9) return 0;
(10) }
(11) else{
(12) return 1;
(13) }
(14) }
(1) Declare an array that stores the right password which is “4352”
(2) Declare an integer i for indexing array which is passed
(4) For the for loop, it compares the array which stores the real password and the
array which was entered by user by checking on character at time.
(5) If the elements are different, return 0, which stands for false.
(6) If the elements are equal, go to the next element.
(8 - 9) If the two arrays are equal, check the 5th position of the array which was
entered by user. If the 5th position is empty, return 1, which means ture.
Otherwise, user entered a string that contains string, but it is not the real
password.
4.5 KeypadRdTask
static void KeypadRdTask (void *p_arg)
{
(1) CPU_INT08U key;
(2) CPU_INT08U out_str[17];
(3) CPU_INT08U out_str1[17];
(4) CPU_INT08U res[17];
(5) CPU_INT08U authSucess = 0;
(6) CPU_INT08U key_map[] = {'1', '2', '3', 'A',
12 of 18
'4', '5', '6', 'B',
'7', '8', '9', 'C',
'*', '0', '#', 'D'
};
(7) CPU_INT08U err;
(8) // int rotateAngle = 55;
(9) // CPU_INT08U angular[17];
(10 )int i = 0;
(11 )int count = 0;
(12) int passAttempts = 5;
(13) (void)p_arg;
(14) KeypadInitPort();
(15) keypadEnFlagGrp = OSFlagCreate(0, &err);
(16)while (err != OS_NO_ERR) {
(17) OSTimeDlyHMSM(0, 0, 1, 0);
(18) keypadEnFlagGrp = OSFlagCreate(0, &err);
(19) }
(20) OSFlagPend(keypadEnFlagGrp, 0x01, OS_FLAG_WAIT_SET_ALL, 0, &err);
(21)DispClrLine(0);
(22) DispClrLine(1);
(23)while (DEF_TRUE ) {
(24) OSFlagPend(keypadEnFlagGrp, 0x01, OS_FLAG_WAIT_SET_ALL,0,&err);
(25) key = KeypadReadPort();
(26) if (key == 0xFF) {
(27) if (passAttempts > 0 && PassVerify(res) == 0 )
(28) {err = sprintf(out_str, "Enter password:");
(29) DispStr(0,0, out_str);
(30) OSTimeDlyHMSM(0,0,0,500);
(31) }
(32) if (passAttempts == 0 && PassVerify(res) == 0)
(33) {err = sprintf(out_str, "System locked!");
(34) OSFlagPost(keypadEnFlagGrp, 0x01, OS_FLAG_CLR, &err);
(35) for (i = 0; i < 3; i= i+1){
(36) DispStr(0,0, out_str);
(37) OSTimeDlyHMSM(0,0,0,500);
(38) DispClrLine(0);
(39) OSTimeDlyHMSM(0,0,0,300);
(40) }
(41) BadPasswordBlock(30);
(42) OSFlagPost(keypadEnFlagGrp, 0x01, OS_FLAG_SET, &err);
(43) passAttempts = 5;
(44) }
(45) } else if (key_map[key] == '*'){
(46) sprintf(out_str, "Clearing entry");
(47) count = PasswordReset(res);
(48) DispStr(1,0, out_str);
(49) OSTimeDlyHMSM(0,0,0,500);
(50) }
(51) else if (key_map[key] == '#') {
(52) DispClrLine(1);
(53) OSTimeDlyHMSM(0,0,0,500);
(54) if(PassVerify(res)){
(55) err = sprintf(out_str, "Successful! ");
(56) DispStr(0,0, out_str);
(57) OSTimeDlyHMSM(0, 0, 0,500);
(58) count = ShowWelcomeStr();
13 of 18
(59) OSTimeDlyHMSM(0,0,0,500);
(60) WelcomeAndRotateServo(key_map);
(61) }
(62) else{
(63 ) passAttempts = passAttempts - 1;
(64) err = sprintf(out_str, "Bad Password! ");
(65) err = sprintf(out_str1, "Attempts left: %d", passAttempts);
(66) DispStr(0,0, out_str);
(67) DispStr(1,0, out_str1);
(68) OSTimeDlyHMSM(0,0,0,500);
(69) DispClrLine(0);
(70) DispClrLine(1);
(71) count = PasswordReset(res);
(72) }
(73) }
(74) else {
(75) err = sprintf(out_str, "You entered %c ", key_map[key]);
(76) DispStr(1,0, out_str);
(77) OSTimeDlyHMSM(0,0,0,500);
(78) err = sprintf(out_str, "You entered * ");
(79) DispStr(1,0, out_str);
(80) res[count] = key_map[key];
(81) count = count + 1;
(82) OSTimeDlyHMSM(0,0,0,500);
(83) }
(84) OSTimeDlyHMSM(0, 0, 0 ,500);
(85) }
(86) }
14 of 18
(23) All tasks bodies include an infinite loop
(24) Suspend the task if flag 0 has been cleared
(25) Scan the keypad. Returns 0-15 or 0xFF if nothing pushed
(27) if still have pass attempts remaining and password verification is unsuccessful
(28) Prompt the user to enter the password
(29) Display the string
(30) 500 ms delay
(32) if password attempts are maxed out, and wrong password on final attempt
(33) Display a string which states that system is locked
(35 - 40) Continue displaying string that system is locked for 3 more times, each time
system will be delayed for 500ms
(41) After displaying string, call BadPasswordBlock function to lock the keypad for 30
seconds
(42) enable the keypad for password entry
(43) reset the passAttempts to 5
(45 - 50) If ‘*’ is pressed, application will clear the current array which stores the
password, and enables user to reenter it.
(51 - 54) If ‘#’ is pressed, application will check if the password user entered is equal to
the real password.
(55) Copy the string “Succesful to output string
(56 & 57) Display the output string for half a second
(58) Reset the count to 0, from return value of ShowWelcomeStr() and display
greeting
(59) Delay the system for half a second
(60) WelcomeAndRotateServo function which instructs on how to & operates servo
(63) If password is not correct, decrease the number of attempts by 1
(64) Copy the string “Bad Password” into the output for row 1
(65) Copy the string “Attempts left” into the output for row 2
(66) Display output for row 1
(67) Display output for row 2
(68) Delay the system for half a second for the displays to persist briefly
(69 & 70) Clear LCD display rows 1 and 2
(71) Reset the index of the password array to 0 and clear all array elements
(75) Copy the string “You entered %c” into the output
(76) Display the output on the bottom row
(77) Delay the system for half a second for the output string to persist
(78) Replace the previous output by “You entered *” in order to mask the %c entered
(79) Display the new output
(80) Array for the password entered at index count becomes the %c entered
(81) Increase the count for indexing password array by 1
15 of 18
(82) Delay system for half a second to prevent multiple recordings of single key press
(83) Delay system for half a second to prevent multiple recordings of single key press
D. Perform a critical analysis of the performance and correctness of your real-time embedded system
application. Explain what tests you have performed in order to demonstrate the performance and
5 Our Tests
Our tests show the correctness of the program and full functionality of the keypad entry, LCD
display, seven segment display and change_servo function, along with appropriate disabling
and enabling of specific task related functions. There have been no issues with mutual
exclusion, as our priorities set up in priority configuration header work smoothly with the
implementation of our authentication and servo changing functions. In our app.c we use micro C
built in disabling and enabling of Dragon 12 board components in order to accommodate our
specific needs.
The authentication currently works in converting a keypad input of integers into a string array.
What is wrong is that the keypad also reads alphabetic characters [A-D] as integer inputs,
therefore an ASCII code for the alphabetic character could in theory replace an appropriate
16 of 18
The servo function uses modularity in ordering the servo to spin to a certain degree. Because
the servo can only rotate in a range of 175 to 195 degrees, our function is the following:
on the keypad will always make the servo rotate. For example an entry of 365, which is greater
than the angle 195 degrees, would rotate the servo to (365%20)+175 = 5 + 175 = 180 degrees.
Similarly if the user were to enter 35 degrees, which is below the lower boundary of 175
degrees would spin the servo (35%20)+175 = 15 + 175 = 190 degrees. This is an error catching
mechanism that ensures that the servo always rotates and does not malfunction. However, our
program is not designed to fully implement the servo yet, and as such we expect that the user
will enter an error-free input, thus not entering characters [A-D], or a value outside the scope of
Test 1:
Change servo motor to a degree that is greater than the range of servo’s functionality
Test 2:
6 Difficulties Encountered
During the project our group worked endlessly on creating the password authentication and our
project originally began with the authentication system in mind. Having spent most of our time
on that major component of this project, we were left with little implementation time for the
change_servo function. Initially our main problem for the change_servo function was to convert
the sequence of keypad entries by the user into a valid degree of angle for the servo function to
use. However, with little time left to implement we allowed the servo would rotate arbitrarily. Our
difficulty was to ensure the user entry was error free, and this would involve a lot of type
checking and cases where the user would enter invalid input. We chose to overcome this
difficulty by assuming that the user will enter correct input each time (no alphanumeric entries)
or unpredictable inputs. However, even this was not enough, because our servo function would
make an initial input incorrect. This would cause a rotation to an unknown angle at first until the
17 of 18
user pressed * to clear the entry and typed in a new value. The way we solved the servo
rotation problem was to use modularity function on the user input, thus if a user entered an
incorrect angle (less than 175 degrees or greater than 195 degrees) we would use modularity to
determine a new angle. The formula for determining the angle is (user_entry%20)+ 175. This
would ensure that a degree of angle passed to the servo was always between 175 and 195.
Fin
18 of 18