NHÚNG. nhúng dùng 1 hay nhiều CPU dựa trên vi ñiều. ngữ và C. nhúng; sử dụng ñược các hệ ñiều hành nhúng cơ bản (FreeRTOS).

Save this PDF as:
 WORD  PNG  TXT  JPG

Size: px
Start display at page:

Download "NHÚNG. nhúng dùng 1 hay nhiều CPU dựa trên vi ñiều. ngữ và C. nhúng; sử dụng ñược các hệ ñiều hành nhúng cơ bản (FreeRTOS)."

Transcription

1 LẬP TRÌNH HỆ THỐNG NHÚNG BÙI QUỐC BẢO BỘ MÔN KỸ THUẬT ðiện TỬ-ðH BK TP.HCM Mục tiêu môn học Tự mình thiết kế phần mềm cho một hệ thống nhúng dùng 1 hay nhiều CPU dựa trên vi ñiều khiển (8051, ARM) dựa trên một phần cứng có sẵn. Phần mềm ñược thiết kế có cấu trúc, dựa trên ngôn ngữ cấp cao (C) hoặc sử dụng cả hợp ngữ và C. Nắm ñược lý thuyết cơ bản về hệ ñiều hành nhúng; sử dụng ñược các hệ ñiều hành nhúng cơ bản (FreeRTOS). 1

2 Tài liệu tham khảo C and the 8051, 3 rd Edition, Thomas Schultz Embedded C, Michael J Pont ðánh giá kết quả Giữa kỳ: 20% Bài tập lớn: 30% Cuối kỳ: 50% 2

3 Khái niệm về hệ thống nhúng Hệ thống nhúng là sự kết hợp giữa phần cứng máy tính và phần mềm, ñược thiết kế ñể thực hiện một chức năng chuyên biệt. Người sử dụng một hệ thống nhúng không cần biết rằng hệ thống có một máy tính bên trong VD: remote TV, lò vi sóng, Vi xử lý trong hệ thống nhúng Họ 8086 PowerPC MIPS Họ 8051 PIC Tùy thuộc vào ứng dụng và giá thành, người thiết kế quyết ñịnh loại vi xử lý dùng trong hệ thống nhúng. 3

4 Vi xử lý dùng trong môn học này 8051 ARM Ngôn ngữ lập trình Assembler C 4

5 Lý do sử dụng ngôn ngữ C C cho phép lập trình có cấu trúc. Ngôn ngữ C cho phép dễ dàng truy cập ñến cấu trúc phần cứng (ví dụ thông qua con trỏ) C ñược dùng rất phổ biến. Hầu hết các họ vi xử lý ñều ñược hỗ trợ trình biên dịch C. Rất nhiều taì nguyên tham khảo (sách, ví dụ, website ) về lập trình C. Lý do dùng hợp ngữ (Assembler) Cho phép viết những chương trình có kích thước nhỏ nhất và chạy với tốc ñộ nhanh nhất. Thích hợp cho những ứng dụng có yêu cầu nghiêm ngặt về thời gian. 5

6 C operator < >! ~ + - * / % & ^. assignment statement address of selection less than greater than logical not (true to false, false to true) 1's complement addition subtraction multiply or pointer reference divide modulo, division remainder logical or logical and, or address of logical exclusive or used to access parts of a structure C operator == <= >=!= << >> && equal to comparison less than or equal to greater than or equal to not equal to shift left shift right increment decrement boolean and boolean or 6

7 += -= *= /= = &= ^= <<= >>= %= -> add value to subtract value to multiply value to divide value to or value to and value to exclusive or value to shift value left shift value right modulo divide value to pointer to a structure Comments (chú thích) // This is a comment line /* This is a comment block */ 7

8 Preprocessor Directives (chỉ dẫn tiền xử lý) ðược xử lý ñầu tiên trong quá trình biên dịch Bắt ñầu bằng từ khóa # VD: #include LCD.h" #define LCD *(unsigned char volatile *)(0x1003) Key word (Từ khóa) asm auto break case char const continue default do double else extern float Insert assembly code Specifies a variable as automatic (created on the stack) Causes the program control structure to finish One possibility within a switch statement 8 bit integer Defines parameter as constant in ROM Causes the program to go to beginning of loop Used in switch statement for all other cases Used for creating program loops Specifies variable as double precision floating point Alternative part of a conditional Defined in another module Specifies variable as single precision floating point 8

