Init commit
- Import assignment 1 files and repo - Assignment 2 code
This commit is contained in:
commit
0f28637aed
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# General
|
||||||
|
doc/
|
||||||
|
hex/
|
||||||
|
micro2019/
|
||||||
|
deliver/
|
||||||
|
|
||||||
|
# Eclipse-Atollic related
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.settings/
|
||||||
|
*.ld
|
||||||
|
Debug/
|
||||||
|
Release/
|
||||||
|
|
||||||
|
# Keil related
|
||||||
|
Keil/
|
||||||
|
*.gz
|
||||||
|
*.zip
|
9
.gitmodules
vendored
Normal file
9
.gitmodules
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[submodule "assignment_1/report/config"]
|
||||||
|
path = assignment_1/report/config
|
||||||
|
url = https://git.hoo2.net/hoo2/LaTeX_confing.git
|
||||||
|
[submodule "assignment_2/report/config"]
|
||||||
|
path = assignment_2/report/config
|
||||||
|
url = https://git.hoo2.net/hoo2/LaTeX_confing.git
|
||||||
|
[submodule "assignment_2/Libraries/STM32CubeF4"]
|
||||||
|
path = assignment_2/Libraries/STM32CubeF4
|
||||||
|
url = https://github.com/hoo2/STM32CubeF4.git
|
121
assignment_1/main.c
Normal file
121
assignment_1/main.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* main.c
|
||||||
|
* @brief
|
||||||
|
* A palindrome implementation and testing application
|
||||||
|
* for A.U.TH. Microprocessors and peripherals Lab.
|
||||||
|
*
|
||||||
|
* Created on: May 1, 2020
|
||||||
|
* Author: Christos Choutouridis AEM: 8997
|
||||||
|
* email : <cchoutou@ece.auth.gr>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The RAM address to use for palindrome result.
|
||||||
|
* @note:
|
||||||
|
* Select a RAM location above `__initial_sp`. See your startup_xx.s for details.
|
||||||
|
* Keil's RAM layout is:
|
||||||
|
*
|
||||||
|
* RAM: |<-Heap_Size-><-Stack_Size->|<- WASTED RAM SPACE ->|
|
||||||
|
* ^ ^ ^
|
||||||
|
* | | |
|
||||||
|
* Start:0x20000000 __initial_sp End of RAM
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define RESULT 0x20001000
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* String length calculation.
|
||||||
|
* @arg src{R0} Pointer to string
|
||||||
|
* @return {R0} String length, -1 if src is NULL
|
||||||
|
*/
|
||||||
|
__asm uint32_t strLength (const char* src) {
|
||||||
|
// R0: length, return value
|
||||||
|
// R1: src
|
||||||
|
// R2: v = *src
|
||||||
|
MOV R1, R0 // Get variable
|
||||||
|
CMP R1, #0 // if (src{R1} == NULL)
|
||||||
|
MOVEQ R0, #-1 // return -1;
|
||||||
|
BXEQ LR
|
||||||
|
MOV R0, #0 // length{R0} =0;
|
||||||
|
len_loop // do {
|
||||||
|
LDRB R2, [R1], #1 // v{R2} = *src++;
|
||||||
|
CMP R2, #0 // if(v)
|
||||||
|
ADDNE R0, R0, #1 // ++length{R0};
|
||||||
|
BNE len_loop // } while (v);
|
||||||
|
BX LR // return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* A string palindrome predicate.
|
||||||
|
* @note
|
||||||
|
* We use a simple O(n), no stack algorithm.
|
||||||
|
* @note
|
||||||
|
* This function also writes to RAM address @ref RESULT the return value (which is nasty).
|
||||||
|
* @arg src{R0} Pointer to string
|
||||||
|
* @return {R0} True if palindrome, false if not or src is NULL pointer
|
||||||
|
* @note
|
||||||
|
* We consider an empty string "" to be a palindrome, as we can see it the same way both
|
||||||
|
* from the front and the back.
|
||||||
|
*/
|
||||||
|
__asm uint32_t isPalindrome (const char* src) {
|
||||||
|
// R0: src[]
|
||||||
|
// R1: i
|
||||||
|
// R2: j
|
||||||
|
// R3: v1 = src[i]
|
||||||
|
// R4: v2 = src[j]
|
||||||
|
PUSH {R4, LR}
|
||||||
|
CMP R0, #0 // if (src{R0} == NULL)
|
||||||
|
BEQ pal_false // return false;
|
||||||
|
MOV R4, R0 // save R0
|
||||||
|
BL strLength // j{R2} = strLength(src) - 1
|
||||||
|
SUB R2, R0, #1
|
||||||
|
MOV R0, R4 // src{R0}
|
||||||
|
MOV R1, #0 // i{R1} =0;
|
||||||
|
|
||||||
|
pal_loop
|
||||||
|
CMP R1, R2 // while (i<j) {
|
||||||
|
BGE pal_true
|
||||||
|
LDRB R3, [R0, R1] // v1 = *src[i];
|
||||||
|
LDRB R4, [R0, R2] // v2 = *src[j];
|
||||||
|
CMP R3, R4 // if (v1 == v2) {
|
||||||
|
ADDEQ R1, R1, #1 // ++i;
|
||||||
|
SUBEQ R2, R2, #1 // --j;
|
||||||
|
BEQ pal_loop // // goto loop;
|
||||||
|
pal_false // } else
|
||||||
|
MOV R0, #0 // return *RESULT = 0;
|
||||||
|
LDR R1, =RESULT
|
||||||
|
STRB R0, [R1]
|
||||||
|
POP {R4, PC}
|
||||||
|
// }
|
||||||
|
pal_true
|
||||||
|
MOV R0, #1 // return *RESULT = 1;
|
||||||
|
LDR R1, =RESULT
|
||||||
|
STRB R0, [R1]
|
||||||
|
POP {R4, PC}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Main routine.
|
||||||
|
* @note
|
||||||
|
* This routine plays the role of debuging-mode unit testing.
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
const char *s1 = "hello world!"; // Not a palindrome
|
||||||
|
const char *s2 = "aibohphobia"; // Aibophobia def= "Irational fear of palindromes", palindrome.
|
||||||
|
const char *s3 = ""; // Empty string, palindrome.
|
||||||
|
const char *s4 = 0; // NULL pointer. Out of scope, not palindrome
|
||||||
|
|
||||||
|
uint32_t res1 = isPalindrome (s1); // Test case 1
|
||||||
|
uint32_t res2 = isPalindrome (s2); // Test case 2
|
||||||
|
uint32_t res3 = isPalindrome (s3); // Test case 3
|
||||||
|
uint32_t res4 = isPalindrome (s4); // Test case 4
|
||||||
|
|
||||||
|
while (1); // Trap forever
|
||||||
|
//return 0; //!< comment out return, to suppress "statement is unreachable" warning.
|
||||||
|
//!^ @note:
|
||||||
|
//! **Weird** Keil's way for "statement is unreachable", suppresion.
|
||||||
|
|
||||||
|
}
|
1
assignment_1/report/config
Submodule
1
assignment_1/report/config
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit ddb6624bbf227f98db5d25ae7b2a5698719fc17b
|
BIN
assignment_1/report/images/RAM_layout.png
Normal file
BIN
assignment_1/report/images/RAM_layout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
337
assignment_1/report/images/RAM_layout.svg
Normal file
337
assignment_1/report/images/RAM_layout.svg
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="210mm"
|
||||||
|
height="297mm"
|
||||||
|
viewBox="0 0 210 297"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||||
|
sodipodi:docname="RAM_layout.svg"
|
||||||
|
inkscape:export-filename="/home/hoo2/Software/AUTH/Micro/assignement_1/report/images/RAM_layout.svg.png"
|
||||||
|
inkscape:export-xdpi="600"
|
||||||
|
inkscape:export-ydpi="600">
|
||||||
|
<defs
|
||||||
|
id="defs2">
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow2Mstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4546"
|
||||||
|
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
|
||||||
|
transform="scale(0.6) translate(0,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow1Lstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0.0"
|
||||||
|
refX="0.0"
|
||||||
|
id="Arrow1Lstart"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
id="path4522"
|
||||||
|
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||||
|
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
|
||||||
|
transform="scale(0.8) translate(12.5,0)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mstart-4"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4546-8"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mstart-4-5"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4546-8-2"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mstart-6"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4546-4"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mstart-6-1"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4546-4-4"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(0.6)" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
inkscape:stockid="Arrow2Mstart"
|
||||||
|
orient="auto"
|
||||||
|
refY="0"
|
||||||
|
refX="0"
|
||||||
|
id="Arrow2Mstart-6-1-1"
|
||||||
|
style="overflow:visible"
|
||||||
|
inkscape:isstock="true">
|
||||||
|
<path
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path4546-4-4-7"
|
||||||
|
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||||
|
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||||
|
transform="scale(0.6)" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.4"
|
||||||
|
inkscape:cx="162.42672"
|
||||||
|
inkscape:cy="791.2836"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:snap-page="false"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1011"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
id="g6178"
|
||||||
|
inkscape:export-xdpi="600"
|
||||||
|
inkscape:export-ydpi="600">
|
||||||
|
<rect
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
y="45.689461"
|
||||||
|
x="21.946363"
|
||||||
|
height="73.879112"
|
||||||
|
width="23.566633"
|
||||||
|
id="rect10" />
|
||||||
|
<g
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
id="g5613">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart)"
|
||||||
|
d="m 47.634183,46.875398 h 5.565965"
|
||||||
|
id="path4520"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot4836"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,2.286756,-2.1733631)"><flowRegion
|
||||||
|
id="flowRegion4838"><rect
|
||||||
|
id="rect4840"
|
||||||
|
width="107.85714"
|
||||||
|
height="61.07143"
|
||||||
|
x="197.14285"
|
||||||
|
y="153.23396" /></flowRegion><flowPara
|
||||||
|
id="flowPara4842"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial">End of RAM</flowPara></flowRoot> </g>
|
||||||
|
<g
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
id="g5613-9"
|
||||||
|
transform="translate(0,71.746594)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-6)"
|
||||||
|
d="m 47.634183,46.875398 h 5.565965"
|
||||||
|
id="path4520-9"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot4836-0"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,2.286756,-2.1733631)"><flowRegion
|
||||||
|
id="flowRegion4838-8"><rect
|
||||||
|
id="rect4840-9"
|
||||||
|
width="107.85714"
|
||||||
|
height="61.07143"
|
||||||
|
x="197.14285"
|
||||||
|
y="153.23396" /></flowRegion><flowPara
|
||||||
|
id="flowPara4842-3"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial">0x20000000</flowPara></flowRoot> </g>
|
||||||
|
<path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5765"
|
||||||
|
d="M 21.878451,112.45039 H 45.302185"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<flowRoot
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-21.166366,67.028655)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="flowRoot4836-0-6-7"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-1"><rect
|
||||||
|
y="153.23396"
|
||||||
|
x="197.14285"
|
||||||
|
height="66.627274"
|
||||||
|
width="98.260719"
|
||||||
|
id="rect4840-9-7-2" /></flowRegion><flowPara
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="flowPara4842-3-3-2">data</flowPara></flowRoot> <path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5765-1"
|
||||||
|
d="M 21.949511,106.23637 H 45.302186"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<flowRoot
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-20.665449,60.530144)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="flowRoot4836-0-6-7-5"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-1-0"><rect
|
||||||
|
y="153.23396"
|
||||||
|
x="197.14285"
|
||||||
|
height="66.627274"
|
||||||
|
width="98.260719"
|
||||||
|
id="rect4840-9-7-2-9" /></flowRegion><flowPara
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="flowPara4842-3-3-2-0">bss</flowPara></flowRoot> <flowRoot
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-25.394187,54.279243)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="flowRoot4836-0-6-7-5-3"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-1-0-7"><rect
|
||||||
|
y="153.23396"
|
||||||
|
x="197.14285"
|
||||||
|
height="66.627274"
|
||||||
|
width="98.260719"
|
||||||
|
id="rect4840-9-7-2-9-4" /></flowRegion><flowPara
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="flowPara4842-3-3-2-0-1">Heap_Size</flowPara></flowRoot> <flowRoot
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-25.498918,39.763973)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="flowRoot4836-0-6-7-5-3-1"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-1-0-7-3"><rect
|
||||||
|
y="153.23396"
|
||||||
|
x="197.14285"
|
||||||
|
height="66.627274"
|
||||||
|
width="98.260719"
|
||||||
|
id="rect4840-9-7-2-9-4-0" /></flowRegion><flowPara
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="flowPara4842-3-3-2-0-1-3">Stack_Size</flowPara></flowRoot> <path
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
id="path5765-1-2"
|
||||||
|
d="M 21.949511,86.278273 H 45.302186"
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||||
|
<g
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
id="g5915-5"
|
||||||
|
transform="translate(0,-17.859523)">
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-start:url(#Arrow2Mstart-6-1-1)"
|
||||||
|
d="m 47.634183,105.0463 h 5.565965"
|
||||||
|
id="path4520-9-9-6"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<flowRoot
|
||||||
|
xml:space="preserve"
|
||||||
|
id="flowRoot4836-0-6-5"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,2.286756,55.997509)"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-4"><rect
|
||||||
|
id="rect4840-9-7-22"
|
||||||
|
width="107.85714"
|
||||||
|
height="61.07143"
|
||||||
|
x="197.14285"
|
||||||
|
y="153.23396" /></flowRegion><flowPara
|
||||||
|
id="flowPara4842-3-3-1"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial">__initial_sp</flowPara></flowRoot> </g>
|
||||||
|
<flowRoot
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
transform="matrix(0.26458333,0,0,0.26458333,-21.392364,17.854437)"
|
||||||
|
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||||
|
id="flowRoot4836-0-6-7-5-3-7"
|
||||||
|
xml:space="preserve"><flowRegion
|
||||||
|
id="flowRegion4838-8-7-1-0-7-2"><rect
|
||||||
|
y="153.23396"
|
||||||
|
x="197.14285"
|
||||||
|
height="66.627274"
|
||||||
|
width="98.260719"
|
||||||
|
id="rect4840-9-7-2-9-4-4" /></flowRegion><flowPara
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.66666698px;font-family:Arial;-inkscape-font-specification:Arial"
|
||||||
|
id="flowPara4842-3-3-2-0-1-1">Free</flowPara></flowRoot> </g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 15 KiB |
1
assignment_1/report/images/Untitled Diagram.drawio
Normal file
1
assignment_1/report/images/Untitled Diagram.drawio
Normal file
@ -0,0 +1 @@
|
|||||||
|
<mxfile host="app.diagrams.net" modified="2020-05-03T15:08:08.336Z" agent="5.0 (X11)" etag="FJrRoutRW1H6xKy9lX6Y" version="13.0.6" type="device"><diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">7Vtbc+I2FP41zLSdYceSLyGPIZfdtjTT5to8KlgxzgqLlQWB/vpKtnyTDHgTwCQhM5lYx5IsnXO+7xxd0rFPx/OvDE1Gf1Efkw60/HnHPutACEDPFX+kZJFKPFsJAhb6qlIhuA7/w0poKek09HFcqcgpJTycVIVDGkV4yCsyxBh9qVZ7oqT61QkKsCG4HiJiSu9Dn49SaQ8eFfJvOAxG2ZeBd5y+GaOssppJPEI+fSmJ7POOfcoo5enTeH6KiVReppf73xf3ZPDd+/rHP/EPdNv/8+byrpt2dvEzTfIpMBzxV3c9H0b88f7h7vLqidyh2zk9WQy6wFFz44tMYdgX+lNFyviIBjRC5LyQ9hmdRj6W3VqiVNQZUDoRQiCEz5jzhXIGNOVUiEZ8TNRbPA/5v7L5F1eVHkpvzuaq56SwyAoRZ4tSI1l8KL8rmiWlrF06PzkpzR/WKFPVi+mUDfGKep7yacQCvLI/mLuMwBqmYyxGKRoyTBAPZ9XRIeX0QV6vMKx4ULb9CTs7Vpt2BiUrFzZfY2dQsXJh9P2xcz2iem+0s2r6Nw3FuKGliNjNLKho2O1Z1S7SgalWhbecMIYWpWoTWSFe8R1Y/U7GfhcN62fhoXDWdASF6+Y6aeTNq2wxQ2Sq9BmzoRDIZ1m0Lm8HA8Ph2YiOH6dCD/2XUcjx9QQlBn8Rca/qtjnRS796ohG/QOOQyAl+w2SGeThE6oXyfIFtu49IGESiMBT+hpnshjP6PQ86Scfik2EUiJJXlG4SMHWd3IebuuwMM47nJX8ynS5761aNBI5V+aWIiCBzsFEpGnqak22Mj0CrfPQR4g7Ikql1hPRWPmpq55WjLEG1Az0ixtv3w5l4DHiiq1QkISVzPKRm7v2YyuSqX8AuF2VNZ0DhXqhMcIDblyOSIvcs61UMPO24+jEh3tAQoDmE5zVD0Kkp92ywnp504gkIimPldTWcUyazbRGMDY++uBWKcYBrUozlmhTjbo1i7APFvJFiYNOcp1WKgQbFhDkgrQyBj0xHegn8zwWAORvgKOCjXwSUf5UTqyeLD4ZfPUGAvbYTBPuA3ubordWgZYJ3eTLd1rrUMrDbx0EYmbYnJJzEeD24lnh+U70uR8iRlkKDGoRYNQjZXnxz20TIq5b0VqetJf3ysNVk62ZX8a12lLB3YMKN27le00dt2rnRSinJbKCHxpL2VGYiFxvNspR3sgGyffZ2rIbsre+ybQ7VreY3H4G9e00XJ60mONA7sPeO7Lyrja5Voyyx9wx0ku3oGTwQcWmjSNsmqtuJBrtcaMJW0+gqQK2VAN16mvRWoqw/IYLaCZGtm3JDJ1dOz639zqZOolboTMvahKVkoqZvPHW7zyYT7HTjaPN4djwtsTo2t33dXa6K7aNW4fyavKq9g+4VcbRBwLWdNgMuMCMuw3zKROA7EeIra9Ue8G9X59e3g5tylQ8GTFs/l687j4E1yHS2FmjNvb4HHBuKF3rgWhKUaPCUEipymbOIRhKyTyEhmshIe6RWRYZETtSLcej7ZNkeYpUDtmUWqC9EoZn/1O2zw61Zxdx2+HxWcTSwuDXbAzu1ir1HSen7XDVm9zv3PIplw1wfxcD6KAYMp3nvUQxo6aVbQ5e7jWK2GcUu6Sejy/xudxbEemZusVu6NIPYpzOKrWUWrtt2DHMMo9QcaJxHfsPTi707AvZaPwK263YfSiq2MsctLq0R/MTNK2z6cmgufi0xF6uhbd4OrWRc+wksLTnMY9K6uzHbQ5a59K1B1h1iIXoUyoNWV6YSOAhjwV7x6vuPJVF3+c/yW1VrexUpTZLaJDe2m7YBaZuweQuYtlh6NGq2sNMWs6V3vswmjmoCm+vjEwMH2g2BA7aGHOew2pWX+/TLurDt9a5j5gqfLoHTs2q4vQROFIt/W0yPQop//rTP/wc=</diagram></mxfile>
|
BIN
assignment_1/report/images/isPalindrome.png
Normal file
BIN
assignment_1/report/images/isPalindrome.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
assignment_1/report/report.pdf
Normal file
BIN
assignment_1/report/report.pdf
Normal file
Binary file not shown.
119
assignment_1/report/report.tex
Normal file
119
assignment_1/report/report.tex
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
%
|
||||||
|
% Report description
|
||||||
|
%
|
||||||
|
% authors:
|
||||||
|
% Χρήστος Χουτουρίδης ΑΕΜ 8997
|
||||||
|
% cchoutou@ece.auth.gr
|
||||||
|
|
||||||
|
|
||||||
|
% Document configuration
|
||||||
|
\newcommand{\ClassName}{Μικροεπεξεργαστές και Περιφερειακά}
|
||||||
|
\newcommand{\DocTitle}{1η Εργασία}
|
||||||
|
\newcommand{\InstructorName}{Παπαευσταθίου Ιωάννης}
|
||||||
|
\newcommand{\InstructorMail}{ygp@ece.auth.gr}
|
||||||
|
\newcommand{\CurrentDate}{\today}
|
||||||
|
|
||||||
|
\input{config/AuthReportConfig.tex}
|
||||||
|
|
||||||
|
%\renewcommand{\AuthorName}{Χρήστος Χουτουρίδης}
|
||||||
|
%\renewcommand{\AuthorMail}{cchoutou@ece.auth.gr}
|
||||||
|
%\renewcommand{\AuthorAEM}{8997}
|
||||||
|
|
||||||
|
\setFancyHeadLR{\ClassName}{\DocTitle}
|
||||||
|
%\setFancyHeadLERO{\ClassName}{\DocTitle}
|
||||||
|
|
||||||
|
% Document
|
||||||
|
% =================
|
||||||
|
\begin{document}
|
||||||
|
|
||||||
|
\FirstPage
|
||||||
|
|
||||||
|
%\tableofcontents
|
||||||
|
%\listoffigures
|
||||||
|
%\listoftables
|
||||||
|
|
||||||
|
\section{Εισαγωγή}
|
||||||
|
Στην παρούσα εργασία το ζητούμενο είναι η υλοποίηση μιας ρουτίνας σε γλώσσα \eng{assemblly ARM,} που να ελέγχει αν ένα αλφαριθμητικό είναι παλίνδρομο, αλλά και η ενσωμάτωση αυτής σε ένα πρόγραμμα σε γλώσσα \eng{C.}
|
||||||
|
Για την εργασία χρησιμοποιήσαμε το εργαλείο \eng{Keil uVision} και μιας και δεν αντιμετωπίσαμε κάποιο ιδιαίτερο πρόβλημα, η αναφορά αυτή θα αναλωθεί κυρίως στην υλοποίηση και τον έλεγχο του προγράμματος.
|
||||||
|
Τον κώδικα της εργασίας αλλά και της παρούσας αναφοράς μπορείτε να βρείτε ακόμα στο προσωπικό \href{https://git.hoo2.net/hoo2/micro_assign_1}{αποθετήριο της εργασίας}.
|
||||||
|
|
||||||
|
\section{Παραδοτέα}
|
||||||
|
Στο παραδοτέο \eng{.zip} αρχείο μπορείτε να βρείτε:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Το αρχείο \textbf{\eng{main.c}} που περιέχει όλο τον ζητούμενο κώδικα της εργασίας.
|
||||||
|
\item Το αρχείο \textbf{\eng{report.pdf}} που είναι παρούσα αναφορά.
|
||||||
|
\item Τον κατάλογο \textbf{\eng{Keil}} που περιέχει το \eng{project} στο \eng{Keil} που χρησιμοποιήσαμε.\\
|
||||||
|
Στο \eng{project} αυτό περιέχονται επιπλέων οι ρυθμίσεις καθώς και τα αρχεία από τη βιβλιοθήκη \eng{CMSIS} που χρειάστηκαν για την ορθή αρχικοποίηση και αλληλεπίδραση με τον επεξεργαστή.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
\section{Υλοποίηση}
|
||||||
|
Η υλοποίηση του ελέγχου αν ένα αλφαριθμητικό είναι παλίνδρομο έγινε σε δύο συναρτήσεις, την \eng{\textit{isPalindrome()}} και την \eng{\textit{strLength()},} που λειτουργεί ως βοηθητική συνάρτηση.
|
||||||
|
Οι συναρτήσεις αυτές είναι υλοποιημένες σε γλώσσα \eng{assemblly} αλλά η κλήση τους από το κυρίως πρόγραμμα δεν διαφέρει καθόλου από την κλήση μιας οποιασδήποτε άλλης συνάρτησης σε γλώσσα \eng{C.}
|
||||||
|
Για τον λόγο αυτό δεν θα ασχοληθούμε περαιτέρω με το κύριο πρόγραμμα (συνάρτηση \eng{main).}
|
||||||
|
|
||||||
|
\subsection{Συνάρτηση \eng{\textit{isPalindrome()}}}
|
||||||
|
\WrapFigure{0.42}{r}{fig:isPalindrome}{isPalindrome.png}{Διάγραμμα ροής της συνάρτησης \eng{\textit{isPalindrome()}}}
|
||||||
|
Για τη συνάρτηση αυτή χρησιμοποιήσαμε ένα απλό \eng{O(n)} σειριακό αλγόριθμο, ο οποίος απαιτεί το μήκος του αλφαριθμητικού εισόδου προτού εισέλθει στον κύριο βρόχο επανάληψης.
|
||||||
|
Για να βρούμε το μήκος χρησιμοποιούμε μια ξεχωριστή συνάρτηση.
|
||||||
|
Αυτή την υλοποιήσαμε από την αρχή ώστε να μην χρειαστεί να χρησιμοποιηθεί η συνάρτηση \eng{\textit{strlen()}} της \eng{\textit{libc}.}
|
||||||
|
|
||||||
|
\par Όπως φαίνεται και στο διάγραμμα του σχήματος \ref{fig:isPalindrome}, στον κύριο βρόχο της συνάρτησης χρησιμοποιούμε δύο απαριθμητές \eng{i, j} χρησιμοποιώντας τους καταχωρητές \eng {R1, R2} αντίστοιχα και ένα δείκτη στη διεύθυνση του αλφαριθμητικού χρησιμοποιώντας τον καταχωρητή \eng{R0.}
|
||||||
|
Ο ένας δείκτης εκκινεί από την αρχή του αλφαριθμητικού και ο άλλος από το τέλος.
|
||||||
|
Σε κάθε επανάληψη διαβάζουμε από το αλφαριθμητικό τα \eng{src[i]} και \eng{src[j]} και ελέγχουμε αν είναι ίσα.
|
||||||
|
Αν δεν είναι τότε το αλφαριθμητικό δεν είναι παλίνδρομο.
|
||||||
|
Αν είναι τότε μεταθέτουμε το \eng{i} μία θέση δεξιά και το \eng{j} μία θέση αριστερά και επανεκτελούμε τον βρόχο.
|
||||||
|
Ο βρόχος συνεχίζει όσο το \eng{i} είναι μικρότερο από το \eng{j.}
|
||||||
|
Αν το \eng{i} γίνει ίσο ή μεγαλύτερο από το \eng{j,} τότε ο βρόχος τερματίζει.
|
||||||
|
Σε αυτή την περίπτωση το αλφαριθμητικό είναι παλίνδρομο.
|
||||||
|
|
||||||
|
\par Αν το αλφαριθμητικό έχει μηδενικό μήκος, τότε ο βρόχος δεν θα εκτελεστεί ούτε μία φορά και η συνάρτηση θα επιστρέψει ότι το αλφαριθμητικό είναι παλίνδρομο.
|
||||||
|
Έχουμε κάνει δηλαδή την θεώρηση ότι \textbf{\textit{τα μηδενικού μήκους αλφαριθμητικά είναι παλίνδρομα}}, καθώς είναι τα ίδια είτε τα κοιτάς από μπροστά είτε τα κοιτάς από πίσω.
|
||||||
|
Στην περίπτωση που η είσοδος της συνάρτησης είναι εκτός πεδίου ορισμού, δηλαδή ο \eng{NULL pointer,} τότε η συνάρτηση επιστρέφει ψευδές αποτέλεσμα.
|
||||||
|
Ο έλεγχος του δείκτη εισόδου γίνεται στην αρχή της συνάρτησης πριν καν γίνει η κλήση για το μήκος, προστατεύοντας έτσι κάποιο \eng{exception} από το \eng{dereference} του δείκτη στην εντολή \eng{LDR.}
|
||||||
|
|
||||||
|
\subsection{Συνάρτηση \eng{\textit{strLength()}}}
|
||||||
|
Η υλοποίηση της \eng{\textit{strLength()}} είναι επίσης ένας σειριακός αλγόριθμος.
|
||||||
|
Εδώ χρησιμοποιούμε τον καταχωρητή \eng{R1} ώς δείκτη στο αλφαριθμητικό και με αυτόν κάνουμε ανάγνωση της μνήμης, αυξάνοντάς τον ταυτόχρονα μετά από κάθε ανάγνωση.
|
||||||
|
Η συνάρτηση επιστρέφει τον αριθμό των αναγνώσεων που χρειάστηκαν μέχρι να λάβουμε το νούμερο '0', το οποίο σηματοδοτεί το τέλος του αλφαριθμητικού.
|
||||||
|
|
||||||
|
\par Ομοίως και εδώ κάνουμε έλεγχο της εισόδου ώστε αυτή να μην είναι ο \eng{NULL pointer.}
|
||||||
|
Φυσικά αυτό στη δική μας περίπτωση δεν είναι απαραίτητο καθώς υπάρχει ο αντίστοιχος έλεγχος στην \eng{\textit{isPalindrome()}} προτού την κλήση.
|
||||||
|
Παρόλα αυτά το θεωρούμε καλή πρακτική, καθώς αυτό καθιστά την \eng{\textit{strLength()}} πιο ολοκληρωμένη συνάρτηση και μια χρήση της στο μέλλον δεν θα προκαλέσει εκπλήξεις.
|
||||||
|
|
||||||
|
\subsection{Εγγραφή του αποτελέσματος στη μνήμη}
|
||||||
|
\WrapFigure{0.23}{l}{fig:ram_layout}{RAM_layout.png}{Διάταξη της μνήμης}
|
||||||
|
Η συνάρτηση \eng{\textit{isPalindrome()}} αφού εκτελεστεί, επιστρέφει μια τιμή στον \eng{caller.}
|
||||||
|
Στα ζητούμενα όμως της εργασίας ήταν η συνάρτηση αυτή να γράφει το αποτέλεσμα και σε μία θέση μνήμης της επιλογής μας.
|
||||||
|
Αυτό υπό κανονικές συνθήκες είναι ανεπίτρεπτο.
|
||||||
|
Για τα πλαίσια όμως της εργασίας προσπαθήσαμε να ανταπεξέλθουμε με ένα σχετικά ασφαλή τρόπο.
|
||||||
|
|
||||||
|
\par Όπως φαίνεται και στο σχήμα \ref{fig:ram_layout}, o συνδέτης \eng{(linker)} του εργαλείου \eng{keil} δεν τοποθετεί τον \eng{SP} στο τέλος της μνήμης.
|
||||||
|
Για την ακρίβεια, χρησιμοποιώντας δύο τιμές από το \eng{configuration} του \eng{startup} αρχείου για το μέγεθος του σωρού και της στοίβας, υπολογίζει τη τιμή \eng{\textit{\textbf{\_\_initial\_sp}}.}
|
||||||
|
Αυτή την τιμή χρησιμοποιεί έπειτα σαν πρώτο όρισμα στο \eng{vector table} και άρα αυτή την τιμή έχει ο \eng{SP} κατά την εκκίνηση.
|
||||||
|
|
||||||
|
\par Έχοντας αυτό σαν δεδομένο μπορούμε να επιλέξουμε μια τιμή στην ελεύθερη περιοχή, έχοντας πάντα στο μυαλό μας ότι αλλάζοντας τα δεδομένα του προγράμματος η τιμή αυτή μπορεί να αλλάξει.
|
||||||
|
Στη δική μας περίπτωση η επιλεγμένη τιμή ήταν το \eng{\textbf{0x20001000}.}
|
||||||
|
Φυσικά αυτή η τιμή μπορεί να αλλάξει εύκολα αλλάζοντας απλώς την τιμή από το \eng{\textbf{\#define RESULT}.}
|
||||||
|
Μάλιστα αυτό είναι και κάτι που προτρέπουμε κάνει ο οποιονδήποτε θέλει να τρέξει τον κώδικά μας, ώστε να βεβαιωθεί πως η τιμή αυτή είναι στην ασφαλή ζώνη.
|
||||||
|
|
||||||
|
|
||||||
|
\section{Έλεγχος}
|
||||||
|
Για τον έλεγχο της ορθότητας του κώδικα χρησιμοποιήσαμε τον \eng{debuger} του εργαλείου κάνοντας ταυτόχρονη χρήση του \eng{simulator.}
|
||||||
|
Καθώς η εκφώνηση ανέφερε την δημιουργία μιας \eng{main,} θεωρήσαμε ότι είναι ευκαιρία να χρησιμοποιήσουμε την \eng{main} για να επιτύχουμε ένα είδους \eng{debug-mode unit testing.}
|
||||||
|
Έτσι στο εσωτερικό της δηλώσαμε αλφαριθμητικά για έλεγχο και για αυτά καλέσαμε την \eng{\textit{isPalindrome()}.}
|
||||||
|
Έπειτα εκτελώντας τον \eng{debuger} καταφέραμε να κάνουμε την όποια αποσφαλμάτωση που χρειάστηκε.
|
||||||
|
|
||||||
|
\section{Επίλογος}
|
||||||
|
Θεωρούμε ότι η παρούσα εργασία ήταν μια καλή πρώτη επαφή με την μίξη κώδικα \eng{C - assemblly,} καθώς και των όποιων απαιτήσεων από μεριάς \eng{assemblly} ώστε αυτή να είναι συμβατή με το πρότυπο που ακολουθεί ο \eng{compiler (AAPCS).}
|
||||||
|
Η μόνη παραφωνία σε αυτή τη συνεργασία ήταν η επιλογή μιας ελεύθερης θέσης μνήμης για την επιστροφή του αποτελέσματος.
|
||||||
|
Αυτό γιατί μέχρι τη σύνταξη του παρόντος δεν βρήκαμε τρόπο να διαβάσουμε από διαφορετικό αρχείο(πχ το \eng{main.c}) την τιμή \eng{\_\_initial\_sp,} ώστε η επιλογή της θέσης να αυτοματοποιηθεί.
|
||||||
|
|
||||||
|
% References
|
||||||
|
% ============================
|
||||||
|
%\begin{thebibliography}{100}
|
||||||
|
%
|
||||||
|
%\bibitem{item}item...
|
||||||
|
|
||||||
|
%\end{thebibliography}
|
||||||
|
|
||||||
|
\end{document}
|
1
assignment_2/Libraries/STM32CubeF4
Submodule
1
assignment_2/Libraries/STM32CubeF4
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit e00530150fa6d390ff68bd6fafe6c611c39d8cd7
|
1
assignment_2/report/config
Submodule
1
assignment_2/report/config
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit ddb6624bbf227f98db5d25ae7b2a5698719fc17b
|
BIN
assignment_2/report/images/experiment-1.png
Executable file
BIN
assignment_2/report/images/experiment-1.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 9.8 KiB |
BIN
assignment_2/report/images/experiment-2.png
Executable file
BIN
assignment_2/report/images/experiment-2.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
289
assignment_2/src/NUCLEO_F401RE.c
Normal file
289
assignment_2/src/NUCLEO_F401RE.c
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* NUCLEO_F401RE.h
|
||||||
|
* \brief
|
||||||
|
* Nucleo F401RE port file. This file contain the implementation of driver
|
||||||
|
* calls for F401RE board.
|
||||||
|
*
|
||||||
|
* Created on: May 23, 2020
|
||||||
|
* Author: Christos Choutouridis AEM: 8997
|
||||||
|
* email : <cchoutou@ece.auth.gr>
|
||||||
|
*/
|
||||||
|
#include "NUCLEO_F401RE.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =============== System ===============
|
||||||
|
*/
|
||||||
|
|
||||||
|
static clock_t volatile __ticks; //!< CPU time
|
||||||
|
static time_t volatile __now; //!< Time in UNIX seconds past 1-Jan-70
|
||||||
|
static clock_t volatile __sys_freq; //!< The CPU's time frequency (SysTick freq)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* This is the SysTick ISR, micro-system time base service for CPU time.
|
||||||
|
* \note
|
||||||
|
* This service implements the SysTick callback function in order
|
||||||
|
* to provide micro system - os like functionalities to an application
|
||||||
|
* without RTOS
|
||||||
|
*/
|
||||||
|
void SysTick_Handler(void) {
|
||||||
|
// Time
|
||||||
|
++__ticks;
|
||||||
|
if ( !(__ticks % __sys_freq ) )
|
||||||
|
++__now; // Do not update __now when we have external time system
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This function configures the source of the time base.
|
||||||
|
* The time source is configured to have 1ms time base with a dedicated
|
||||||
|
* Tick interrupt priority.
|
||||||
|
* \param sf Tick interrupt frequency.
|
||||||
|
* \retval HAL status
|
||||||
|
*/
|
||||||
|
__weak HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf) {
|
||||||
|
SystemCoreClockUpdate ();
|
||||||
|
|
||||||
|
/* Configure the SysTick to have interrupt in sf time basis */
|
||||||
|
if (SysTick_Config (SystemCoreClock/sf) != 0)
|
||||||
|
return HAL_ERROR;
|
||||||
|
__sys_freq = sf;
|
||||||
|
|
||||||
|
/*Configure the SysTick IRQ priority */
|
||||||
|
NVIC_SetPriority (SysTick_IRQn, 3U);
|
||||||
|
|
||||||
|
/* Return function status */
|
||||||
|
return HAL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Select the system frequency without calling the Setting functionality
|
||||||
|
* \param sf The desired value
|
||||||
|
* \return The desired value (enable chaining)
|
||||||
|
*/
|
||||||
|
__INLINE clock_t HAL_SelectSysTickFreq (clock_t sf){
|
||||||
|
return __sys_freq =sf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get the __sys_freq.
|
||||||
|
*/
|
||||||
|
__INLINE clock_t HAL_GetSysTickFreq (void){
|
||||||
|
return __sys_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Reconfigure the SysTick and update __sys_freq
|
||||||
|
* \param sf Tick interrupt frequency (CPU time)
|
||||||
|
* \return status of the operation
|
||||||
|
* \arg 0 Success
|
||||||
|
* \arg 1 Fail
|
||||||
|
*/
|
||||||
|
int HAL_SetSysTickFreq (clock_t sf) {
|
||||||
|
/*Configure the SysTick to have interrupt in sf time basis*/
|
||||||
|
if (__sys_freq != sf) {
|
||||||
|
// Time base configuration
|
||||||
|
SystemCoreClockUpdate ();
|
||||||
|
if (SysTick_Config ( (SystemCoreClock>>3)/sf) != 0)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
__sys_freq = sf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take over control of SysTick from HAL library
|
||||||
|
|
||||||
|
//! disable HAL_InitTick implementation
|
||||||
|
HAL_StatusTypeDef
|
||||||
|
HAL_InitTick(uint32_t TickPriority) { return HAL_OK; }
|
||||||
|
|
||||||
|
//! Chain GetTick to our implementation
|
||||||
|
uint32_t HAL_GetTick(void) { return clock(); }
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This function provides minimum delay (in CPU time) based
|
||||||
|
* on variable incremented.
|
||||||
|
* \param Delay specifies the delay time length, in CPU time.
|
||||||
|
* \note
|
||||||
|
* uint32_t is implicitly convertible to clock_t and vice versa.
|
||||||
|
*/
|
||||||
|
void HAL_Delay(uint32_t Delay) {
|
||||||
|
uint32_t tickstart = clock();
|
||||||
|
|
||||||
|
while((clock() - tickstart) < Delay)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ======== OS like Functionalities ============
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
//! SysTick frequency getter
|
||||||
|
__INLINE clock_t get_freq (void) {
|
||||||
|
return __sys_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! SysTick frequency setter
|
||||||
|
//! \return True on failure
|
||||||
|
int set_freq (clock_t sf) {
|
||||||
|
return HAL_SetSysTickFreq (sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* determines the processor time.
|
||||||
|
* \return
|
||||||
|
* the implementation's best approximation to the processor time
|
||||||
|
* used by the program since program invocation. The time in
|
||||||
|
* seconds is the value returned divided by the value of the macro
|
||||||
|
* CLK_TCK or CLOCKS_PER_SEC
|
||||||
|
*/
|
||||||
|
__INLINE clock_t clock (void) {
|
||||||
|
return (clock_t) __ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Set the processor time used.
|
||||||
|
* \param c The new CPU time value
|
||||||
|
* \return
|
||||||
|
* The implementation's best approximation to the processor time
|
||||||
|
* used by the program since program invocation. The time in
|
||||||
|
* seconds is the value returned divided by the value of the macro
|
||||||
|
* CLK_TCK or CLOCKS_PER_SEC
|
||||||
|
*/
|
||||||
|
clock_t setclock (clock_t c) {
|
||||||
|
return __ticks = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* determines the current calendar time. The encoding of the value is
|
||||||
|
* unspecified.
|
||||||
|
* \return
|
||||||
|
* The implementations best approximation to the current calendar
|
||||||
|
* time. If timer is not a null pointer, the return value
|
||||||
|
* is also assigned to the object it points to.
|
||||||
|
*/
|
||||||
|
time_t time (time_t *timer) {
|
||||||
|
if (timer)
|
||||||
|
*timer = (time_t)__now;
|
||||||
|
return (time_t)__now;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
* Sets the system's idea of the time and date. The time,
|
||||||
|
* pointed to by t, is measured in seconds since the Epoch, 1970-01-01
|
||||||
|
* 00:00:00 +0000 (UTC).
|
||||||
|
* \param t Pointer to new system's time and date.
|
||||||
|
* \return On success, zero is returned. On error, -1 is returned
|
||||||
|
*/
|
||||||
|
int settime (const time_t *t) {
|
||||||
|
if (t) {
|
||||||
|
__now = *t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============== Cycle count ==============
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
* Initialize CPU cycle measurement functionality based on DBG
|
||||||
|
* \return The status of the operation
|
||||||
|
* \arg LLD_OK Success
|
||||||
|
* \arg LLD_ERROR Failure
|
||||||
|
*/
|
||||||
|
LLD_Status_en CYCLE_Init (void) {
|
||||||
|
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // enable trace
|
||||||
|
//DWT->LAR = 0xC5ACCE55; // <-- added unlock access to DWT (ITM, etc.)registers
|
||||||
|
DWT->CYCCNT = 0; // clear DWT cycle counter
|
||||||
|
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // enable DWT cycle counter
|
||||||
|
return LLD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! CPU cycle getter
|
||||||
|
__INLINE clock_t CYCLE_Get (void) {
|
||||||
|
return (clock_t)DWT->CYCCNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =============== Digital I/O ===============
|
||||||
|
* BTN -- PC13
|
||||||
|
* LED -- PA5 (SB42 is in place) [SB29: PB13]
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Helper digital input pin getter
|
||||||
|
static __INLINE uint8_t _DINx (GPIO_TypeDef *port, uint32_t pin) {
|
||||||
|
return ((port->IDR & pin) != 0) ? 1:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Helper digital output pin setter
|
||||||
|
static __INLINE uint8_t _DOUTx (GPIO_TypeDef *port, uint32_t pin, uint8_t st) {
|
||||||
|
if (st) port->BSRR = (uint32_t)pin;
|
||||||
|
else port->BSRR = (uint32_t)pin << 16;
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Initialize GPIO port pins for Nucleo Board
|
||||||
|
* \return The status of the operation
|
||||||
|
* \arg LLD_OK Success
|
||||||
|
* \arg LLD_ERROR Failure
|
||||||
|
*/
|
||||||
|
LLD_Status_en Port_Init (void) {
|
||||||
|
GPIO_InitTypeDef GPIO_InitType;
|
||||||
|
|
||||||
|
// Enable Port clock
|
||||||
|
__HAL_RCC_GPIOA_CLK_ENABLE ();
|
||||||
|
__HAL_RCC_GPIOC_CLK_ENABLE ();
|
||||||
|
|
||||||
|
// BTN port configuration
|
||||||
|
GPIO_InitType.Mode = GPIO_MODE_INPUT;
|
||||||
|
GPIO_InitType.Pin = GPIO_PIN_13;
|
||||||
|
GPIO_InitType.Pull = GPIO_NOPULL;
|
||||||
|
|
||||||
|
HAL_GPIO_Init(GPIOC, &GPIO_InitType);
|
||||||
|
|
||||||
|
GPIO_InitType.Mode = GPIO_MODE_OUTPUT_PP;
|
||||||
|
GPIO_InitType.Speed = GPIO_SPEED_LOW;
|
||||||
|
GPIO_InitType.Pin = GPIO_PIN_5;
|
||||||
|
|
||||||
|
HAL_GPIO_Init(GPIOA, &GPIO_InitType);
|
||||||
|
|
||||||
|
return LLD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Nucleo's user button reader
|
||||||
|
uint8_t BTN (void) {
|
||||||
|
return _DINx (GPIOC, GPIO_PIN_13);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Nucleo's LD2 led setter
|
||||||
|
void LED (uint8_t on) {
|
||||||
|
_DOUTx(GPIOA, GPIO_PIN_5, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Low level driver init functionality
|
||||||
|
* \return The status of the operation
|
||||||
|
* \arg LLD_OK Success
|
||||||
|
* \arg LLD_ERROR Failure
|
||||||
|
*/
|
||||||
|
LLD_Status_en LLD_Init (clock_t sys_freq) {
|
||||||
|
HAL_Init();
|
||||||
|
HAL_SysTick_Init (sys_freq);
|
||||||
|
CYCLE_Init ();
|
||||||
|
Port_Init ();
|
||||||
|
|
||||||
|
return LLD_OK;
|
||||||
|
}
|
137
assignment_2/src/NUCLEO_F401RE.h
Normal file
137
assignment_2/src/NUCLEO_F401RE.h
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* NUCLEO_F401RE.h
|
||||||
|
* \brief
|
||||||
|
* Nucleo F401RE port file. This file contain the implementation of driver
|
||||||
|
* calls for F401RE board.
|
||||||
|
*
|
||||||
|
* Created on: May 23, 2020
|
||||||
|
* Author: Christos Choutouridis AEM: 8997
|
||||||
|
* email : <cchoutou@ece.auth.gr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUCLEO_F401RE_H_
|
||||||
|
#define NUCLEO_F401RE_H_
|
||||||
|
|
||||||
|
#include <stm32f4xx.h>
|
||||||
|
#include <stm32f4xx_hal.h>
|
||||||
|
#include <core_cm4.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ========= Data types ========
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Driver status return type
|
||||||
|
typedef enum {
|
||||||
|
LLD_OK = 0, //!< Indicate successful operation
|
||||||
|
LLD_ERROR //!< Indicate Error
|
||||||
|
}LLD_Status_en;
|
||||||
|
|
||||||
|
typedef uint8_t din_t;
|
||||||
|
//typedef int adc_t;
|
||||||
|
|
||||||
|
#define OFF (0)
|
||||||
|
#define ON (!OFF)
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE (0)
|
||||||
|
#endif
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE (!FALSE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =============== System ===============
|
||||||
|
*/
|
||||||
|
#if defined ( __GNUC__ ) && !defined (__CC_ARM)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also defined in types.h
|
||||||
|
*/
|
||||||
|
#ifndef _CLOCK_T_
|
||||||
|
#define _CLOCK_T_ unsigned long /* clock() */
|
||||||
|
typedef _CLOCK_T_ clock_t; /*!< CPU time type */
|
||||||
|
#endif
|
||||||
|
#ifndef _TIME_T_
|
||||||
|
#define _TIME_T_ long /* time() */
|
||||||
|
typedef _TIME_T_ time_t; /*!< date/time in unix secs past 1-Jan-70 type for 68 years*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper macros
|
||||||
|
*/
|
||||||
|
#define _CLOCK_T_MAX_VALUE_ (ULONG_MAX) //!< Helper macro for maximum signed CPU time calculations
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculate the positive time difference of _t2_ and _t1_, where
|
||||||
|
* _t1_, _t2_ are clock_t values
|
||||||
|
* \note
|
||||||
|
* _t2_ event comes is AFTER _t1_
|
||||||
|
*
|
||||||
|
* ex:
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9
|
||||||
|
* ^ ^
|
||||||
|
* | |
|
||||||
|
* a b
|
||||||
|
*
|
||||||
|
* if : t1=a, t2=b then dt = b-a = t2 - t1
|
||||||
|
* if : t1=b, t2=a then dt = 9 - (b-a) + 1 = UMAX - (t1-t2) + 1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define _CLOCK_DIFF(_t2_, _t1_) ( ((_t2_)>(_t1_)) ? ((_t2_)-(_t1_)) : (_CLOCK_T_MAX_VALUE_ - ((_t1_) - (_t2_)) + 1) )
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU time macros
|
||||||
|
*/
|
||||||
|
#define msec2CPUtime(_ms_) (((_ms_) * get_freq()) / 1000)
|
||||||
|
#define sec2CPUtime(_s_) ((_s_) * get_freq())
|
||||||
|
|
||||||
|
#define CPUtime2msec(_t_) (((_t_) * 1000) / get_freq())
|
||||||
|
#define CPUtime2sec(_t_) ((_t_) / get_freq())
|
||||||
|
|
||||||
|
HAL_StatusTypeDef HAL_SysTick_Init(clock_t sf);
|
||||||
|
|
||||||
|
clock_t HAL_SelectSysTickFreq (clock_t sf);
|
||||||
|
clock_t HAL_GetSysTickFreq (void);
|
||||||
|
int HAL_SetSysTickFreq (clock_t sf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OS like Functionalities
|
||||||
|
*/
|
||||||
|
clock_t get_freq (void);
|
||||||
|
int set_freq (clock_t sf);
|
||||||
|
|
||||||
|
clock_t clock (void);
|
||||||
|
clock_t setclock (clock_t c);
|
||||||
|
|
||||||
|
time_t time (time_t *timer);
|
||||||
|
int settime (const time_t *t);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============== Cycle count ==============
|
||||||
|
*/
|
||||||
|
LLD_Status_en CYCLE_Init (void);
|
||||||
|
clock_t CYCLE_Get (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =============== Digital I/O ===============
|
||||||
|
* BTN -- PC13
|
||||||
|
* LED -- PA5 (SB42 is in place) [SB29: PB13]
|
||||||
|
*/
|
||||||
|
LLD_Status_en Port_Init (void);
|
||||||
|
|
||||||
|
uint8_t BTN (void);
|
||||||
|
void LED (uint8_t on);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============= Board Init ==============
|
||||||
|
*/
|
||||||
|
LLD_Status_en LLD_Init (clock_t sys_freq);
|
||||||
|
|
||||||
|
#endif /* NUCLEO_F401RE_H_ */
|
63
assignment_2/src/assign2_impl.h
Normal file
63
assignment_2/src/assign2_impl.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* assign2_impl.h
|
||||||
|
* \brief
|
||||||
|
* Assignment 2 application header
|
||||||
|
*
|
||||||
|
* Created on: May 23, 2020
|
||||||
|
* Author: Christos Choutouridis AEM: 8997
|
||||||
|
* email : <cchoutou@ece.auth.gr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIGN2_IMPL_H_
|
||||||
|
#define ASSIGN2_IMPL_H_
|
||||||
|
|
||||||
|
#include "NUCLEO_F401RE.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============= User defines ===============
|
||||||
|
*/
|
||||||
|
#define SYSTICK_FREQ (1000) //!< 1000Hz => 1msec accuracy
|
||||||
|
|
||||||
|
#define MODE_LEADING_EDGE (1) //!< Start counting as soon as the led is switched on
|
||||||
|
#define MODE_TRAILING_EDGE (2) //!< Start counting as soon as the led is switched off (Motor sport style)
|
||||||
|
|
||||||
|
//! If there is no Pre-define MODE, select one here
|
||||||
|
#ifndef MODE
|
||||||
|
#define MODE MODE_TRAILING_EDGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MEASUREMENTS (5) //!< The number of measurements for each experiment
|
||||||
|
|
||||||
|
//! elect the maximum waiting time before the visual trigger.
|
||||||
|
#define MAX_WAIT_TIME sec2CPUtime(10)
|
||||||
|
|
||||||
|
//! Select if we need cycle counting also.
|
||||||
|
#define CYCLE_COUNTING (1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ============= Data types ===============
|
||||||
|
*/
|
||||||
|
//! Select the application wide accuracy of the floating point type.
|
||||||
|
typedef float fp_data_t; //!< floating point data alias.
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Statistical data structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
fp_data_t average; //!< The average response time of the experiment
|
||||||
|
fp_data_t median; //!< The median of the times
|
||||||
|
fp_data_t std_dev; //!< Standard deviation
|
||||||
|
} stats_t;
|
||||||
|
|
||||||
|
fp_data_t average (const clock_t *t, size_t n);
|
||||||
|
fp_data_t median (const clock_t *t, size_t n);
|
||||||
|
fp_data_t std_deviation (const clock_t* t, size_t n);
|
||||||
|
|
||||||
|
void leading (clock_t *out, size_t n);
|
||||||
|
void trailing (clock_t *out, size_t n);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ASSIGN2_IMPL_H_ */
|
145
assignment_2/src/main.c
Normal file
145
assignment_2/src/main.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
* main.c
|
||||||
|
* \brief
|
||||||
|
* Main application file
|
||||||
|
*
|
||||||
|
* Created on: May 23, 2020
|
||||||
|
* Author: Christos Choutouridis AEM: 8997
|
||||||
|
* email : <cchoutou@ece.auth.gr>
|
||||||
|
*/
|
||||||
|
#include "assign2_impl.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global data
|
||||||
|
*/
|
||||||
|
stats_t stats;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Compare functionality for qsort
|
||||||
|
* \param a left hand site
|
||||||
|
* \param b right hand site
|
||||||
|
* \return stdlib requirements
|
||||||
|
* \arg -1 a<b
|
||||||
|
* \arg 0 a==b
|
||||||
|
* \arg 1 a>b
|
||||||
|
*/
|
||||||
|
static int cmpfunc (const void * a, const void * b) {
|
||||||
|
fp_data_t v = *(fp_data_t*)a - *(fp_data_t*)b;
|
||||||
|
return (v < 0) ? -1 : (v > 0) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculates and return the average of an array of measurements
|
||||||
|
* \param t Pointer to measurements
|
||||||
|
* \param n Size of measurements array
|
||||||
|
* \return The average
|
||||||
|
*/
|
||||||
|
fp_data_t average (const clock_t *t, size_t n) {
|
||||||
|
fp_data_t ret =0;
|
||||||
|
for (size_t i=0 ; i<n ; ++i)
|
||||||
|
ret += t[i];
|
||||||
|
return ret / n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculates and return the median of an array of measurements
|
||||||
|
* \param t Pointer to measurements
|
||||||
|
* \param n Size of measurements array
|
||||||
|
* \return The average
|
||||||
|
*/
|
||||||
|
fp_data_t median (const clock_t *t, size_t n) {
|
||||||
|
qsort ((void*)t, n, sizeof(t[0]), cmpfunc);
|
||||||
|
return (n % 2) ? t[n/2] : (t[n/2] + t[n/2 -1]) /2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Calculates and return the std. deviation of an array of measurements
|
||||||
|
* \param t Pointer to measurements
|
||||||
|
* \param n Size of measurements array
|
||||||
|
* \return The average
|
||||||
|
*/
|
||||||
|
fp_data_t std_deviation (const clock_t* t, size_t n) {
|
||||||
|
fp_data_t av = average (t, n);
|
||||||
|
fp_data_t s =0;
|
||||||
|
for (size_t i=0 ; i<n ; ++i) {
|
||||||
|
s += (t[i]-av)*(t[i]-av);
|
||||||
|
}
|
||||||
|
return sqrt (s/n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Leading edge trigger experiment
|
||||||
|
* \param out Pointer to array to store the measurements
|
||||||
|
* \param n Number of measurements
|
||||||
|
*/
|
||||||
|
void leading (clock_t *out, size_t n) {
|
||||||
|
srand(0);
|
||||||
|
rand();
|
||||||
|
|
||||||
|
LED (OFF);
|
||||||
|
for (size_t i =0 ; i<n ; ++i) {
|
||||||
|
clock_t t1, t2;
|
||||||
|
HAL_Delay(rand() % (MAX_WAIT_TIME + 1));
|
||||||
|
LED(ON);
|
||||||
|
t1 = clock ();
|
||||||
|
while (BTN())
|
||||||
|
;
|
||||||
|
t2 = clock ();
|
||||||
|
LED (OFF);
|
||||||
|
out[i] = CPUtime2msec(_CLOCK_DIFF(t2, t1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Trailing edge trigger experiment
|
||||||
|
* \param out Pointer to array to store the measurements
|
||||||
|
* \param n Number of measurements
|
||||||
|
*/
|
||||||
|
void trailing (clock_t *out, size_t n) {
|
||||||
|
srand(0);
|
||||||
|
rand();
|
||||||
|
|
||||||
|
LED (ON);
|
||||||
|
for (size_t i =0 ; i<n ; ++i) {
|
||||||
|
clock_t t1, t2;
|
||||||
|
HAL_Delay(rand() % (MAX_WAIT_TIME + 1));
|
||||||
|
LED(OFF);
|
||||||
|
t1 = clock ();
|
||||||
|
while (BTN())
|
||||||
|
;
|
||||||
|
t2 = clock ();
|
||||||
|
LED (ON);
|
||||||
|
out[i] = CPUtime2msec(_CLOCK_DIFF(t2, t1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main
|
||||||
|
*/
|
||||||
|
int main(void) {
|
||||||
|
clock_t times[MEASUREMENTS];
|
||||||
|
|
||||||
|
LLD_Init (SYSTICK_FREQ); // Initialize the board
|
||||||
|
|
||||||
|
// Experiment
|
||||||
|
#if MODE == MODE_LEADING_EDGE
|
||||||
|
leading (times, MEASUREMENTS);
|
||||||
|
#elif MODE == MODE_TRAILING_EDGE
|
||||||
|
trailing (times, MEASUREMENTS);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Get statistical data
|
||||||
|
stats.average = average ((const clock_t*)times, MEASUREMENTS);
|
||||||
|
stats.median = median ((const clock_t*)times, MEASUREMENTS);
|
||||||
|
stats.std_dev = std_deviation((const clock_t*)times, MEASUREMENTS);
|
||||||
|
|
||||||
|
// Flash 10Hz to indicate the end of experiment
|
||||||
|
while (1) {
|
||||||
|
HAL_Delay(msec2CPUtime(50));
|
||||||
|
LED (ON);
|
||||||
|
HAL_Delay(msec2CPUtime(50));
|
||||||
|
LED (OFF);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user