Professional Documents
Culture Documents
Hệ thống máy tính (hoặc chỉ máy tính) thường được mô hình hóa là một
hệ thống bao gồm:
- Đầu vào: tín hiệu vật lý từ môi trường
- Đầu ra: phản hồi của hệ thống với môi trường
- Và đơn vị xử lý: tìm nạp và thực hiện các lệnh từ bộ nhớ
- Một thành phần của một số sản - Một sản phẩm hoàn chỉnh
phẩm lớn hơn; mục đích của nó là
tập trung hạn chế vào việc hỗ trợ
sản phẩm đó
- Người dùng cuối của sản phẩm - Người dùng cuối tương tác trực
thường không tương tác trực tiếp tiếp với nó
với hệ thống nhúng hoặc chỉ tương
tác với một giao diện hạn chế
- Người dùng không coi sản phẩm - Người dùng biết rõ ràng về sản
(ví dụ: máy nghe nhạc DVD, máy phẩm họ đang mua là một chiếc
nghe nhạc MP3, bảng điều khiển máy tính
trò chơi) mà họ đang mua là máy
tính
“Hệ thống nhúng là hệ thống máy tính có tích hợp phần cứng và phần mềm
được kết hợp chặt chẽ, được thiết kế để thực hiện một chức năng chuyên
dụng. Từ ‘nhúng’ phản ánh thực tế là các hệ thống này thường là một phần
không thể thiếu của hệ thống / sản phẩm lớn hơn (cơ hoặc điện), được gọi
là hệ thống nhúng. Nhiều hệ thống nhúng có thể cùng tồn tại trong một hệ
thống nhúng. ” – (Qing Li and Carolyn Yao)
● Đặc điểm của hệ thống nhúng
- Cấu trúc hệ thống:
+ Cảm biến: để lấy dữ liệu từ môi trường của nó
+ ADC: chuyển đổi dữ liệu tương tự từ cảm biến sang tín hiệu
số
+ Bộ điều khiển: đầu não của hệ thống; thực hiện đồng thời một
tập hợp các tác vụ thời gian thực, có thể có hoặc không với sự
hỗ trợ của RTOS(hệ thống điều hành thời gian thực)
+ Bộ truyền động: thông qua bộ truyền động, bộ điều khiển tác
động lên hệ thống đích
+ DAC: chuyển đổi tín hiệu kỹ thuật số từ vi điều khiển sang tín
hiệu tương tự
- Chức năng tinh vi:
+ Các thuật toán phức tạp: ô tô, điện hạt nhân, hàng không vũ
trụ, ...
+ Giao diện người dùng: giọng nói, hình ảnh, ...
- Các hạn chế về hiệu suất:
+ Thời gian thực (Hard/Soft real-time)
+ Nhiều tỷ lệ
+ Xử lý đa tác vụ, hoạt động ở các mức độ khác nhau
- Yêu cầu chi phí: Chi phí sản xuất, Nguồn cấp và năng lượng, giá
thành thấp.
- Môi trường bị ràng buộc cao
+ Môi trường hạn chế tài nguyên cao: tốc độ bộ xử lý, dung
lượng bộ nhớ và giao diện người dùng
- Đồng thời
+ Một số tính toán đang thực hiện đồng thời và có khả năng
tương tác với nhau
- An toàn và Độ tin cậy
+ An toàn có nghĩa là “không bị tai nạn hoặc mất mát” trong
trường hợp không có lỗi cũng như khi có lỗi đơn điểm.
+ Độ tin cậy đề cập đến khả năng của một hệ thống hoặc thành
phần để thực hiện các chức năng cần thiết của nó trong các
điều kiện đã nêu trong một thời gian xác định.
Được đo bằng lỗi trên một triệu giờ hoạt động
● Tại sao nhúng bộ vi xử lý vào hệ thống?
- Bộ vi xử lý là một cách rất hiệu quả để triển khai các hệ thống kỹ
thuật số:
+ Bộ xử lý hiệu suất cao có thể thực hiện một số lệnh trong
mỗi chu kỳ
+ CPU được tối ưu hóa cao cho tốc độ sản xuất công nghệ mới
nhất
+ Mặt khác, một bộ vi xử lý có thể được sử dụng cho nhiều
thuật toán khác nhau chỉ bằng cách thay đổi chương trình mà
nó thực thi.
+ Việc triển khai ứng dụng của bạn nhanh hơn so với việc thiết
kế logic tùy chỉnh của riêng bạn
- Bộ vi xử lý linh hoạt nhờ khả năng lập trình của chúng:
+ Dễ dàng hơn để thiết kế các dòng sản phẩm
+ Dễ dàng hơn trong việc cung cấp các tính năng mới để theo
kịp với thị trường đang thay đổi nhanh chóng
+ Có thể sử dụng lại phần mềm cho các sản phẩm thế hệ tiếp
theo, do đó giảm thời gian và chi phí phát triển.
● Tại sao không sử dụng PC cho tất cả các máy tính nhúng?
- Khó đáp ứng các yêu cầu về hiệu suất thời gian thực
+ Hiệu suất thời gian thực thường đạt được tốt nhất bởi bộ xử
lý đa xử lý hoặc logic tùy chỉnh
- Khó đáp ứng các yêu cầu Công suất thấp và chi phí thấp:
+ PC được thiết kế để đáp ứng nhiều yêu cầu về tính toán.
+ Ngược lại, các hệ thống nhúng tùy chỉnh được thiết kế cho
một ứng dụng.
Liệu chúng ta có thể sử dụng Điện thoại thông minh làm nền tảng cho máy tính
nhúng không?
• Đặc trưng:
• Điện thoại thông minh rất tiết kiệm điện
• Điện thoại thông minh có thể thực hiện một lượng lớn tính toán trong
thời gian thực
• Kích thước nhỏ
Một số vấn đề quan trọng phải được tính đến trong thiết kế hệ thống nhúng:
- Chúng ta cần bao nhiêu phần cứng?
• lựa chọn phần cứng phải đáp ứng cả thời hạn hiệu suất và hạn chế về chi
phí sản xuất
- Làm thế nào để chúng ta hạn chế về thời gian?
• để tăng tốc phần cứng để chương trình chạy nhanh hơn
- Làm cách nào để giảm thiểu điện năng tiêu thụ?
• làm chậm hệ thống
- Làm thế nào để chúng tôi thiết kế để có thể nâng cấp?
• Thiết kế phải đủ linh hoạt cho một số thế hệ sản phẩm hoặc cho một số
phiên bản khác nhau của một sản phẩm trong cùng một thế hệ
- Làm thế nào nó thực sự làm việc?
• Độ tin cậy luôn quan trọng khi bán sản phẩm
● Các yếu tố làm cho việc thiết kế hệ thống nhúng trở nên khó khăn
hơn
- Thử nghiệm phức tạp:
• phải chạy một máy thực để tạo ra dữ liệu thích hợp - Khả năng quan sát
và kiểm soát hạn chế:
• không đi kèm với bàn phím và màn hình
• trong các ứng dụng thời gian thực, không dễ gì dừng hệ thống
- Môi trường phát triển hạn chế:
• các công cụ được sử dụng để phát triển phần mềm và phần cứng)
thường bị hạn chế hơn nhiều
Q1: Hệ thống máy tính nhúng là gì? Điều gì là khó khăn và độc đáo về việc
nhúng máy tính và máy tính đa năng?
Câu 2: Kể tên ba sản phẩm điện tử tiêu dùng có hệ thống nhúng. Kể tên ba sản
phẩm điện tử tiêu dùng không chứa hệ thống máy tính nhúng.
Basic Concepts
● Kiến trúc hệ thống nhúng
- DMA cung cấp khả năng truy cập bộ nhớ trực tiếp
- Timers được sử dụng bởi hệ điều hành, thiết bị.
- Nhiều bus kết nối CPU và bộ nhớ với các thiết bị.
+ tốc độ thấp: cung cấp một cách không tốn kém để kết nối các thiết bị
đơn giản hơn
+ tốc độ cao: cho phép các thiết bị nhanh chóng giao tiếp hiệu quả
- Nhiều bus phục vụ hai mục đích:
+ giảm tải truy cập tổng thể và tăng hiệu suất sử dụng bus
+ bus tốc độ thấp cung cấp giao diện đơn giản hơn và rẻ hơn so với bus
tốc độ cao
● Cơ chế giao tiếp
- Các thành phần của hệ thống máy tính giao tiếp thông qua mạng kết nối
- Cung cấp các phương tiện để truyền dữ liệu và trao đổi trạng thái và thông tin
điều khiển
- Mạng kết nối có thể là:
+ Kết nối trực tiếp
+ Shared bus
+ Mạng trên chip
● Một bus đơn giản
- Dây dẫn:
+ Một chiều hoặc hai chiều
+ Một đường dây có thể đại diện cho nhiều dây
- Bus
+ Bộ dây dẫn với một chức năng duy nhất: bus địa chỉ, bus dữ liệu
+ Hoặc, toàn bộ dây dẫn:
• Địa chỉ, dữ liệu và kiểm soát
• Giao thức được liên kết: các quy tắc cho kết nối
● Cổng
● Bus
- Tối thiểu, một bus là một tập hợp các dây nhưng nó cũng được xác định một
giao thức của CPU, bộ nhớ và các thiết bị giao tiếp.
- Các tín hiệu tạo nên bus cung cấp thông tin liên lạc cần thiết: bản thân dữ liệu,
địa chỉ, clock và một số tín hiệu điều khiển.
● Bus vi xử lý
Các thành phần chính trên một bus điển hình bao gồm:
- Clock cung cấp sự đồng bộ hóa.
- R / W’ là true khi đọc (R / W’ là false khi đọc).
- Address là một gói-bit của các dòng địa chỉ.
- Data là gói dữ liệu n-bit.
- Data ready báo hiệu khi dữ liệu n-bit đã sẵn sàng.
● Timing diagrams
- Biểu đồ thời gian cho thấy các tín hiệu trên bus thay đổi như thế nào theo thời
gian.
- Trạng thái bus:
- Ràng buộc về thời gian: lượng thời gian giữa các sự kiện hoặc chỉ thứ tự của
các sự kiện
- Phương pháp phổ biến nhất để mô tả một giao thức truyền thông
- Thời gian tiến về bên phải trên trục x
- Tín hiệu điều khiển (enable): thấp hoặc cao
+ Có thể hoạt động thấp (ví dụ: go’, / go, nGo hoặc go_L)
+ Sử dụng các điều khoản khẳng định (hoạt động) và phủ định
+ Khẳng định go’ có nghĩa là go = 0
- Data signal: không hợp lệ hoặc hợp lệ
- Giao thức có thể có các giao thức con
+ Được gọi là chu kỳ bus, ví dụ: đọc và ghi
+ Mỗi giao thức có thể là một số chu kỳ đồng hồ
- Ví dụ giao thức đọc (read)
+ rd ’/ wr đặt ở mức thấp
+ địa chỉ được đặt trên addr trong ít nhất thời gian tsetup trước khi enable
được xác nhận, kích hoạt bộ nhớ để đặt dữ liệu trên data wires theo thời
gian tread
● Các khái niệm giao thức cơ bản
- Giao thức bus xác định cách các thiết bị giao tiếp:
+ khi các thành phần bus có thể sử dụng một số tín hiệu nhất định và
những tín hiệu đó có ý nghĩa
- Các thiết bị trên bus đi qua các chuỗi trạng thái.
+ Các giao thức được chỉ định bởi các máy trạng thái, một máy trạng thái
cho mỗi tác nhân trong giao thức.
- Có thể chứa hành vi logic không đồng bộ.
DMA
● Direct memory access (DMA) thực hiện truyền dữ liệu mà không cần thực hiện
hướng dẫn.
- CPU thiết lập chuyển giao.
- Bộ điều khiển DMA thực hiện các thao tác đọc và ghi trực tiếp giữa các
thiết bị và bộ nhớ.
● Bộ điều khiển DMA là một đơn vị riêng biệt.
- Bộ điều khiển DMA có thể hoạt động như một bộ điều khiển bus
● Bus mastership
- Theo mặc định, CPU là bus master và bắt đầu chuyển tiếp.
- DMA phải trở thành bus master để thực hiện công việc của nó.
+ CPU không thể sử dụng bus trong khi DMA hoạt động.
- Giao thức cấp quyền làm chủ bus:
+ Hai tín hiệu bus bổ sung: Bus request và Bus grant.
+ Phương pháp điều khiển: bắt tay bốn chu kỳ
● Hoạt động của DMA
- CPU điều khiển hoạt động DMA thông qua các thanh ghi trong bộ điều khiển
DMA:
+ Một thanh ghi địa chỉ bắt đầu chỉ định nơi bắt đầu chuyển.
+ Một thanh ghi địa chỉ đích chỉ định nơi dữ liệu được chuyển đến.
+ Một thanh ghi độ dài chỉ định số lượng từ được chuyển.
+ Một thanh ghi trạng thái cho phép bộ điều khiển DMA được vận hành
bởi CPU.
- CPU bắt đầu truyền DMA bằng
+ thiết lập thanh ghi địa chỉ bắt đầu và thanh ghi độ dài và địa chỉ mục tiêu
một cách thích hợp.
+ Đặt bit “bắt đầu chuyển” trong thanh ghi trạng thái của DMA.
- Khi DMA là bus chính, nó sẽ tự động truyền.
+ Có thể chạy liên tục cho đến khi hoàn thành.
+ Có thể sử dụng mỗi chu kỳ bus thứ n.
● Slide 27-32 không hiểu không trình bày được
● Slide 33 trở đi: del hiểu j mà dịch luôn :)
● DMA hoạt động đồng thời
- DMA là bus master vì:
+ Luôn chạy cho đến khi hoàn thành.
+
Bài 2: Giới thiệu ngôn ngữ C
● Hai cách tiếp cận trong lập trình chip ARM
- Sử dụng các hàm do nhà cung cấp viết để truy cập các thiết bị ngoại
vi.
+ Các hàm thư viện thiết bị này có bản quyền và không thể sử dụng
với chip ARM của một nhà cung cấp khác.
+ Bạn không kiểm soát được các hàm và rất khó tùy chỉnh chúng
cho dự án của mình.
+ Dễ dàng và tiết kiệm thời gian để phát triển
- Tạo thư viện tùy chỉnh của riêng bạn để truy cập các đăng ký hàm
đặc biệt của thiết bị ngoại vi
+ Các hàm có thể được sửa đổi và sử dụng với nhà cung cấp khác.
+ Bạn có toàn quyền kiểm soát mỗi hàm
+ Khó và tốn rất nhiều thời gian
● Tại sao sử dụng ngôn ngữ C cho Hệ thống nhúng?
- C là một ngôn ngữ dành cho mục đích chung, liên kết chặt chẽ với
UNIX vì hệ điều hành này được viết bằng C.
- C là một ngôn ngữ cấp tương đối
+ Dễ dàng thao tác các ký tự, số và địa chỉ bằng cách sử dụng phạm
vi số học và các hoạt động logic thường được triển khai.
+ Cấu trúc luồng điều khiển đơn luồng.
- C tương đối nhỏ và có thể học nhanh.
- Một trình biên dịch C có thể đơn giản và nhỏ gọn (bởi vì các kiểu dữ
liệu và cấu trúc điều khiển do C cung cấp được hỗ trợ trực tiếp bởi hầu
hết các máy hiện có nên thư viện thời gian chạy cần thiết để thực hiện
các chương trình độc lập là rất nhỏ).
● Lịch sử phát triển:
- Được thiết kế bởi Dennis Richie (1944-2011) tại Bell Labs vào đầu
những năm 1970.
+ Một ngôn ngữ lập trình có mục đích chung
+ Các tính năng cấp thấp làm cho nó trở nên hấp dẫn đối với lập
trình hệ thống (UNIX ban đầu được viết bằng C).
- Được tiêu chuẩn hóa bởi Viện Tiêu chuẩn Quốc gia Hoa Kỳ (ANSI) vào
năm 1989 (tiêu chuẩn C89),
- Tiêu chuẩn hóa và sửa đổi bởi ANSI và Tổ chức Tiêu chuẩn hóa Quốc tế
(ISO) vào năm 1994 (C95), 1999 (C99).
- Hiện nay, C là ngôn ngữ lập trình phổ biến nhất ..
- Làm thế nào để bắt đầu?
+ Văn bản của Brian Kernighan và Dennis Ritchie là tài liệu tham
khảo cơ sở được chấp nhận nhưng không phù hợp với những
người mới lập trình.
I. Tổng quan về lập trình C
- Một chương trình C bao gồm một hoặc nhiều tệp nguồn, mỗi tệp chứa
một số phần của toàn bộ chương trình C - thường là một số chức năng
bên ngoài.
- Các khai báo chung thường được thu thập thành các tệp tiêu đề và được
đưa vào tệp nguồn bằng lệnh #include đặc biệt.
- Một hàm bên ngoài phải được đặt tên là main; hàm này là nơi chương
trình của bạn bắt đầu.
- Một trình biên dịch C xử lý từng tệp nguồn và chuyển nó thành các
hướng dẫn mà máy tính hiểu được (mã đối tượng). Đầu ra của trình biên
dịch thường được gọi là mã đối tượng hoặc các mô-đun đối tượng.
- Khi tất cả các tệp nguồn được biên dịch, các mô-đun đối tượng được
chuyển đến một chương trình được gọi là trình liên kết, chương trình
này phân giải các tham chiếu địa chỉ bên ngoài để tạo ra một tệp thực thi
(.exe).
● "Header file" của bộ vi điều khiển
- Keil MDK-ARM cung cấp một “Header file” dẫn xuất cụ thể cho mỗi vi
điều khiển, xác định địa chỉ bộ nhớ và các nhãn tượng trưng cho địa chỉ
thanh ghi chức năng của CPU và ngoại vi.
● The C Preprocessor
- #define là tiện ích mở rộng đơn giản và phổ biến nhất trong số các tiện
ích mở rộng này
1 định nghĩa về biểu mẫu:
#define YES 1
calls for a macro substitution, thay thế tên bằng một chuỗi ký tự.
- #include “filename”
+ bao gồm nội dung của các tệp khác trong quá trình biên dịch
+ #include “filename” được thay thế bằng nội dung của tệp “filename”
- Thường thì một hoặc hai dòng của biểu mẫu này xuất hiện ở đầu mỗi tệp
nguồn
● Macro substitution
- Cũng có thể xác định macro bằng các đối số, vì vậy văn bản thay thế
phụ thuộc vào cách gọi macro.
- Hàm PRINTF là một trong những hàm được cung cấp trong Thư viện
Chuẩn C fsl_debug_console.h
+ Không phải là một phần của ngôn ngữ lập trình C
- #include <fsl_debug_console.h> khai báo printf và các hàm UART
khác.
- Trình liên kết định vị chức năng và chèn địa chỉ của nó để chương trình
hoàn chỉnh có thể được thực thi.
III. Data types
● C data types
- Theo mặc định, các biến được coi là có dấu trừ khi từ khóa unsigned
được sử dụng với ngoại lệ là char.
- Luôn khớp với các đặc điểm của kiểu dữ liệu
- Loại biến cho biết cách dữ liệu được biểu diễn
+ Số bit xác định phạm vi giá trị số
+ signed/unsigned xác định toán tử số học / quan hệ nào sẽ được
trình biên dịch sử dụng
+ Dữ liệu không phải số phải là "unsigned"
- Tệp tiêu đề “stdint.h” xác định các tên kiểu thay thế cho các loại dữ liệu
tiêu chuẩn trong C
+ Loại bỏ sự mơ hồ về số lượng bit
+ Loại bỏ sự mơ hồ liên quan đến signed / unsigned
● Constant/literal values
- Decimal là định dạng số mặc định
+ int m, n; // số có dấu 16 bit
+ m = 453; n = -25;
- Hexadecimal: Giá trị đầu là 0x hoặc 0X
+ VD: m = 0xF312; n = -0x12E4;
- Octal: Giá trị đầu là 0
+ m = 0453; n = -023;
+ NOTE: Không sử dụng các số 0 ở đầu trên các giá trị "thập
phân". Chúng sẽ được hiểu là bát phân.
- Character: ký tự trong dấu ngoặc kép hoặc giá trị ASCII theo
sau dấu ‘’
+ m = ‘a’; //ASCII value 0x61
+ n = ‘\13’; //ASCII 13 là ký tự "trả về"
- String (array) of characters:
unsigned char k[7];
strcpy(k,“hello\n”); //k[0]=‘h’, k[1]=‘e’, k[2]=‘l’, k[3]=‘l’,
k[4]=‘o’,
//k[5]=13 or ‘\n’ (ASCII new line character),
//k[6]=0 or ‘\0’ (null character –end of string)
● C là một ngôn ngữ lập trình được định kiểu mạnh
- Ngôn ngữ lập trình được định kiểu mạnh là ngôn ngữ trong đó mỗi kiểu
dữ liệu (chẳng hạn như số nguyên, ký tự, thập lục phân, thập phân đóng
gói, v.v.) được xác định trước như một phần của ngôn ngữ lập trình.
- Tất cả các hằng số hoặc biến được định nghĩa cho một chương trình nhất
định phải được mô tả bằng một trong các kiểu dữ liệu.
- Một số thao tác nhất định có thể chỉ được phép với một số kiểu dữ liệu
nhất định.
- Trình biên dịch thực thi việc tuân thủ việc nhập và sử dụng dữ liệu.
- Một ưu điểm của cách đánh dữ liệu mạnh là nó áp đặt một bộ quy tắc
chặt chẽ lên người lập trình và do đó đảm bảo tính nhất quán nhất định
của kết quả.
- Một nhược điểm là nó ngăn lập trình viên phát minh ra một kiểu dữ liệu
không được các nhà phát triển ngôn ngữ lập trình dự đoán và nó hạn chế
mức độ "sáng tạo" của người dùng trong việc sử dụng một kiểu dữ liệu
nhất định.
● Chuyển đổi kiểu dữ liệu (TYPE CONVERSIONS)
- Khi các toán hạng của các kiểu khác nhau xuất hiện trong biểu thức,
chúng được chuyển thành một kiểu chung theo một số quy tắc.
- Thông thường, điều này xảy ra tự động (mặc dù đôi khi trình biên dịch
sẽ đưa ra thông báo cảnh báo - tùy thuộc vào mức độ cảnh báo).
● Ép kiểu
- Chuyển đổi kiểu có thể bị ép buộc (ép buộc) trong bất kỳ biểu thức nào
có cấu trúc được gọi là ép kiểu.
IV. Variables
● Biến
- Một biến là một vị trí lưu trữ có thể địa chỉ được chương trình sử dụng
+ Mỗi biến phải được khai báo để chỉ ra kích thước và loại thông tin
được lưu trữ, cộng với tên được sử dụng để tham chiếu thông tin
int x, y, z; // khai báo 3 biến kiểu “int”
char a, b; // khai báo 2 biến kiểu “char”
+ Không gian cho các biến có thể được cấp phát trong thanh ghi,
RAM hoặc ROM / Flash (đối với hằng số)
+ Các biến có thể động hoặc tĩnh
● Toán tử gán
- Nội dung của một vị trí bộ nhớ được thay đổi bởi một câu lệnh gán.
- Hằng và biến có thể được kết hợp với các toán tử số học, logic và quan
hệ để tạo thành các câu lệnh ghép.
● Các biến bên ngoài
- Được xác định bên ngoài mô-đun nguồn hiện tại, từ khóa extern
- Được tham chiếu bởi bất kỳ chức năng nào từ bất kỳ tệp nào trong hệ
thống phần mềm
- Chỉ các khai báo extern mới có thể được chỉ định bên ngoài
extern short ExtGlobal; /* an external global variable*/
void main(void){
ExtGlobal = 1000;
}
● Các biến tự động
- Khai báo trong một hàm / thủ tục
- Biến chỉ hiển thị (có phạm vi) trong hàm đó
+ Không gian cho biến được cấp phát trên ngăn xếp hệ thống khi
thủ tục được nhập. Bỏ cấp phát, được sử dụng lại, khi thủ tục
được thoát
+ Nếu chỉ có 1 hoặc 2 biến, trình biên dịch có thể cấp phát chúng
vào các thanh ghi trong thủ tục đó, thay vì cấp phát bộ nhớ.
+ Giá trị không được giữ lại giữa các lần gọi thủ tục
● Các biến tĩnh
- Biến tĩnh là lớp lưu trữ thứ ba, bên cạnh các biến extern và biến tự
động.
- Khai báo bên trong hoặc bên ngoài một hàm:
+ Các biến tĩnh bên trong là cục bộ của hàm mà chúng được khai
báo nhưng không giống như các biến tự động, chúng vẫn tồn tại
thay vì đến và đi mỗi khi hàm được gọi. Điều này có nghĩa là các
biến tĩnh bên trong cung cấp một kho lưu trữ vĩnh viễn, riêng tư
trong một hàm.
• chèn từ khóa tĩnh trước định nghĩa biến.
static unsigned char bob;
static int pressure[10];
- Các biến tĩnh bên ngoài hiển thị trong phần còn lại của tệp nguồn mà
chúng được khai báo, nhưng không hiển thị trong bất kỳ tệp nào khác.
• Sử dụng các khai báo "normal"
int count;
● Khai báo biến (Register variable)
Lớp lưu trữ thứ tư và cuối cùng là thanh ghi. Một tờ khai đăng ký thông
báo cho trình biên dịch rằng biến sẽ được sử dụng nhiều. Nếu có thể, các
biến thanh ghi được đặt trong các thanh ghi của bộ xử lý vì chúng cung
cấp quyền truy cập nhanh nhất.
● Biến không đổi và biến động
- const: việc áp dụng từ khóa const trong một khai báo chỉ ra cho trình
biên dịch biết rằng đối tượng sẽ được coi như một hằng số và không thể
bị thay đổi.
- volatile: việc áp dụng từ khóa “volatile” trong một khai báo chỉ ra cho
trình biên dịch biết rằng nội dung của đối tượng có thể bị thay đổi không
thể đoán trước và không nên được tối ưu hóa. Ví dụ, nó có thể là một
biến sẽ được thay đổi bởi một quy trình dịch vụ ngắt, hoặc một thanh
ghi I / O sẽ được thay đổi bởi một thiết bị I / O.
● Con trỏ và địa chỉ
- Con trỏ có lẽ là khái niệm khó nhất trong C.
- Con trỏ là một biến chứa địa chỉ của một biến khác.
- Con trỏ rất phổ biến trong C vì chúng thường dẫn đến mã nhỏ gọn và
hiệu quả hơn.
- Vì một con trỏ chứa địa chỉ của một đối tượng, nên có thể truy cập gián
tiếp vào đối tượng thông qua con trỏ.
- Xem xét đoạn mã:
● Con trỏ
- Khi các biến được truyền theo giá trị, bản sao của các đối số đầu
vào được thực hiện khi hàm được gọi. Đây là những bản sao cục
bộ; chúng bị xóa khi chức năng kết thúc.
- Khi các biến được chuyển qua tham chiếu, các đối số đầu vào là địa chỉ
bộ nhớ (lấy bằng cách sử dụng &). Chúng được sao chép cục bộ (như
trước đây), nhưng chúng được sử dụng cục bộ để thay đổi giá trị của các
biến mà chúng "trỏ" vào. Khi chúng ta khai báo một con trỏ, chúng ta
phải nói loại biến mà nó trỏ đến (sử dụng *).
● Mảng
- Mảng là một tập hợp dữ liệu, được lưu trữ trong các vị trí bộ nhớ liên
tiếp, bắt đầu từ một địa chỉ được đặt tên
- Khai báo tên mảng và số phần tử dữ liệu, N
int n [5]; // khai báo mảng 5 giá trị "int"
- Tên mảng thực chất là một bút danh cho địa chỉ của phần tử đầu tiên.
• tức là tên là một con trỏ đến phần tử đầu tiên.
- Các phần tử được "lập chỉ mục", với các chỉ số [0 .. N-1]
n [3] = 5; // đặt giá trị của 4 phần tử array
• Chúng ta cũng có thể truy cập các phần tử thông qua một con trỏ, ví
dụ: p = x+9;
● Struct
- Cấu trúc là một tập hợp của một hoặc nhiều biến, có thể là các kiểu khác
nhau, được nhóm lại với nhau dưới một tên duy nhất để thuận tiện cho
việc xử lý.
- Các cấu trúc giúp tổ chức dữ liệu vì chúng cho phép một nhóm các biến
liên quan được coi như một đơn vị thay vì các thực thể riêng biệt.
- Cấu trúc có thể được xác định bằng cách sử dụng câu lệnh C “struct”.
- Một tên tùy chọn được gọi là thẻ cấu trúc có thể theo sau từ struct (như
với struct clock ở đây). Thẻ có thể được sử dụng để tham chiếu đến cấu
trúc.
● Biến struct
- Dấu ngoặc nhọn kết thúc cấu trúc có thể được theo sau bởi một danh
sách các biến, giống như đối với bất kỳ kiểu cơ bản nào. Đó là,
struct {. . . } x, y, z; về mặt cú pháp tương tự như int x, y, z;
- Một khai báo cấu trúc không được kèm theo bởi danh sách các biến
phân bổ không có bộ nhớ; nó chỉ đơn giản mô tả một khuôn mẫu cho
cấu trúc. Tuy nhiên, nếu cấu trúc được gắn thẻ, tên này có thể được sử
dụng trong khai báo biến.
struct clock timer;
- Các thành viên của một cấu trúc có thể được gọi bằng cách sử dụng toán
tử “.”, như trong:
timer.sec = 60;
● typedef
- Từ khóa typedef cho phép tạo các tên kiểu dữ liệu mới. Ví dụ:
typedef struct clock time_t; /* time_t là từ đồng nghĩa với struct clock */
time_t timer; / * khai báo var hẹn giờ tốt hơn * /
- typedef thường được sử dụng để xác định tên kiểu viết tắt, ví dụ, Keil
thường bao gồm tiêu đề <stdint.h> trong chương trình của họ, đây là
đoạn code:
/* exact-width signed integer types */
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long long int int64_t;
- Để làm cho kiểu dữ liệu nổi bật trong một chương trình, quy ước rằng
các tên được kết thúc bằng _t đôi khi được chấp nhận (t == type)
● Truy cập các phần tử cấu trúc
- Có thể truy cập các trường riêng lẻ trong một cấu trúc bằng cách sử
dụng ký hiệu dấu chấm,
ví dụ: clock.hours = 1;
- Cũng có thể truy cập các trường trong một cấu trúc thông qua một con
trỏ,
ví dụ. pclock → hours = 1; / * pclock là một con trỏ đến đồng hồ * /
● Structures and Peripherals I
- Bộ xử lý nhúng thường chứa I / O song song, USART, Bộ hẹn giờ, v.v.
+ Mỗi thiết bị ngoại vi này có một tập hợp các thanh ghi liên quan
cho phép nó được cấu hình và sử dụng (ví dụ: cổng GPIO E,
trong Labs 1 và 2).
- Thanh ghi cho mỗi thiết bị ngoại vi được định nghĩa là một cấu trúc
+ Khi trình biên dịch thấy một khai báo struct, nó sẽ dự trữ không
gian bộ nhớ. Bằng cách sắp xếp cho không gian này ánh xạ vào
các thanh ghi ngoại vi, chúng ta có thể tham chiếu gọn gàng từng
thanh ghi.
- Chúng ta sử dụng câu lệnh này để xuất ra một số đếm (i) cho các đèn
LED trong Lab 2
GPIOE → ODR = i << 8;
trong đó Output Data Register (ODR) là một trường được xác định
trong cấu trúc GPIOE là một con trỏ đến cấu trúc
- Các chân A-E của cổng GPIO có thể được cấu hình ở nhiều chế độ khác
nhau bằng cách ghi vào thanh ghi điều khiển cổng.
- Bản thân các thanh ghi là bộ nhớ được ánh xạ vào không gian địa chỉ
trung tâm ARM.
- Quyền truy cập vào ODR thực sự phân giải thành một địa chỉ bộ nhớ.
V. Operations
● Arithmetic operations (Các phép tính toán)
●
● Second C Program: Add Two integers (Thêm hai số nguyên )
- Toán tử & cung cấp địa chỉ của một đối tượng
+ Sử dụng “& a” để tìm và chuyển tới địa chỉ của biến a
- Toán tử% xác định một đặc tả định dạng (% i đề cập đến số
nguyên)
● Setting and Clearing (masking) bits (Các bit cài đặt và xóa (che))
-
- Chương trình sau chỉ chuyển đổi liên tục bit 4 của var1 mà không làm
ảnh hưởng đến các bit còn lại?
- Chương trình sau chỉ chuyển đổi liên tục bit 4 của var1 mà không làm
ảnh hưởng đến các bit còn lại?
- Các thiết bị ngoại vi (ví dụ: cổng GPIO, ADC, v.v.) thường được cấu
hình và điều khiển bởi một tập hợp các thanh ghi. Các bit riêng lẻ của
thanh ghi có thể cần được đọc (hoặc ghi).
- Nếu một bit thanh ghi (hoặc nhóm) được ghi (thành 1 hoặc 0) thì thường
xảy ra trường hợp các bit khác được giữ nguyên.
- Khi đọc một thanh ghi, chúng ta có thể xác định các bit riêng lẻ bằng
cách sử dụng MASK được gọi là MASK theo bit khôn ngoan VÀ phù
hợp với nội dung thanh ghi. (Ví dụ: Dòng 32 kiểm tra bit 7 của thanh
ghi GPIOB).
● Testing bit with bitwise operators in C (Kiểm tra bit với các toán tử
bitwise trong C)
-Viết chương trình C để giám sát bit 5 của var1. Nếu nó là CAO, hãy
thay đổi giá trị của var2 thành 0x55; nếu không, hãy thay đổi giá trị của
var2 thành 0xAA.
● Bitwise shift operator in C (Toán tử dịch chuyển bit trong C )
- Dòng 24 đặt bit 6 của thanh ghi APB2ENR Đặt lại và Điều khiển Đồng
hồ (giữ nguyên các bit khác).
-
Example:
-
unsigned char a,b;
int j,k; if (a < b)
- unsigned if (j > k)
- signed
● Boolean operators (Toán tử boolean )
- Toán tử Boolean && (AND) và || (OR) tạo ra
- Kết quả TRUE / FALSE khi thử nghiệm nhiều
- Điều kiện TRUE / FALSE
- if ((n> 1) && (n <5)) // kiểm tra n từ 1 đến 5
- if ((c = ‘q’) || (c = ‘Q’)) // kiểm tra c = chữ thường hoặc chữ hoa
Q
- • Lưu ý sự khác biệt giữa các toán tử Boolean &&, || và toán tử
logic bit &, |
- if (k && m) // kiểm tra nếu k và m đều ĐÚNG (các giá trị khác
0)
- if (k & m) // tính theo từng bit AND giữa m và n, // kiểm tra xem
kết quả có khác 0 hay không (TRUE)
● Common error (Lỗi chung )
- Lưu ý rằng == là một toán tử quan hệ, trong khi = là một
- toán tử gán.
- if (m == n) // kiểm tra tính bình đẳng của các giá trị của biến m và n
- if (m = n) // gán giá trị của n cho biến m, và sau đó
// kiểm tra xem giá trị đó có phải là TRUE (khác không)
- Dạng thứ hai là một lỗi phổ biến (bỏ qua dấu bằng thứ hai), và
thường tạo ra kết quả không mong muốn, cụ thể là điều kiện TRUE
nếu n là 0 và FALSE nếu n khác 0.
● If-Else
● Else - if
● switch
● while
● do-while
● For
- Chương trình trên in ra gì?
● Break
-
- getline trả về chiều dài của dòng
- Bên trong vòng lặp while bắt đầu từ ký tự cuối cùng của dòng(gọi lại --n(trước)
giảm n trước khi sử dụng biến), và quét lại phía sau tìm kiếm ký tự đầu tiên mà
không phải khoảng trắng, tab hoặc newline. Vòng lặp kết thúc khi một trong
những điều kiện kia xảy ra, hoặc khi n âm(ví dụ khi ký tự kết thúc dòng được
tìm thấy).
VII. Functions
1. Phạm vi
- Các biến trong main là private hoặc local với main; bởi vì chúng được khai báo bên
trong hàm main không có chức năng nào khác có thể có quyền truy cập trực tiếp
vào chúng:
- Điều này cũng đúng với các biến trong các hàm khác; ví dụ các biến trong getline
hoàn toàn không liên quan đến những thứ trong main.
- Mỗi biến cục bộ xuất hiện khi hàm được gọi, và biến mất khi kết thúc hàm; vì lý
do này, các biến được gọi là biến tự động.
- Để thay thế cho các biến tự động, có thể xác định các biến toàn cục có thể được
truy cập bởi bất kỳ chương trình con nào.
- Vì các biến toàn cục vẫn tồn tại vĩnh viễn nên chúng có thể được sử dụng để chia
sẻ dữ liệu giữa các hàm.
2. Chia sẻ dữ liệu và biến toàn cục
● Functions
- Chương trình con chia chương trình thành các tác vụ nhỏ hơn:
+ Giúp quản lý chương trình phức tạp
+ Các nhiệm vụ nhỏ được thiết kế dễ dàng gỡ lỗi
+ Chương trình con có thể tái sử dụng thay vì việc khởi tạo
+ Có thể sử dụng các thư viện của chương trình con phát triển bởi
bên thứ 3 thay cho việc tự tạo
- Một chương trình con được gọi bởi nhiều chương trình khác để thực hiện một
tác vụ :
+ Chương trình con có thể trả về kết quả qua lời gọi
+ Một hoặc nhiều tham số có thể bỏ qua trong chương trình con/hàm
- Một hàm có kết cấu:
-
- Một hàm tối thiểu là :
void dummy(){}
- Một chương trình chỉ có duy nhất một bộ các chương trình con xác định các
chức năng riêng
- Giao tiếp giữa chương trình con đảm bảo:
+ Tham số và giá trị trả về
+ biến bên ngoài
- Chương trình con xác định có thể thể hiện theo nhiều thứ tự trong file nguồn
hoặc được tách ra bởi nhiều file, miễn là không có chức năng riêng lẻ nào được
phân chia.
3. Định nghĩa chương trình con
- Chương trình con rất quan trọng trong thiết kế(trừu tượng) công cụ:
+ Chúng cho phép chúng ta cấu trúc một tác vụ lớn thành các phần
nhỏ(dễ dàng quản lý), chi tiết có thể ẩn qua những lời gọi hàm.
4. Tham số của chương trình con
- Tham số của chương trình con được truyền giá trị:
+ Chương trình con nhận một tham số riêng tạm thời, không phải địa chỉ của
nó điều này có nghĩa là hàm đó không thể ảnh hưởng đến đối số ban đầu
của lệnh gọi hàm.
+ Trong hàm, mỗi đối số có hiệu lực là một biến cục bộ.
- Khi tên mảng xuất hiện dưới dạng đối số của một hàm,
+ vị trí của mảng được truyền; các phần tử không được sao chép.
+ mảng được truyền bằng tham chiếu.
- Bất kỳ biến nào cũng có thể được chuyển qua tham chiếu bằng cách sử dụng
toán tử & để
+ lấy địa chỉ của biến.
5. Tham chiếu với tham trị
● INTERRUPT
- Cơ chế Interrupt sẽ chỉ ra thiết bị I/O nào đang gửi tín hiệu về, chờ đến
khi CPU thực hiện xong lệnh sẽ thực thi tín hiệu I/O gửi về.
- Giải pháp phần cứng, nhận tín hiệu I/O qua các chân.
- Giải quyết được vấn đề năng lượng cho CPU
- Đánh giá được mức ưu tiên.
- Lưu nội dung của thanh ghi bên trong của CPU và thông tin trạng thái
trong Thiết bị điều khiển
6. Cơ chế ngắt:
● Chương trình xử lý ngắt:
- Chương trình được gọi và thực hiện bằng phần cứng, có bug
không theo quy luật.
- Nên viết chương trình xử lý ngắt càng ngắn càng tốt, thực hiện
trong khoảng thời gian ngắn.
● Cơ chế ngắt cố định ISR:
- Địa chỉ ngắt cố định, đã được tích hợp sẵn trong bộ vi xử lý,
không thể thay đổi.
- ISR được lưu trữ tại địa chỉ hoặc chuyển đến ISR thực được lưu
trữ nếu không có đủ byte. cơ chế xem slide
● Cơ chế vector ngắt ISR:
- Địa chỉ ngắt cho thiết bị ngoại vi cung cấp.
- Phổ biến khi bộ vi xử lý có nhiều thiết bị ngoại vi được kết nối
bởi một bus hệ thống.
- Sự khác nhau giữa Exceptions và Interrupts:
+ EX: xảy ra bên trong hệ thống
+ In: xảy ra bên ngoài hệ thống
7. Priorities and vectors
- Hai cơ chế cho phép thực hiện ngắt linh hoạt:
+ Priorities: xác định Interrupt nào lấy CPU đầu tiên.
+ Interrupt vector Table: cho phép các thiết bị ngắt khác nhau được
xử lý bởi trình xử lý khác nhau.
- Vectors number (hoặc Số ngắt) xác định mã nào được ưu
tiên cho từng loại ngắt.
- Handler address trỏ đến điểm vào ngắt trong bộ nhớ.
- Các cơ chế là trực giao: hầu hết các CPU đều cung cấp cả hai.
- Các ngắt được ưu tiên cho phép CPU bỏ qua các yêu cầu ngắt ít quan trọng hơn
trong khi nó xử lý các yêu cầu quan trọng hơn.
- cache hit: vị trí được yêu cầu nằm trong bộ nhớ cache.
- Cache miss: vị trí cần thiết không có trong bộ nhớ cache.
- Working set: tập hợp các vị trí được chương trình sử dụng trong
một khoảng thời gian.
- Compulsory (cold) miss: xảy ra lần đầu tiên một vị trí được sử
dụng.
- Capacity miss: bộ làm việc quá lớn.
- Conflict miss: nhiều vị trí trong tập hợp làm việc ánh xạ vào cùng
một dòng bộ nhớ cache.
- Driven by data locality (tính cục bộ của dữ liệu):
- theo thời gian: chương trình sử dụng lại cùng một dữ liệu mà
nó đã sử dụng gần đây
- không gian: chương trình sử dụng dữ liệu gần với các vị trí
được truy cập gần đây
- Nhiều vị trí bộ nhớ chính được ánh xạ vào một mục nhập bộ nhớ
cache.
- Có thể có bộ nhớ đệm cho:
- Câu lệnh;
- dữ liệu;
- dữ liệu + câu lệnh (hợp nhất).
- Thời gian truy cập bộ nhớ là sự thay đổi.
- cache hit là dữ liệu nằm trong bộ nhớ cache
- Ánh xạ trực tiếp: mỗi vị trí bộ nhớ ánh xạ vào chính xác một mục nhập
bộ nhớ cache.
- N-way set-Associative: mỗi vị trí bộ nhớ có thể đi vào một trong n bộ.
- Liên kết hoàn toàn: bất kỳ vị trí bộ nhớ nào cũng có thể được lưu trữ tại
bất kỳ mục nhập bộ nhớ cache nào trong bộ nhớ đệm (hầu như không bao
giờ được triển khai).
4. Write Operations:
- Write-through: mỗi lần ghi đều thay đổi cả bộ đệm và vị trí bộ nhớ
chính tương ứng.
- Write-back: chỉ ghi vào bộ nhớ chính khi vị trí được xóa khỏi bộ
nhớ cache.
- Replacement policy: chiến lược để chọn mục nhập bộ nhớ cache
nào cần loại bỏ để nhường chỗ cho vị trí bộ nhớ mới.
- Two popular strategies:
- Ngẫu nhiên: yêu cầu ít phần cứng hơn để thực hiện
- Ít được sử dụng gần đây (LRU): yêu cầu tương đối nhỏ
lượng phần cứng vào bộ nhớ đệm để theo dõi thời gian kể từ
lần truy cập cuối cùng cho mỗi khối.
5. Memory Management Units (here)
- Đơn vị quản lý bộ nhớ (MMU) bù đắp cho không gian địa chỉ hạn
chế trong tập lệnh của chúng
- MMU dịch các địa chỉ: - Địa chỉ ảo / logic tham chiếu đến không
gian địa chỉ trừu tượng của chương trình
- Địa chỉ vật lý tương ứng với vị trí RAM thực tế
- Dịch địa chỉ: quá trình xác định địa chỉ vật lý từ địa chỉ ảo;
- Lỗi trang: khi truy cập địa chỉ ảo không có trong bộ nhớ vật lý