1 of 15

EE 319K�Introduction to Embedded Systems

Lecture 5: Arrays, �Functional Debugging

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

Friday 3/4 7-8:30pm

Location: Canvas

http://users.ece.utexas.edu/~valvano/Volume1/exams.htm

5-1

2 of 15

Agenda

  • Recap
    • TExaS Logic Analyzer
    • Arm Architecture Procedure Call Standard
    • Functions, parameter passing
    • Indexed Addressing and Pointers
    • Data Structures: Arrays in assembly
  • Outline
    • Indexed Addressing and Pointers (more)
    • Data Structures: Arrays (C and assembly)
    • Functional Debugging

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

5-2

3 of 15

Pointer Array Access

    • In assembly

p RN 3

sum RN 0

Sum7Primes

MOV sum,#0 ;sum = 0

LDR p,=Prime ;p = Prime

ADD R1,p,#14 ;&Prime[7]

lp LDRH R2,[p] ;*p

ADD sum,sum,R2 ;sum += ..

ADD p,p,#2 ;p++

CMP p,R1

BNE lp

BX LR

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

  • Pointer access
    • In C

const uint16_t Prime[] = {1,2,3,5,7,11,13};

uint16_t Sum7Primes(void){

uint32_t sum;

uint16_t *p;

sum = 0;

p = Prime;

do{

sum += *p;

p++;

}

while(p != &Prime[7]);

return sum;

}

5-3

4 of 15

Pointer Array Access

    • In assembly

p RN 0

n RN 1

sum RN 2

x RN 3

Sum MOV sum,#0 ;sum = 0

lp LDR x,[p] ;*p

ADD sum,sum,x ;sum += ..

ADD p,p,#4 ;p++

SUBS n,n,#1

BNE lp

MOV R0,sum

BX LR

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

    • In C

uint32_t Sum(uint32_t *p,

uint32_t n){

uint32_t sum,x;

sum = 0;

for(; n; n--){

x = *p;

sum += x;

p++;

}

return sum;

}

5-4

5 of 15

Pointer Array Access

    • In assembly

AREA data

SIZE EQU 100

y SPACE 4

Buf SPACE SIZE*4

AREA |.text|

main LDR R0,=Buf

MOV R1,#SIZE

BL Sum

LDR R1,=y

STR R0,[R1]

Loop B Loop

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

  • Pointer access
    • In C

#define SIZE 100

int16_t Buf[SIZE];

int32_t y;

int main(void){

y = Sum(Buf,SIZE);

while(1){

}

}

5-5

6 of 15

Array example

;***** Sum subroutine *********************

;Calculate the sum of all the data in an array

;Let pt be pointer to an array of 16-bit signed numbers

;Let size be the number of points in the array

;Inputs: R0 is pt

; R1 is size

;Output: R0 the sum of the elements

EXPORT Sum

Sum

BX LR

int32_t Sum(int16_t *pt,

uint32_t size){

int32_t s=0;

while(size){

s += *pt;

pt++;

size--;

}

return s;

}

5-6

7 of 15

Array example (solution)

;***** Sum subroutine *********************

;Calculate the sum of all the data in an array

;Let pt be pointer to an array of 16-bit signed numbers

;Let size be the number of points in the array

;Inputs: R0 is pt

; R1 is size

;Output: R0 the sum of the elements

pt RN 0

size RN 1

S RN 4

Sum PUSH {R4,R5}

MOV s,#0 ; result

Loop CMP size,#0

BEQ done

LDRSH R5,[pt],#2 ;promote,add2

ADD s,s,R5

SUB size,size,#1

B loop

done MOV R0,s; R0 has return result

POP {R4,R5}

BX LR

int32_t Sum(int16_t *pt,

uint32_t size){

int32_t s=0;

while(size){

s += *pt;

pt++;

size--;

}

return s;

}

5-7

8 of 15

Functional Debugging: Dump

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 100

uint32_t Len;

uint8_t Ebuf[SIZE];

void Debug_Init(void){

Len = 0;

}

void Debug_Capture(void){

if(Len < SIZE){

Ebuf[Len] = GPIO_PORTE_DATA_R;

Len++;

}

}

-Implement in assembly

Minimally intrusive: small but negligible affect on system

T1 is the time to execute instrument

T2 is the time between executions

T1/T2 ≈ 0

5-8

9 of 15

Functional Debugging: Dump

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 100

uint32_t Len;

uint8_t Ebuf[SIZE];

void Debug_Init(void){

Len = 0;

}

// what does this version do?

