[go: up one dir, main page]

0% found this document useful (0 votes)
33 views165 pages

Embedded C Part 2

These is for embedded
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
33 views165 pages

Embedded C Part 2

These is for embedded
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 165
6 Come let's see how deep it is!! 1D) Team Emertxe Functions Embedded C Functions - What? An activity that is natural to or the purpose of a person or thing. “bridges perform the function of providing access across water” A relation or expression involving one or more variables. “the function (bx + c)" Source: Google * In programing languages it can something which performs a specific service * Generally it can have 3 parameters like - Input - Operation = Output ZMERTXE Embedded C Functions - What? ZMERTXE Embedded C > Functions - How to write ‘Syntax return_data_type function_name(arg_l, arg_2, ..., arg_n) /* Function Body */ } Example Return data type as int First parameter with int type Second parameter with int type XMERTXE Embedded C Bi pS Functions - How to write yexed Example int foo(int x) int ret = 0; ret=x+1; Return from function > ZMERTXE Embedded C i Functions - How to call Example #include int main() t aint x, yi The function calt x= 2? , ¥ = foo(x); print£("y is d\n", y); return 0; int foo(int x) int ret = 0; ret = x +1; return ret; ZMERTXE Embedded C a Functions - Why? * Re usability - Functions can be stored in library & re-used - When some specific code is to be used more than once, at different places, functions avoids repetition of the code. * Divide & Conquer - A big & difficult problem can be divided into smaller sub-problems and solved using divide & conquer technique * Modularity can be achieved. * Code can be easily understandable & modifiable. * Functions are easy to debug & test. * One can suppress, how the task is done inside the function, which is called Abstraction > > SMERTXE Embedded C Functions - A complete look Example #include int main() « { ant numl = 10, num2 = 20; int sum = 0; , sum = add_numbers print£("Sum is %d) ‘The main function The function call Actual arguments Return type Formal arguments Function Return from function ZMERTXE Embedded C Functions - Ignoring return value Example #include int main() { ant numl = 10, num2 = 20; cece Ignored the return from function In C, it is up to the programmer to add_numbers(numl, num2); < capture or ignore the return value print£("Sum is %d\n”, sum); return 0; int add_numbers(int numl, int num2) int sum = 0; sum = num] + num2; return sum; >» EMERTXE Embedded C Fi» Function and the Stack RAM Memory Layout Stack Frame P; » Local Variables P, Return Address Parameter List Ps Past Pn XMERTXE Embedded C Functions - Parameter Passing Types * This method copies the actual * This method copies the address of value of an argument into the an argument into the formal formal parameter of the function. parameter. * In this case, changes made to the + Inside the function, the address is Parameter inside the function have used to access the actual no effect on the actual argument. argument used in the call. This means that changes made to the parameter affect the argument. > XMERTXE Embedded C Functions - Pass by Value Example #include int add_numbers(int numi, int num2); int main () t int numl = 10, num2 = 20, sum; sum = add_numbers(numl, num2) ; print€("Sim is 44\n", sum); return 0; } int add_numbers(int numl, int num2) C int sum = 0; sum = numl + num2; return sum; ZMERTXE Embedded C Functions - Pass by Value Example #include void modify (int numl) ; int main() int numl = 10; printf ("Before Modification\n") 7 print£("numl is ¢d\n", numl); modify (num1) ; printf (“After Modification\n"); print£("numl is td\n", numl); return 0; , void modify(int num1) { ? > SMERTXE numl = numl + 1; Embedded C Functions - Pass by Reference Example #include void modify(int *iptr);: aint main() ant num = 10; printf ("Before Modification\n") 7 print£("numl is td\n", num); modify (énum) ; printf (“After Modification\n”); Printé("numl is %d\n", num); return 0; , void modify(int *iptr) { ? *iptr = *iptr + 1; SMERTXE Embedded C Functions - Pass by Reference Example finclude 1 void modify (int *iptr) ; int main() . 1000 print£ ("Before Modification\n”) ; Return Address printf£("numl is td\n", num); to caller modify (énum) ; printf (“After Modification\n”); Printé("numl is %d\n", num); return 0; , void modify(int *iptr) { , *iptr = *iptr + 1; > SMERTXE Embedded C Functions - Pass by Reference Example finclude void modify(int *iptr);: aint main() int num = 10; printf ("Before Modification\n") 7 print£("numl is td\n", num); printé (“After Modification\n” Printé("numl is %d\n", num); return 0; , void modify(int *iptr) { *iptr = iptr +1; , > 1000 Return Address to caller 2 Return Address to main jptr= 1000 2000. SMERTXE Embedded C Functions - Pass by Reference Example ffinclude 1 void modify (int *iptr) ; int main() int num = 10; 1000 print£ ("Before Modification\n”) ; Return Address printf£("numl is td\n", num) ; to caller modify (snum) ; 2 Return Address printf (“After Modification\n”); to.main printé("numi is %d\n", num) ; jptr= 1000 2000 return 0; , void modify(int *iptr) SMERTXE Functions - Pass by Reference - Advantages * Return more than one value from a function * Copy of the argument is not made, making it fast, even when used with large variables like arrays etc. * Saving stack space if argument variables are larger (example - user defined data types) > SMERTXE Embedded C >> Functions - Passing Array * As mentioned in previous slide passing an array to function can be faster * But before you proceed further it is expected you are familiar with some pointer rules * If you are OK with your concepts proceed further, else please know the rules first » > SMERTXE Embedded C Functions - Passing Array Example finclude void print_array(int array[])? int main() © cae aceeprst-o7t4n) 20. 90-400) print_array (array): return 0; } void print_array (int array[]) int 4; for (b= 0; 4< 5; i++) print£ ("Index %d has Element d\n", 4, array[i]); ZMERTXE Embedded C Functions - Passing Array Example finelude void print array (int tazray) : int main() © ine array(5] = {10, 20, 30, 40, 50); print_array (array) ; return 0; ) void print_array(int *array) ant i; for (b= 0; 2 <5; 444) { print£("Index %d has Element d\n", 4, ¢axray); array++: 1 ZMERTXE Embedded C Functions - Passing Array Example finclude void print_array(int tarray, int size): int main() © saa sczeprst-oo4n 20. 90) 40.0) print_array(array, 5); return 0; } void print_array(int ‘array, int size) ant i; for (i= 0; i < size; i++) print£ ("Index %d has Element d\n", 4, *axzay++); ZMERTXE Embedded C Func ns - Returning Array Example include int +modify array (int ‘array, int size}; void print array(int array(], int size) ; Ant mada () { ant array(5] = (10, 20, 30, 40, 50); ant taper: aptr = modify _array(array, 5); print_array(iptr, 5); return 0; void print_array(int array(], int size) ( int ip for (A= 0; 4 < size: its) int "modify array(int ‘array, int size) int 4; for (Lm 0; 4 € eize: ite) { ) *(aray + 4) += 10; return array; printf ("Index Gd has Element id\n", i, areay[iter]); XMERTXE Embedded C Functions - Returning Array Example Hinciude SMERTXE Embedded C > Functions - Recursive * Recursion is the process of repeating items in a self-similar way * In programming a function calling itself is called as recursive function * Two steps Step 1: Identification of base case Step 2: Writing a recursive case » > SMERTXE Embedded C Functions - Recursive - Example Example #include /* Pactorial of 3 numbers */ ant factorial(int number) ‘ . (number <= 1) return 1; return number * factorial (number - 1); int main() int result; result = factorial (3); printf ("Factorial of 3 is td\n”, result); return 0; ZMERTXE Embedded C Functions - Recursive - Example Flow Stack Frames Return Address to caller Return Address 1 2 to main number = 3 Return Address 3 to factorial number = 2 4 Return Address 4 tofactorial number = 1 Value with calls factorial(3) number != 1 number * factorial(number = 1) 3 * factarial(3 - 1) number != 1 number * factorial(number - 1) 2* factorial(2 - 1) number == 1 ZMERTXE Embedded C > Functions - Recursive - Example Flow Stack Frames Results with return Ratan Addrois Gets 6 a value to caller - =a Returns 3 * 2 to the caller ae siimber 23s, 2 ™ ce “Return Address 3) Eesteaeal Returns 2* 1 to the caller eo filimber 22s, z “ ~. x “sReturn Address” 4 Ttaqortl returns 4 to the caller aeiimber 21s, > XMERTXE Embedded C a>» Functions - Function Pointers * A variable that stores the pointer to a function. * Chunk of code that can be called independently and is standalone * “Registering” a piece of code and calling it later when required Syntax return_datatype (*foo) (datatype, ...); ZMERTXE Embedded C Functions - Function Pointers Example #include , add(int numl, int num2) xeturn num] + num2; } aint main() int (#function) (int, int); function = add; print£(#d\n", function (2, 4)); return 0; Example #include void run_at_exit (void) t printé("Exiting\n"); int main() printf ("In Main Function\n”) : atexit(run_at_exit) ; return 0; XMERTXE Embedded C i>: Functions - Variadic * Variadic functions can be called with any number of trailing arguments * For example, printf(), scanf() are common variadic functions * Variadic functions can be called in the usual way with individual arguments Syntax weturn_data_type function_name(parameter list, ...); > SMERTXE Embedded C Functions - Variadic - Definition & Usage * Defining and using a variadic function involves three steps: Step 1: Variadic functions are defined using an ellipsis (‘...”) in the argument list, and using special macros to access the variable arguments. Example int foo(int a, ...) /* Function Body */ } Step 2: Declare the function as variadic, using a prototype with an ellipsis (‘...’), in all the files which call it. Step 3: Call the function by writing the fixed arguments followed by the additional variable arguments. > SMERTXE Embedded C Functions - Variadic - Argument access macros * Descriptions of the macros used to retrieve variable arguments * These macros are defined in the header file stdarg.h va_list The type va_list is used for argument pointer variables va_start This macro initializes the argument pointer variable ap to point to the first of the optional arguments of the current function; last-required must be the last required argument to the function va_arg The va_arg macro returns the value of the next optional argument, and modifies the value of ap to point to the subsequent argument. Thus, successive uses of va_arg return successive optional arguments va_end. This ends the use of ap > > SMERTXE Embedded C Functions - Variadic - Example Example Finelude ame main() t ant ret ret = add(3, 2, 4, 4): Print£("Sum is d\n", zet); wet = add(5, 3, 3, 4, 5, 10); Printé (sum is'Sd\n", ret); return 0; int add(int count, ...) { va_list ap; int iter, sum; /* Initialize the arg list */ va_start (ap, count) ; sum = 0; for (iter = 0; iter < count; iter#) sum += va_arg(ap, int): , /* Cleanup */ va_end(ap) : return sum; XMERTXE Advanced Pointers and Strings Embedded C > Pointers - Pitfalls - Segmentation Fault * Asegmentation fault occurs when a program attempts to access a memory location that it is not allowed to access, or attempts to access a memory location in a way that is not allowed. Example Example finclude #include int main() int main() int num = 0; int “num = 0; printf("Enter the number\n”) ; print£(°num = %d\n”, *num); scanf(°%d", num); return 0; return 0; } ZMERTXE Embedded C Pointers - Pitfalls - Dangling Pointer >> * A dangling pointer is something which does not point to a valid location any more. Example #include int main() ‘ int *iptr; aptr = malloc(4); free(iptr) ; siptr = 100; return 0; Example flinclude int *£00(void) { int num = 5; return énum_ptr; } int main() int *iptr; iptr = foo(); return 0; ZMERTXE Embedded C i Pointers - Pitfalls - Wild Pointer * An uninitialized pointer pointing to a invalid location can be called as an wild pointer. Example #include int main() { int *iptr 1; /* Wild Pointer */ static int *iptr_2; / Not a wild pointer */ xeturn 0; ZMERTXE Embedded C >> Pointers - Pitfall - Memory Leak * Improper usage of the memory allocation will lead to memory leaks * Failing to deallocating memory which is no longer needed is one of most common issue. * Can exhaust available system memory as an application runs longer. > > SMERTXE Embedded C Pointers - Pitfall - Memory Leak Example finelude Amt main () { int *num_array, sum = 0, no_of elements, i: while (2) t Print£(°Enter the nunbar of elements: \n"): scanf("d", &no_of elements) ; mum_array = malloc (no_of elements) ; sum = 0; for (4 = 0; 4 < no_of elements; i++) ( scanf("td", &num_arzay[i]}; sum += num_array(i]: ements are d\n”, sum); » XMERTXE Embedded C Wi > Pointers - Pitfalls - Bus Error * A bus error is a fault raised by hardware, notifying an operating system (OS) that, a process is trying to access memory that the CPU cannot physically address: an invalid address for the address bus, hence the name. Example #include int main() char array[sizeof(int) + 11; int *ptrl, *ptr2; ptrl = sarray[0]; ptr2 = sarray(1]; scanf("td %d”, ptr, ptr2); return 0; ZMERTXE Embedded C o> Pointers - Const Qualifier Example inelude int main() t The location, its pointing to is int const *num = NULL; constant. return 0; 3 Example finelude int main() ant * const mum = NULL; < The pointer is constant return 0; > © SMeRrXE Embedded C >> Pointers - Multilevel * A pointer, pointing to another pointer which can be pointing to others pointers and so on is know as multilevel pointers. * We can have any level of pointers. * As the depth of the level increase we have to bit careful while dealing with it. > > SMERTXE Embedded C Pointers - Multilevel Example #include int main () t P 7 int **ptr2 = sptrl; int ***ptr3 = gpte2; print£(°id", ptr3); prints ("4d", *ptr3); prints (~ *eptr3): print£("d", ***ptr3) ; return 0; num a ZMERTXE Embedded C Pointers - Multilevel Example include num naesmase) mo 10x t ptri int ***ptr3 = tp 3 an print£(°id", ptr3); prints ("4a' prints (~ print£("sd", ***ptr3) ; return 0; ZMERTXE Embedded C Pointers - Multilevel Example #include int main () int num = 10; int *ptrl = snum; 8 ee print£(°id", ptr3); num ptri 2000 ptr2 3000 XMERTXE Embedded C Pointers - Multilevel Example Hinclude int main() aint num = 10; int *ptrl = enum; ptrl printé (“4d’ prints ("4d", *ptr3); eeptr3); eeaptrs); g ptr2 g A ptr3 4000 XMERTXE Embedded C Pointers - Multilevel Example Hinclude num sae main oo 0 { aint num = 10; int *ptel = énum; int **ptr2 = sptrl; 2000 int ***ptr3 = gptr2; ptr2 g A ptr3 & 8 Output > 3000 > XMERTXE Embedded C Pointers - Multilevel Example Hinclude num sae main oo 0 { aint num = 10; int *ptel = énum; int **ptr2 = sptrl; 2000 int ***ptr3 = gptr2; ptr2 g A ptr3 4000 Output > 2000 > XMERTXE Embedded C Pointers - Multilevel Example #include int main () int num = 10; int *ptrl = enum; int **ptr2 = sptrl; int ***ptr3 = gptr2; print£(°4d", ptr3); prints ("4a' “peinte (“a”) *ptrd) return 0; g ptr2 g A ptr3 4000 Output > 1000 XMERTXE Embedded C Pointers - Multilevel Example Hinclude int main () t int num = 10; int *ptrl = enum; int **ptr2 = sptrl; int ***ptr3 = gptr2; print£(°4d", ptr3); prints ("4a g ptr2 g A ptr3 4000 Output > 10 XMERTXE Embedded C Pointers - 2D Array & OLUys > SMERTXE Embedded C Pointers - 2D Array cOLs co c1 C2 Q)11 14 RO| 00 01 02 8 = 2|2 2 2 R1| 10 11 12 > > SMERTXE Embedded C i Pointers - 2D Array Example #include ant main() ant a[2](3) = {1, 2, 3, 4, 5, 6); return 0; y Total Memory: ROWS * COLS * sizeof (datatype) Bytes ZMERTXE Embedded C > Pointers - 2D Array - Referencing 2° 1D array linearly placed in memory . 1020 1016 1012 1008 1004 1000 2" 1D Array with base address 1012 alt] = Ga[1][0] = a+ 1 > 1012 1" 1D Array with base address 1000 a[0] = &a[0][0] = a+ 0 -» 1000 Index to access the 1D array > > EMERTXE Embedded C > Pointers - 2D Array - Dereferencing 2° 1D array linearly Example 1: Say a[0][1] is to be accessed, then placed in memory decomposition happens like, a a[OJ[1] = *(a[0] + 1 * sizeof(type)) a + 0 sizeof(1D array)) + 1 * sizeofitype)) *(*(1000 + 0* 12) +1* 4) =*(°(1000 + 0) +4) *(°(1004)) 1020 1016 1012 1008 Example 2: Say a[1}[2] is to be accessed, then decomposition happens like, 1000 a[1)[2] = *(a[1] + 2 * sizeof(type)) (a + 1* sizeof(1D array)) + 2 * sizeof(type)) *(*(1000 + 1 * 12) +2* 4) (*(1000 + 12) + 8) *(*(1020)) 6 Index to access the 1D array ZMERTXE Embedded C Pointers - Array of pointers Syntax datatype *ptr_name [SIZE] int *ptr[3]; ptr[0] = £a; ptr[1] = &b; ptr[2] = 6c; > ZMERTXE Embedded C Pointers - Array of pointers Syntax datatype *ptr_name [SIZE] Example int a = 10; a b c to 40") mon 260) 0 300) int b = 20; int 30; per a 4000 4004 4008 ptr [0] ptr[l] = : ptr[2] = sc; ZMERTXE Embedded C Pointers - Array of pointers Syntax datatype *ptr_name [SIZE] Example a 5 . int B= 20; 1000 TE oe En EE int b = 20; int ce = 30; int *ptr[3 ptr 1000 2000 3000, 4000 4004 ©4008 ZMERTXE Pointers - Array of pointers Syntax 1004 2004 3004 1000 a 2000 b 3000 c datatype *ptr_name [SIZE] Example int *ptr[3]; ptr[0] pte [1] ptr [2] > ZMERTXE Embedded C o> Pointers - Array of pointers Syntax datatype *ptr_name [SIZE] Example int a[2] = (10, 20); 18 ams aoe int b[2] 30, 40}; 1000 a 2000 b 3000 c int e[2] 50, 60}; ptr per [0] pte [1] ptr [2] 4000 «4004 «= 4008 ZMERTXE Embedded C o> Pointers - Array of pointers Syntax datatype *ptr_name [SIZE] Example int a[2] = (10, 20); ‘18 ams aoe int b[2] 30, 40}; 1000 a 2000 b 3000 c int c[2] = (50, 60}; int *ptr[3]; ptr 4000 «4004 «= 4008 ZMERTXE Embedded C Pointers - Array of pointers Example #include void print_array(int **p) 2 int i; for (4 = 0; 4 <3) at4) ‘ print£("td ", *p[i})¢ printf (‘at ep\n", p{i}); ) int main() print_array (ptr); return 0; b 20 2000 3000 ZMERTXE Embedded C Pointers - Array of pointers Example #include void print_array(int **p) int i; fer (i = 0; 4 <3; Att) print£("td ", *p{i]); printf(*at tp\n”, plil); d int main() int a = 10; int b= 2 int c= 3 31 print_array (ptr); return 0) ZMERTXE Embedded C Pointers - Array of pointers Example #include void print_array(int **p) int i; for (i = 0; 4 <3; itt) print£("td ", *p[i}) + printf (‘at ep\n", pli}; d int main() int a = 10; int b= 2 int c= 3 int “ptr[(3] = (sa, 6b, se)? ZMERTXE Embedded C Pointers - Array of pointers Example #include void print_array! int i; for (i= 0; 4 <3) at) ‘ print£("td ", *p[i})¢ printf (‘at ep\n", pli}: ) int main() int a = 10; int b = 20; int ¢ = 307 int *ptr(3] = (sa, tb, te); print_array (ptr) + return 0) 4000 4004 = 4008 SMERTXE Embedded C Vey» S s- Fill in the blanks please ;) “hath auch tr > SMERTXE Embedded C Strings HS. A set of things tied or threaded together on a thin cord. Source: Google String of Beads v . e a i 4 String a ‘Start of String Bead Contains n numbers of Beads ‘String ends here SMERTXE * Contiguous sequence of characters * Easily stores ASCII and its extensions End of the string is marked with a special character, the null character ‘\0' ‘\0' is implicit in strings enclosed with “” Example “You know, now this is what a string is!” ZMERTXE Embedded C > Strings - Initializations Examples char char array[5] = ({'H', 'E', '"L', 'L', '0'}; < Character Array char str[6) = {'H', 'E', 'L', 'L', 'O', '\O'}; = String char str[] = {'H', 'E', 'L', 'L', '0', "\O"}; «Valid char str[6] = (“H”, “E”, “L”, “L”, “O"}; =< Invalid char str[6] = {“H" “E” “LY “ZL” “O”}; «Valid char str[6) = (“HELLO”); =< Valid char str[6] = “HELLO”; =< Valid char str[] = “HELLO”; =< Valid char *str = “HELLO”; =< Valid > EMERTXE Sungai ae Examples #include int main() { ehar char array 1(5] = {'H', 'E', 'L', 'L', 'O'}; The size of the array char char_array_2[] = “Hello”; Is calculated So, sizeof (ehar_array 1); sizeof (char_array_2); 5,6 return 0; , int main() t char tstr = “Hello”; The size of pointer is a always constant so, sizeof (str); return 0; 4 (32 Bit Sys) XMERTXE Embedded C Wi > Strings - Size Example #include int main() C if (sizeof("Hello” “World”) == sizeof("Hello”) + sizeof ("World”)) { printé(*Wow\n"); ) else printé(*Hul\n") ; } return 0; ZMERTXE Embedded C Strings - Manipulations Examples char stri[6] = “Hello”; char str2(6]; Le Not possible to assign a string to a array since its a constant pointer str2 = “World”; char *str3 = “Hello”; char *str4; Possible to assign a string to a pointer since its variable stra = “World”; stri1[0] = 'h'; < Valid. stri contains “hello” str3(0] = ‘wi; « Invalid. str3 might be stored in read only section. Undefined behaviour ZMERTXE Embedded C Strings - Sharing Example include int main() C char *strl = “Hello”; char *str2 = “Hello”; if (str = str2) print£("Hoo. They share same space\n”); else print£("Nc. They are in different space\n"); 1 xeturn 0; ZMERTXE Embedded C Strings - Library Functions Length Compare Copy Check String Check Character Merge size_t strlen(const char *str) int strcmp(const char *str1, const char *str2) char *strepy(char “dest, const char *src) char *strstr(const char *haystack, const char *needle) char *strchr(const char “s, int c) char *streat(char *dest, const char *src) String Length str1 str2 27> 0 stri =str2 > =0 Pointer to dest Pointer to the beginning of substring Pointer to the matched char else NULL Pointer to dest ZMERTXE Storage Classes Embedded C o> Memory Segments Linux OS 1 The Linux OS is divided into two major sections ‘+ User Space * Kernel Space ‘The user programs cannot access the kernel space. If done will lead te segmentation User violation Space Let us concentrate on the user space section here iclaaT=se Byers) » > SMERTXE Embedded C Memory Segments Linux OS User Space taal =se Serta) User Space nt The User space contains many processes Every process will be scheduled by the kernel Each process will have its memory layout discussed in next slide ZMERTXE Embedded C Memory Segments User Space Memory Segments 5 The memory segment of a Program contains four major areas. * Text Segment * Stack + Data Segment * Heap XMERTXE Embedded C o> Memory Segments - Text Segment Memory Segments Also referred as Code Segment Tita Holds one of the section of program in 3 object file or memory In memory, this is place below the heap or stack to prevent getting over written Is a read only section and size is fixed cumini a Initiatized » > EMERTXE Embedded C o> Memory Segments - Data Segment Memory Segments Contains 2 sections as initialized and uninitialized data segments Initialized section is generally called as Data Segment. Uninitialized section is referred as BSS (Block Started by Symbal) usually filled = with Os 1 Data Segment Initiatized Embedded C o> Memory Segments - Data Segment Memory Segments Dynamic memory allocation takes place here Begins at the end of BSS and grows upward from there i > XMERTXE Embedded C > Memory Segments - Stack Segment Memory Segments Adjoins the heap area and grow in opposite area of heap when stack and heap pointer meet (Memory Exhausted) Typically loaded at the higher part of y memory A “stack pointer” register tracks the top of the stack; it is adjusted each time a value is “pushed” onto the stack The set of values pushed for one function call is termed a “stack frame” Embedded C > Memory Segments - Stack Segment Memory Segments Stack Frame | Saati) "Local Variables A stack frame contain at least. } Ran aS of areturn address Parameter List > XMERTXE Embedded C Memory Segments - Stack Frame Stack Frame #include numt = 10 ant main() fum2 = 20 | { sum = 0 main() int num = 10, num? = 20; Return Address to the caller int som = 0; 3=0 sun = add_pumbers(numi, num2) ; Printé ("Sum is td\n", sum); Return Address to the main) — add numbers() return 0; aire ; n2=20 Ant add_numbers(int nl, int n2) int s = 0; s = nl + n2; return s; > EMERTXE Embedded C W. > Memory Segments - Runtime * Run-time memory includes four (or more) segments - Text area: program text ~ Global data area: global & static variables ~ Allocated during whole run-time * Stack: local variables & parameters - Astack entry for a functions - Allocated (pushed) - When entering a function ~ De-allocated (popped) - When the function returns. * Heap = Dynamic memory - Allocated by malloc() - De-allocated by free() > > SMERTXE Embedded C Storage Classes auto Within the block / Till the end of the block / Stack Function function register Within the block / Till the end of the block / Register Function function static local Within the block / Till the end of the program Data Segment Function Static global File Till the end of the program Data segment extern Program Till the end of the program Data segment ZMERTXE Embedded C Storage Classes Example ftinclude global_i No No nt global_1; int global_2 = 10; an global_3 Static global global_4 Static global localt auto ink meta) tocal_2 Static local { local_3 Static local int lecal_1; lee Register static int local _1; static int loeal_2 = 20; static int global_: static int global_4 register int i; for (4 = 0; i <0; i++) { 1 /* Do Something */ return 0; BSS Initialized data segment -BSS Initialized data segment stack BSS Initialized data segment Registers XMERTXE Embedded C Declaration extern int numl; < extern int numl; 4 ant main(); < ant main() int numl, num2; char short_opt; Declaration specifies type to the variables Its like an announcement and hence can be made 1 or more times Declaration about num1 Declaration about numi yet again!! Declaration about main function > EMERTXE Embedded C Storage Classes - extern filet1.c finelude int num; int main() while (1) { unt; fune_1(); sleep (1); fune_2()? t return 0; file2.c #include * One of the step performed before compilation * Is a text substitution tool and it instructs the compiler to do required pre-processing before the actual compilation * Instructions given to preprocessor are called preprocessor directives and they begin with “#” symbol * Few advantages of using preprocessor directives would be, ~ Easy Development —- Readability — Portability ZMERTXE Preprocessor - Compilation Stages + Before we proceed with preprocessor directive let's try to understand the stages involved in compilation * Some major steps involved in compilation are ~ Pre-processing - Compilation ~ Assembly - Linking * The next slide provide the flow of these stages > SMERTXE Embedded C a Preprocessor - Compilation Stages Compiler < gcc -E file.c == 2: Assembler < a gcc -S file.c (cea gce -c file.c = 4 > SMERTXE Embedded C > Preprocessor - Directives #include #elif #define #error #undef #warning #ifdef #line #ifndef #pragma #else # #endif ## #if #else SMERTXE Embedded C > Preprocessor - Header Files + A header file is a file containing C declarations and macro definitions to be shared between several source files. * Has to be included using C preprocessing directive ‘#include’ + Header files serve two purposes. ~ Declare the interfaces to parts of the operating system by supplying the definitions and declarations you need to invoke system calls and libraries. - Your own header files contain declarations for interfaces between the source files of your program. ZMERTXE Embedded C > Preprocessor - Header Files vs Source Files VS * Declarations * Function and variable * Sharable/reusable definitions + #tdefines + Non sharable/reusable + Datatypes + #defines + Used by more than 1 + Datatypes file Embedded C > Preprocessor - Header Files - Syntax ‘Syntax #include « + System header files * It searches for a file named file ina standard list of system directories ‘Syntax #include “file.h” < * Local (your) header files + It searches for a file named file first in the directory containing the current file, then in the quote directories and then the same directories used for SMERTXE Embedded C Preprocessor - Header Files - Operation a file2.c char *test (void) { static char *str = “Hello”; return str; ) filet.c int num; #include “file2.h” int main() puts (test()); return 0; file2.h char *test (void) ; int num; char *test (void) ; Ant main() puts (test (}); return 0; ZMERTXE Preprocessor - Header Files - Search Path * Ona normal Unix system GCC by default will look for headers requested with #include in: ~ /usr/local/include ~ libdir/gcc/target/version/include - /usr/target/include ~ /usr/include * You can add to this list with the -I command-line option “gcc -print-prog-name=cc1 -v would the search path info > ZMERTXE Embedded C i> Preprocessor - Header Files - Once-Only * If aheader file happens to be included twice, the compiler will process its contents twice causing an error * E.g. when the compiler sees the same structure definition twice * This can be avoided like Example ifndef NAME define NAME /* The entire file is protected */ flendif > SMERTXE Preprocessor - Macro - Object-Like * An object-like macro is a simple identifier which will be replaced by a code fragment It is called object-like because it looks like a data object in code that uses it. They are most commonly used to give symbolic names to numeric constants Syntax fidefine SYMBOLIC NAME ConsTANTS Example f#idefine BUFFER SIZE 1024 ZMERTXE Embedded C i. > Preprocessor - Macro - Arguments * Function-like macros can take arguments, just like true functions * To define a macro that uses arguments, you insert parameters between the pair of parentheses in the macro definition that make the macro function-like Example #include define SET_BIT(num, pos) (num | (1 << pos)) int main() SET BIT(O, 2); return 0; ZMERTXE Embedded C Preprocessor - Macro - Multiple Lines we You may continue the definition onto multiple lines, if necessary, using backslash- newline. When the macro is expanded, however, it will all come out on one line Example include #idefine SWAP(a, b) { nt temp = a; by temp; poe we } dnt main() Sinise 10, num2= 20; SWAP(num1, num2) ; print£("¢d td\n”, numl, num2); return 0; > SMERTXE Embedded C Preprocessor - Macro - Stringification Example include #define WARN_IF (EXP) \ do \ { x x=} \ if (EXP) \ { \ fprintf(stderr, "Warning: " #EXP "\n"); \ } N } while (x); int main() { iat x * You can convert a macro argument into a string ; eee constant by adding # WARN_IF(x == 0); ZMERTXE Embedded C Preprocessor - Macro - Concatenation Example #include fidefine CaT (x) (xii#t_val) int main() { int int_val = 4; float float_val = 2.54; printf("int val = %d\n", CAT(int)); printf€("flost val = 8£\n", CAT(float)) ; return 0; ZMERTXE Embedded C > Preprocessor - Macro - Standard Predefined * Several object-like macros are predefined; you use them without supplying their definitions. * Standard are specified by the relevant language standards, so they are available with all compilers that implement those standards Example #inelude int main() { PFint£("Progcam: \"Gs\" ", FILE) printf(*was compiled on te at $e. 7, DATE, _TIME_): print£("This print is from Function; \"ts\” at Tine d\n”, _func_, LINE); return 0; ZMERTXE Embedded C Preprocessor - Conditional Compilation * A conditional is a directive that instructs the preprocessor to select whether or not to include a chunk of code in the final token stream passed to the compiler * Preprocessor conditionals can test arithmetic expressions, or whether a name is defined as a macro, or both simultaneously using the special defined operator * Aconditional in the C preprocessor resembles in some ways an if statement in C with the only difference being it happens in compile time * Its purpose is to allow different code to be included in the program depending on the situation at the time of compilation. ZMERTXE Embedded C Preprocessor - Conditional Compilation * There are three general reasons to use a conditional. - A program may need to use different code depending on the machine or operating system it is to run on - You may want to be able to compile the same source file into two different programs, like one for debug and other as final - Aconditional whose condition is always false is one way to exclude code from the program but keep it as a sort of comment for future reference > > SMERTXE Embedded C Preprocessor - Conditional Compilation - ifdef Vi» Syntax #ifdef MACRO /* Controlled Text */ flendif ZMERTXE Preprocessor - Conditional Compilation - defined Syntax #if defined (ERROR) && (WARNING) /* Controlled Text */ flendif SMERTXE Embedded C Preprocessor - Conditional Compilation - if Syntax #if expression /* Controlled Text */ flendif ZMERTXE Embedded C Preprocessor - Conditional Compilation - else Syntax #if expression /* Controlled Text if true */ Helse /* Controlled Text if false */ endif ZMERTXE Embedded C Preprocessor - Conditional Compilation - elif Syntax #if DEBUG LEVEL == 1 /* Controlled ‘Text*/ felif DEBUG LEVEL == 2 /* Controlled Text */ Helse /* Controlled Text */ fendi SMERTXE Embedded C > Preprocessor - Conditional Com... - Deleted Code Syntax Hit 0 /* Deleted code while compiling */ /* Can be used for nested code comments */ 7* Avoid for general comments */ flendif XMERTXE Embedded C >> Preprocessor - Diagnostic * The directive ‘#error’ causes the preprocessor to report a fatal error. The tokens forming the rest of the line following ‘#error’ are used as the error message * The directive ‘#warning’ is like ‘#error’, but causes the preprocessor to issue a warning and continue preprocessing. The tokens following ‘#warning’ are used as the warning message > > SMERTXE User Defined Datatype Embedded C >> User Defined Datatypes (UDT) * Sometimes it becomes tough to build a whole software that works only with integers, floating values, and characters. + In circumstances such as these, you can create your own data types which are based on the standard ones * There are some mechanisms for doing this in C: - Structures — Unions - Typedef - Enums * Hool!!, let's not forget our old friend _r_a_ which is a user defined data type too!!. ZMERTXE Embedded C UDTs - Structures > SMERTXE Embedded C >> UDTs - Structures + Acomplex data type declaration that defines a physically grouped list of variables to be placed under one name in a block of memory * Unlike arrays, structures allows different data types in the allocated memory region * Generally useful whenever a lot of data needs to be grouped together * Allows us to have OOPS concepts in C, - Data first - Data centric (Manipulations on data) - Better Design > > SMERTXE Embedded C >> UDTs - Structures syntax * If we consider the Student as struct Structuxsiane an example, The admin /* Group of data types */ should have at least some i important data like name, ID and address. * So we if create a structure for the above requirement, it would look like, Example struct Student int id; char name[30]; char address[150] i > > SMERTXE Embedded C > UDTs - Structures - Declartion and definition Example Name of the datatype. Note it's struct Student and not Student Are called as fields or members of of the structure Declaration ends here The memory is not yet allocated! $1 is a variable of type struct Student The memory is allocated now int main() struct Student return 0; » > SMERTXE Embedded C i> UDTs - Structures - Memory Layout Example * What does s1 contain? struct Student ven { * How can we draw it's memory int id; layout? char name[30]; char address([150]; ie "A int main() struct Student sl; name return 0; } address ZMERTXE Embedded C > UDTs - Structures - Access Example * How to write into id now? t Student ee * It's by using “.” (Dot) dnt 14) operator char name[30] ; char address[150]; ye st int main() struct Student si; name address return 0; } * Now please assign the name for s1 > ZMERTXE Embedded C UDTs - Structures - Initialization Example a struct Student . { id int id; char name(30); name char address [150]; hi int main() address struct Student sl = (10, “Tingu”, “Bangalore”}; return 0; ZMERTXE Embedded C UDTs - Structures - Copy Example eT struct Student { id int id; char name [30] ; name char address[150}; Vi ant main() address struct Student si = {10, “Tingu”, “Bangalore”}; struct Student 52; tte G kee nce ZMERTXE Embedded C UDTs - Structures - Address Example struct Student { int id; char name [30]; char address[150] ; int main() struct Student s1 = (10, “Tingu”, “Bangalore”}; printé("Structure starts at tp\n", 681); printf£(‘Member id is at *p\n”, gsl.id); printf(‘Member name is at %p\n”, &S1.name) ; printf("Member address is at ‘p\n”, 6s1.address) ; return 0; XMERTXE Embedded C >> UDTs - Structures - Pointers * Pointers!!!. Not again ;). Fine don't worry, not a big deal * But do you have any idea how to create it? * Will it be different from defining them like in other data types? ZMERTXE Embedded C > UDTs - Structures - Pointer Example struct Student sptr 2000 Polen Se char name(30]; char address [150] ; sf ase) » 1000 struct Student s1; struct Student *sptr = él; name return 0; address SMERTXE Embedded C UDTs - Structures - Pointer - Access Example struct Student { int id; char name[30]; char address[150]; int main() struct Student si; struct Student *sptr = és1; (*sptr) .id = 10; return 0; sptr 2000 1000 st * 1000 name address ZMERTXE Embedded C UDTs - Structures - Pointer - Access - Example struct Student { int id; char name [30]; char address[150]; Vi int main() struct Student sl; struct Student *sptr = 651; sptr->id = 10; return 0; Nec ete ee aaa eee oe ne react a Ue eel me) 1-1 ree noe magse OoaldNm se) Arrow sptr 20001000 st * 1000 name address XMERTXE Embedded C >> UDTs - Structures - Functions * The structures can be passed as parameter and can be returned from a function * This happens just like normal datatypes. * The parameter passing can have two methods again as normal - Pass by value - Pass by reference ZMERTXE Embedded C UDTs - Structures - Functions - Pass by Value Example struct Student { int id; char name [30] ; char address[150] ; Ve void data(struct Student s) ‘ s.id = 10; 1 int main() struct Student s1; data(s1) ; return 0; Not recommended on } ETS ZMERTXE UDTs - Structures - Functions - Pass by Referenc Example struct Student { int id; char name [30] ; char address[150] ye void data(struct Student *s) s->id = 10; 1 int main() struct Student sl; data(ss1); return 0; seoT Uae te Rel} } Eee ZMERTXE Embedded C UDTs - Structures - Functions - Return Example struct Student { int id; char name [30]; char address[150] Ve struct Student data(struct Student s) { s.id = 10; return 8; ) dnt main () SS pierod ates sl; sl = data(si); return 0; } ZMERTXE Embedded C W. > UDTs - Structures - Padding Adding of few extra useless bytes (in fact skip address) in between the address of the members are called structure padding. What!!?, wasting extra bytes!!, Why? This is done for Data Alignment. Now!, what is data alignment and why did this issue suddenly arise? No its is not sudden, it is something the compiler would internally while allocating memory. So let's understand data alignment in next few slides ZMERTXE Embedded C >: Data Alignment * A way the data is arranged and accessed in computer memory. * When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (4 bytes in 32 bit system) or larger. * The main idea is to increase the efficiency of the CPU, while handling the data, by arranging at a memory address equal to some multiple of the word size * So, Data alignment is an important issue for all programmers who directly use memory. ZMERTXE Eabetieis Fi>> * If you don’t understand data and its address alignment issues in your software, the following scenarios, in increasing order of severity, are all possible: — Your software will run slower. — Your application will lock up. ~ Your operating system will crash. - Your software will silently fail, yielding incorrect results. > > SMERTXE Embedded C i> Data Alignment Example * Lets consider the code as i main() given char ch = 'A'; i Ce ie 2 oe eee) * The memory allocation we ) expect would be like shown in figure * So lets see how the CPU tries | to access these data in next ES slides ZMERTXE Embedded C i> Data Alignment Example * Fetching the character by int main() i the CPU will be like shown char ch = 'A'; below int mum = 0412345678; SMERTXE Embedded C > Data Alignment Example * Fetching the integer by ee the CPU will be like shown char ch = 'A'; below int num = 0%12345678; } 0 ma " 1 7B Bo 2 56 cs 3 34 4 12 5 6 7 SMERTXE Embedded C Wie Data Alignment Example * Fetching the integer by ae the CPU will be like shown char ch = 'A'; below int mum = 0x12345678; } Sari s 78 56 56 4 34 0 1 2 3 4 12 . oo E ? 6 / 5 SS ZMERTXE Babess Fy Example * Fetching the integer by oat) the CPU will be like shown char ch = 'A'; below . int mum = 0x12345678; Shift 1 Byte Up = ” 3 8 56 34 2 56 on = o 78 3 34 56 4 2 => 34 5 42 => 0 12 6 ° Combine 7 0 2 Shift 3 Byte Down ZMERTXE Embedded C UDTs - Structures - Data Alignment - Padding * Because of the data alignment issue, structures uses padding between its members if the don't fall under even address. * So if we consider the following structure the memory allocation will be like shown in below figure Example struct Test { char chi; int num; char ch2; ZMERTXE Embedded C i> UDTs - Structures - Data Alignment - Padding * You can instruct the compiler to modify the default padding behavior using #pragma pack directive Example tpragma pack 2) o aH struct Test | ‘num { 2 num char chil; 30 num int num; char ch2; 4 nog , per | ZMERTXE Embedded C >> UDTs - Structures - Bit Fields * The compiler generally gives the memory allocation in multiples of bytes, like 1, 2, 4 etc., What if we want to have freedom of having getting allocations in bits?!. * This can be achieved with bit fields. * But note that — The minimum memory allocation for a bit field member would be a byte that can be broken in max of 8 bits — The maximum number of bits assigned to a member would depend on the length modifier — The default size is equal to word size ZMERTXE Embedded C Wi >» UDTs - Structures - Bit Fields Example struct Nibble t unsigned char lower =: 4; unsigned char upper: 4; Me * The above structure divides a char into two nibbles * We can access these nibbles independently ZMERTXE Embedded C UDTs - Structures - Bit Fields Example struct Nibble { unsigned char lower = 4; unsigned char upper: 4; vi int main() nibble.upper = OxA; nibble.lower = 0x2; return 0; J XMERTXE Embedded C UDTs - Structures - Bit Fields Example struct Nibble { unsigned char lower = 4; unsigned char upper =: 4; Vi int main() struct Nibble nibble; XMERTXE Embedded C UDTs - Structures - Bit Fields Example struct Nibble 4 unsigned char lower: 4; unsigned char upper: 4; vi int. main} 1tTo1roodi1de { struct Nibble nibble; XMERTXE Embedded C UDTs - Unions > SMERTXE Embedded C >: * Like structures, unions may have different members with different data types. * The major difference is, the structure members get different memory allocation, and in case of unions there will be single memory allocation for the biggest data type > > SMERTXE Embedded C is Example union Test t char option; int id; double height; be * The above union will get the size allocated for the type double * The size of the union will be 8 bytes. + All members will be using the same space when accessed * The value the union contain would be the latest update * So as summary a single variable can store different type of data as required > > SMERTXE Embedded C UDTs - Unions Example union Test ( temp_var char option; int id; 1 double height; Me . Total 8 Bytes eeearety allocated since longest member is temp_var.height = 7.2; double temp_var.id = 0x1234 temp_var.option = '1'; 1007 return 0; ZMERTXE Embedded C UDTs - Unions Example union Test 4 temp_var char option; int id; 00; OxcD double height; ‘Oxce be OxcC c maze ‘Oxce double uses union Test temp_var; Oxcc its memory Oxcc ‘temp_var.id = Ox! ‘oxic temp_var.option = '1'; 1007 0x40 return 0; ZMERTXE Embedded C UDTs - Unions Example union Test 4 char option; int id; double height; ve int main() union Test temp_var; temp_var 1000 0x34 Ox12 0x00 0x00 int shares double's memory 1007 SMERTXE Embedded C UDTs - Unions Example union Test 4 be char option; int id; double height; int main() { union Test temp_var; temp_var.height m, temp_var 1000 0x31 char shares double's memory 1007 SMERTXE Embedded C is * Typedef is used to create a new name to the existing types. * K&R states that there are two reasons for using a typedef. — First, it provides a means to make a program more portable. Instead of having to change a type everywhere it appears throughout the program's source files, only a single typedef statement needs to be changed. - Second, a typedef can make a complex definition or declaration easier to understand. ZMERTXE Embedded C UDTs - Typedefs Example typedef unsigned int uint; int main() t uuint number; return 0; Example typedef int * intptr; int main() { intptr ptrl, ptr2, ptr3; return 0; Example typedef struct Student 4 int id; char name[30]; char address[150] } Student; veid data (Student s) { s.id = 10; ) ant main () { Student si; data(s1) ; return 0; SMERTXE Embedded C UDTs - Typedefs Example #include typedef int (*fptr) (int, int); int add(int numl, int num2) if return numl + num2; }: int main() fptr function; function = add; printf(°%d\n", funetion(2, 4)); xeturn 0; ZMERTXE Embedded C UDTs - Enums i> * Set of named integral values Examples * The above example has two members ae ecoisee with its values starting from 0. i.e, eels e false = 0 and e_true = 1. By, + The member values can be explicitly ae oe initialized ae * There is no constraint in values, it can be e_green in any order and same values can be } Color; repeated typedef enum rei + Enums does not have name space of its blue own, so we cannot have same name used } Color; again in the same scope. int blue; ZMERTXE | Stay Connected About us: Emertxe is India’s one of the top IT finishing schools & self Learning kits provider. Our primary focus is on Embedded with diversification focus an Java, Oracle and Android areas Emertxe Information Technologies, No=1, 9th Cross, Sth Main, Jayamahal Extension, Bangalore, Karnataka 560046 T: +91 80 6562 9666. Es » XMERTXE Hope you enjoyed the session. Thank You

You might also like