9 Key word (Từ khóa) for goto if int long register return short Used for creating program loops Causes program to jump to specified location Conditional control structure 16 bit integer 32 bit integer store the variable onto the CPU register if space on the register is available Leave function 16 bit integer Key word (Từ khóa) signed sizeof static struct switch typedef unsigned void volatile while Specifies variable as signed (default) Built-in function returns the size of an object Stored permanently in memory, accessed locally Used for creating data structures Complex conditional control structure Used to create new data types Always greater than or equal to zero Used in parameter list to mean no parameter Can change implicitly Used for creating program loops 9

10 Dấu chấm phẩy (semicolons) Chấm dứt câu lệnh VD: For (i=0;i<1000;i++); Dấu hai chấm (colons) Dùng ñể ñịnh nghĩa 1 nhãn (label) VD: char Debounce(void) short Cnt; unsigned char LastData; Start: Cnt=0; /* number of times Port C is the same */ LastData=PORTC; Loop: if(++cnt==100) goto Done; /* same thing 100 times */ if(lastdata!=portc) goto Start;/* changed */ goto Loop; Done: return(lastdata); } 10

11 Dấu phẩy (Commas) Dùng ñể ngăn cách các phần tử. VD: unsigned short begintime, endtime, elapsedtime; short add(short x, short y) ; Dấu nháy (Apostrophes) Dùng ñể xác ñịnh ký tự VD: mych='a' ; 11

12 Dấu nháy kép (Quotation marks ) Dùng ñể xác ñịnh chuỗi (string) VD: unsigned char Name[] = embedded"; Dấu ngoặc nhọn (braces) Dùng ñể bắt ñầu và kết thúc một khối câu lệnh VD: For (i=0;i<100;i++) { delay(100); PORTB = 0xff; delay(100); PORTB = 0x00; } 12

13 Dấu ngoặc vuông (Brackets ) Dùng ñể chỉ kích thước của mảng (array) và chỉ số VD: short fifo[100]; I = fifo[0]; Dấu ngoặc tròn (Parentheses ) Bao quanh danh sách tham số VD: add(x,y); Xác ñịnh mức ñộ ưu tiên thực thi của các biểu thức VD: X = (17+3)/2 ; 13

14 Biến tĩnh (Static) Biến tĩnh là biến mà giá trị của nó ñược giữ trong suốt quá trình chương trình chạy, nhưng chỉ truy cập ñược bên trong chương trình mà nó ñược ñịnh nghĩa Biến tĩnh char sumit(void) static char sum = 0; sum = sum + 1; return sum; } void main(void) char i; char result; for(i=0;i<10;i++) result = sumit(); } 14

15 Từ khóa volatile Từ khóa volatile mô tả 1 biến mà giá trị có thể thay ñổi không ñoán trước ñược. Biến volatile ñược dùng ñể mô tả: Các ngoại vi ñược thiết kế theo kiểu memory-mapped Biến toàn cục mà bị thay ñổi giá trị trong trình phục vụ ngắt Biến toàn cục ñược truy cập bởi nhiều tác vụ trong các ứng dụng ña tác vụ Từ khóa volatile void main(void) unsigned char xdata *p = (char xdata *) 0x8000; while (*p == 0); } void main(void) volatile unsigned char xdata *p = (char xdata *) 0x8000; while (*p == 0); } 15

16 Từ khóa extern Dùng ñể chỉ biến ñược ñịnh nghĩa trong 1 module khác. VD: Trong module LCD.h, khai báo biến char LCD_value; Trong module main.h extern char LCD_value; Biến ñược khởi tạo trước short Temperature = -55; const unsigned short Steps[4] = {10, 9, 6, 5}; char Name[4] = "Jon"; char Name[6] = "Jon"; char Name[] = "Jon"; char *NamePt = "Jon"; 16

17 Con trỏ (pointer) Con trỏ là 1 biến chứa một ñịa chỉ Giá trị của con trỏ có thể thay ñổi ñược Question: Khai báo biến a: int a; ðịa chỉ của biến a: &a có phải là con trỏ hay không? Con trỏ int *p; p = 0x8000; int *p = (int *)0x8000; int k; p = &k; #define SW *(unsigned char volatile *)(0x2000) 17

18 Phép toán với con trỏ Phép cộng: Con trỏ luôn chỉ vào ñịa chỉ ñầu của một ñối tượng (object). Cộng 1 vào con trỏ làm nó chỉ ñến ñối tượng tiếp theo. Phép so sánh: Khi so sánh 2 con trỏ, giá trị chúng ñang mang ñược coi như số không dấu int *p; p 0x01 0x2000 int *k; p = 0x2000; k 0x00 0x02 0x00 0x2001 0x2002 0x2003 *p = 1; k = p+1; *k = *p+1; 18

