Điều gì xảy ra nếu có lỗi thời gian chạy trong một chương trình? Sẽ thực hiện chương trình chỉ dừng lại? Có cách nào để tôi nhận được Arduino để cho tôi biết lỗi là gì không?
Điều gì xảy ra nếu có lỗi thời gian chạy trong một chương trình? Sẽ thực hiện chương trình chỉ dừng lại? Có cách nào để tôi nhận được Arduino để cho tôi biết lỗi là gì không?
Câu trả lời:
Đầu tiên, chúng ta hãy xem một vài ví dụ về những gì có thể đi sai.
void setup() {
int status;
pinMode(13, OUTPUT);
digitalWrite(13, status);
}
Như Edgar Bonet đã chỉ ra trong các bình luận, các biến cục bộ như status
trong đoạn mã trên không được trình biên dịch C ++ khởi tạo ngầm. Vì vậy, kết quả của mã ở trên là không xác định. Để tránh điều đó, hãy đảm bảo bạn luôn gán giá trị cho các biến cục bộ của mình.
Mọi thứ có một chút khác biệt với các biến toàn cục và tĩnh:
Các biến toàn cục và tĩnh được đảm bảo khởi tạo thành 0 theo tiêu chuẩn C.
Điều đó có nghĩa là bạn không nên lo lắng về việc khởi tạo chúng thành 0 trong mã của mình. Trong thực tế, bạn thực sự nên tránh nó, vì việc khởi tạo có thể lãng phí bộ nhớ. Chỉ khởi tạo chúng thành các giá trị khác 0.
int array[10];
int v = array[100];
array[-100] = 10;
Vấn đề đầu tiên ở đây là bạn không biết cái gì sẽ được gán cho v, nhưng tệ hơn là bạn không biết bạn đã làm gì với việc gán cho vị trí -100 của array
.
void doSomething( void ) {
for (int i = 0; i < 1000; i++);
}
void setup ()
{
void (*funcPtr)( void );
funcPtr = &doSomething;
funcPtr(); // calls doSomething();
funcPtr = NULL;
funcPtr(); // undefined behavior
}
Cuộc gọi đầu tiên funcPtr()
thực sự sẽ là một cuộc gọi đến doSomething()
. Các cuộc gọi như cuộc gọi thứ hai có thể dẫn đến hành vi không xác định.
Chà, chẳng hạn, bạn có thể hết RAM. Còn gì nữa không Trong mọi trường hợp, tôi nghĩ rằng chương trình của bạn sẽ tiếp tục chạy, có thể không phải là cách bạn dự định.
Trong các hệ thống máy tính, các vấn đề như thế này thường được xử lý ở nhiều cấp độ khác nhau:
Arduinos chỉ có sự bảo vệ hạn chế của trình biên dịch, và có lẽ không có gì khác. Tin tốt là chúng không đa tác vụ, vì vậy chương trình duy nhất bị ảnh hưởng là của bạn. Trong mọi trường hợp, bất kỳ lỗi nào trong số đó sẽ dẫn đến hành vi thất thường.
Các giả định là tất cả các vấn đề tôi đã nêu ở trên là các vấn đề thời gian chạy.
Điều gì xảy ra nếu có lỗi thời gian chạy trong một chương trình?
Chương trình sẽ tiếp tục và những gì xảy ra sẽ phụ thuộc vào tác dụng phụ của lỗi thời gian chạy. Một cuộc gọi đến con trỏ hàm null có thể sẽ làm cho chương trình nhảy đến một vị trí không xác định.
Sẽ thực hiện chương trình chỉ dừng lại?
Không, nó sẽ tiếp tục như thể không có gì bất thường xảy ra, có lẽ là làm những gì bạn không có ý định làm. Nó có thể thiết lập lại hoặc hành động thất thường. Nó có thể biến một số đầu vào thành đầu ra và đốt một hoặc hai cảm biến (nhưng điều đó rất khó xảy ra ).
Có một số cách tôi nhận được Arduino để cho tôi biết lỗi là gì?
Tôi không nghĩ vậy. Như tôi đã nói trước đó, các cơ chế bảo vệ không có ở đó. Không có hỗ trợ thời gian chạy từ ngôn ngữ, không có hệ điều hành, không kiểm tra phần cứng để truy cập bộ nhớ ngoài giới hạn (bộ tải khởi động không được tính là một trong hai). Bạn chỉ cần cẩn thận với chương trình của bạn và có thể thiết lập mạng lưới an toàn của riêng bạn.
Lý do thiếu bảo vệ có lẽ là do bộ điều khiển Arduino quá rẻ, bộ nhớ quá ít và không nên chạy bất cứ thứ gì quá quan trọng (vâng, dường như có một sự từ chối của AVR ở đâu đó để bạn không sử dụng MCU thường được sử dụng bởi Arduino trong các hệ thống hỗ trợ cuộc sống).
Không có ngoại lệ thời gian chạy. Chỉ có hành vi không xác định.
Thực sự, không có ngoại lệ nào cả . Nếu bạn cố gắng thực hiện một thao tác không hợp lệ, kết quả sẽ không xác định.
Không có kiểm tra thời gian chạy nào cả, ngoại trừ những gì bạn thực hiện. Chương trình của bạn đang chạy trên phần cứng kim loại trần. Đó là máy tính để bàn tương đương với việc chạy trong vòng 0 mọi lúc, vì ATmega không có chuông .
Có một cơ chế có thể đưa MCU từ trạng thái thất thường và đó là bộ đếm thời gian theo dõi . Nếu bạn đang triển khai một số mã sẽ liên tục chạy trong một vòng lặp, mã đó sẽ không chạy bất kỳ lúc nào lâu hơn một số thời gian cố định, bạn có thể đặt thời gian này là thời gian theo dõi và bật bộ hẹn giờ.
Sau đó, bạn phải liên tục thiết lập lại bộ đếm thời gian trong vòng lặp. Nếu mã của bạn đóng băng tại một số vòng lặp điều kiện sẽ không bao giờ kết thúc, thì cơ quan giám sát sẽ đếm về 0 và cuối cùng đặt lại MCU.
Bằng cách này, bạn đang mất dữ liệu, nhưng nếu bạn chạy AVR WDT ở chế độ ngắt, bạn có thể lưu trữ một số dữ liệu trước khi đặt lại MCU.
Vì vậy, bộ đếm thời gian theo dõi có thể bảo vệ mã của bạn khỏi các vòng lặp vô tận không thường xuyên.
Bạn sẽ cần một trình gỡ lỗi phần cứng cho một cái gì đó như thế này. Nhưng thông thường, bạn sẽ thấy chương trình không hoạt động như bạn mong đợi và sẽ phải xem phần mã đó để xác định vấn đề.
Một cách phổ biến / nhanh chóng / dễ dàng để làm điều này là thêm các câu lệnh in để in ra các giá trị của các biến hoặc bất cứ thứ gì để bạn biết chương trình đạt đến điểm đó trong mã mà không gặp vấn đề gì. Điều này sẽ giúp bạn cách ly vấn đề hơn nữa.
Tôi tin rằng VisualMicro có một số chức năng sửa lỗi được tích hợp.
Tôi cho rằng CPU AVR không có bất kỳ công cụ phát hiện hoặc khôi phục lỗi nào. Nó có thể chỉ dừng lại, hoặc tiếp tục bỏ qua lỗi và hậu quả. Giống như sachleen đã nói, bạn nên thêm một số câu lệnh gỡ lỗi trong chương trình của mình để in ra dữ liệu ở giữa một thao tác, để kiểm tra xem nó có hoạt động không. Nếu bạn sử dụng một biểu tượng và đặt điểm dừng, bạn có thể dễ dàng tìm thấy một vấn đề.
Arduino sẽ khởi động lại (tức là nó sẽ khởi chạy lại setup()
và loop()
).