void Debug2_Capture(void){

Ebuf[Len] = GPIO_PORTE_DATA_R;

Len = (Len+1)%SIZE;

}

5-9

10 of 15

EE319K: Arrays

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 64

uint32_t Len;

uint8_t Data[SIZE];

uint32_t Time[SIZE];

uint32_t Last;

void Debug_Init(void){

Timer2_Init();

Len = 0;

}

void Debug_Capture(void){

if(Len < SIZE){

Data[Len] = d;

Time[Len] = (Last-t);

Last = t;

Len++;

}

}

#define d GPIO_PORTE_DATA_R

#define t TIMER2_TAR_R

Demo: use this method to prove Breathing in Lab 3

5-10

11 of 15

Elasped Time

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

uint32_t ElaspedTime; // time difference in 12.5ns

uint32_t TimeA;       // time at EventA

uint32_t TimeB;       // time at EventB

void EventA(void){

  TimeA = TIMER2A_TAR; 

// actual stuff associated with EventA

}

void EventB(void){

  TimeB = TIMER2A_TAR;

  ElaspedTime = TimeA - TimeB; // down counter 

// actual stuff associated with EventB

}

5-11

12 of 15

Dump using pointers

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 100

uint8_t *Dpt;

uint8_t Bbuf[SIZE];

void Debug2_Init(void){

Dpt = Bbuf;

}

void Debug2_Capture(void){

if(Dpt < &Bbuf[SIZE]){

*Dpt = GPIO_PORTB_DATA_R;

Dpt++;

}

}

-Implement in assembly

5-12

13 of 15

Dump with Filter

uint32_t Last;

void Debug3_Capture(void){

if(GPIO_PORTB_DATA_R != Last){

if(Cnt < SIZE){

Last = GPIO_PORTB_DATA_R;

Bbuf[Cnt] = Last;

Cnt++;

}

}

}

Basic idea of Filter

-Reduce the size of the array

-Focus in where you think the bug is

-Only store strategic information

For example, if we suspect the error in variable B occurs when variable A gets large, we could add a filter that saves B in the array only when the variable A is above a certain value.

void Debug4_Capture(void){

if(A > 100){

if(Cnt < SIZE){

Bbuf[Cnt] = B;

Cnt++;

}

}

}

5-13

14 of 15

EE312H: Arrays versus Vector

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 100

typedef struct{

uint32_t len;

uint8_t data[SIZE];

uint32_t time[SIZE];

} dump2_t;

dump2_t Dump2;

void Debug2_Init(void){

Dump2.len = 0;

Timer2_Init();

}

void Debug2_Capture(void){

if(Dump2.len<SIZE){

Dump2.data[Dump.len] = d;

Dump2.time[Dump.len] =

(Last-t);

Last = t;

Dump2.len++;

}

}

#define SIZE 100

uint32_t Len1;

uint8_t Data1[SIZE];

uint32_t Time1[SIZE];

uint32_t Last;

void Debug1_Init(void){

Len1 = 0;

Timer2_Init();

}

void Debug1_Capture(void){

if(Len1 < SIZE){

Data1[Len1] = d;

Time1[Len1] = Last-t;

Last = t;

Len1++;

}

}

#define d GPIO_PORTE_DATA_R

#define t TIMER2_TAR_R

Demo: use this method to prove Breathing in Lab 3

5-14

15 of 15

EE312H: Arrays versus Vector

Bard, Erez, Gerstlauer, Valvano, Yerraballi, Telang, Cuevas, Tiwari

#define SIZE 100

typedef struct{

uint8_t *dpt;

uint8_t data[SIZE];

uint32_t *tpt;

uint32_t time[SIZE];

} dump4_t;

dump4_t Dump4;

void Debug4_Init(void){

Dump4.dpt = Dump4.data;

Dump4.tpt = Dump4.time;

Timer2_Init();}

void Debug4_Capture(void){

if(Dump4.dpt<&Dump4.data[SIZE]){

*Dump4.dpt = d;

Dump4.dpt++;

*Dump4.tpt = Last-t;

Last = t;

Dump4.tpt++;

}

}

#define SIZE 100

uint8_t *Dpt3;

uint8_t Data3[SIZE];

uint32_t *Tpt3;

uint32_t Time3[SIZE];

uint32_t Last;

void Debug3_Init(void){

Dpt3 = Data3;

Tpt3 = Time3;

Timer2_Init();

}

void Debug3_Capture(void){

if(Dpt3 < &Data3[SIZE]){

*Dpt3 = d;

Dpt3++;

*Tpt3 = Last-t;

Last = t;

Tpt3++;

}

}

5-15