19 Mảng và chuỗi (array and string) Mảng là tập hợp các biến giống nhau có cùng tên gọi. Các phần tử của mảng ñược xác ñịnh bằng chỉ số (bắt ñầu từ 0). Kích thước của mảng là cố ñịnh. VD: int a[4] = {1,2,3,4}; int b = a[0]; Mảng và chuỗi (array and string) Chuỗi tương tự mảng, ngoại trừ: Chuỗi có thể có số lượng phần tử thay ñôỉ. Các phần tử của chuỗi là ký tự ASCII kết thúc bằng giá trị 0. Chuỗi ñược khai báo như 1 con trỏ kiểu char char * mystring = embedded ; 19

20 Kiểu cấu trúc (structure) Một structure là tập hợp của nhiều biến. Các biến trong struct có thể khác kiểu nhau. struct theport int mode; // 0 for I/O, 1 for in only -1 for out only unsigned char volatile *addr; // pointer to its address unsigned char volatile *ddr; // pointer to its direction reg }; struct theport PortA, PortB, PortC; Structure struct theport int mode ; // 0 for I/O, 1 for in only -1 for out only unsigned char volatile *addr ; // pointer to its address unsigned char volatile *ddr ; // pointer to its direction //reg } PortA, PortB, PortC; 20

21 struct theport int mode; // 0 for I/O, 1 for in only -1 for out only unsigned char volatile *addr; // pointer to its address unsigned char volatile *ddr; // pointer to its direction reg }; typedef struct theport port; port PortA, PortB, PortC; Struct typedef struct int mode ; // 0 for I/O, 1 for in only -1 for out only unsigned char volatile *addr ; // pointer to its address unsigned char volatile *ddr ; // pointer to its direction //reg } port; port PortA, PortB, PortC; 21

22 Truy cập phần tử con của struct PortC.mode=0; PortC.addr=(unsigned char volatile *)(0x1003); PortC.ddr=(unsigned char volatile *)(0x1007); (*PortC.ddr)=0; (*PortB.addr)=(*PortC.addr); Truy cập struct thông qua pointer port PORTA; port *p; p = &PORTA; p->mode=0; (dùng dấu -> ñể truy cập phần tử con của 1 con trỏ kiểu struct) 22

23 Khởi tạo struct port PortE={1, (unsigned char volatile *)(0x100A), (unsigned char volatile *)(0)}; Struct and union typedef struct { union { IO uint32_t u32ispcon; struct IO uint32_t ISPEN:1; IO uint32_t BS:1; I uint32_t RESERVE0:2; IO uint32_t CFGUEN:1; IO uint32_t LDUEN:1; IO uint32_t ISPFF:1; IO uint32_t SWRST:1; IO uint32_t PT:3; I uint32_t RESERVE1:1; IO uint32_t ET:3; I uint32_t RESERVE2:17; } ISPCON; }; union IO uint32_t u32ispadr; IO uint32_t ISPADR; } }FMC_T; #define AHB_BASE (( uint32_t)0x ) #define FMC_BASE (AHB_BASE +0x0C000) #define FMC ((FMC_T *)FMC_BASE) FMC->ISPCON.ISPEN = 1 FMC->ISPADR = 0x ; 23

24 Function (Hàm, chương trình con) Một chương trình lớn thường ñược chia thành nhiều khối (module) Module là 1 tác vụ nhận dữ liệu vào (input), xử lý và xuất ra kết quả (output). Các module ñược tạo ra như là các hàm (function). Function Một module (Nguồn: EmbeddedProg/Developing Embedded Software in C) int FtoC(int TempF){ int TempC; TempC=(5*(TempF-32))/9; // conversion return TempC;} Note: Hạn chế truy cập ñến biến toàn cục và I/O trong 1 function 24

25 Mô tả hàm (function declaration) Mô tả hàm cho ta biết tên hàm, kiểu của các tham số và kiểu kết quả trả về. // declaration input output void Ritual(void); // none none char InChar(void); // none 8-bit void OutChar(char letter); // 8-bit none short InSDec(void); // none 16-bit void OutSDec(short i); // 16-bit none char Max(char in1,char in2); // two 8-bit 8-bit int EMax(int in1,int in2); // two 16-bit 16-bit void OutString(char* mystring); // pointer to 8-bit none char *alloc(int size); // 16-bit pointer to 8-bit int Exec(void(*fnctPt)(void)); // function pointer 16-bit ðịnh nghĩa hàm (function definition) Một ñịnh nghĩa của hàm là cách mà hàm ñó thực thi. type Name(parameter list){ CompoundStatement }; int FtoC(int TempF) { int TempC; TempC=(5*(TempF-32))/9; // conversion return TempC; } 25

26 Mô tả hàm Một module thường bao gồm 2 file: Header file (dùng chứa các mô tả hàm). Source file (dùng chứa các ñịnh nghĩa hàm) Extern function Khi ta cần khai báo một hàm ñược ñịnh nghĩa ở một module khác, ta dùng từ khóa extern extern void InitSCI(void); extern char InChar(void); extern void OutChar(char character); 26

27 Truyền tham số (Arguments passing) Có hai phương pháp truyền tham số cho chương trình con: Truyền tham chiếu (call by reference) Truyền giá trị (call by value) Truyền tham chiếu (call by reference) Tham chiếu (con trỏ) ñến tham số ñược ñưa vào chương trình con. Các tính toán trong chương trình con sẽ ảnh hưởng ñến biến ñược ñược truyền vào. int increment(int *num) *num++; return *num; } Void main(void) int number = 1; int temp; temp = increment(& number ); } 27

28 Truyền giá trị (call by value) Giá trị của biến sẽ ñược sao chép và truyền vào chương trình con. Các phép tính trên tham số trong chương trình con không ảnh hưởng biến ban ñầu. int increment(int num) num++; return num; } Void main(void) int number = 1; int temp; temp = increment(number ); } Struct làm tham số của chương trình con struct theport int mode; // 0 for I/O, 1 for in only -1 for out only unsigned char volatile *addr; // pointer to its address unsigned char volatile *ddr; // pointer to its direction reg }; typedef struct theport port; unsigned char Input(port theport) return (theport.addr); } unsigned char Input(port *theport) return (theport->addr); } Function nào là tốt hơn? 28

29 Con trỏ hàm (function pointer) Con trỏ hàm là con trỏ chỉ ñến 1 hàm. int (*fp)(int); // pointer to a function with input and output int fun1(int input) return(input+1); // this adds 1 }; int fun2(int input) return(input+2); // this adds 2 }; void Setp(void) int data; fp=&fun1; // fp points to fun1 data=(*fp)(5); // data=fun1(5); fp=&fun2; // fp points to fun2 data=(*fp)(5); // data=fun2(5); }; Question: Giải thích sự khác nhau giữa: int (*fp)(int); int *fp(int); 29

30 Con trỏ hàm là tham số của 1 hàm khác int fun1(int input){ return(input+1); // this adds 1 }; int fun2(int input){ return(input+2); // this adds 2 }; int execute(int (*fp)(int)) int data; data=(*fp)(5); // data=fun1(5); return (data); }; void main(void) int result; result=execute(&fun1); // result=fun1(5); result=execute(&fun2); // result=fun2(5); }; Hàm callback Hàm callback là hàm ñược gọi khi có 1 sự kiện xảy ra. MyButton void create_button( int x, int y, const char *text, function callback_func ); MyButton ButtonClickedEvent callback_func click 30

31 Ví dụ về hàm callback void cbfunc() { printf("called"); } int main () { /* function pointer */ void (*callback)(void); /* point to your callback function */ callback=(void *)cbfunc; /* perform callback */ callback(); return 0; } Truyền tham số cho hàm callback typedef struct _myst int a; char b[10]; }myst; void cbfunc(myst *mt) fprintf(stdout,"called %d %s.",mt->a,mt->b); } int main() /* func pointer */ void (*callback)(void *); //param myst m; m.a=10; strcpy(m.b,"123"); /* point to callback function */ callback = (void*)cbfunc; /* perform callback and pass in the param */ callback(&m); return 0; } 31

32 Chỉ dẫn tiền biên dịch (Preprocessor Directives ) #define size 100 int data[size]; #define LCD *(unsigned char *)0x2000 Chỉ dẫn tiền biên dịch (Preprocessor Directives ) #ifdef A #endif #ifndef B #endif 32

33 Chỉ dẫn tiền biên dịch (Preprocessor Directives ) #define Debug #define LCD *(unsigned char *)0x2000 void LCD_write(char data) #ifdef Debug printf( entering LCD_write ); #endif LCD = data; #ifdef Debug printf( exitting LCD_write ); #endif return; } Debug macro #ifdef PRGDEBUG #define DBG(x) printf(x) #else #define DBG(x) /* nothing */ #endif 33

34 Chỉ dẫn tiền biên dịch (Preprocessor Directives ) #include "Filename" #include <Filename> 34