Điều gì xảy ra khi tôi gọi exit () từ chương trình của tôi?


17

Trong một trong hai setuphoặc loop, nếu tôi thêm một exit(0)cuộc gọi, điều khiển sẽ được chuyển đến đâu? Trạng thái tiếp theo của vi điều khiển sẽ là gì? Nó sẽ dừng thực thi và mất điện?

Tôi đang sử dụng bản sửa đổi 2 Arduino Uno.


Tôi nghĩ rằng nó chỉ dừng lại. Nó sẽ không tắt đồng hồ, hoặc tắt nguồn.
TheDoctor

Phần còn lại của bộ nhớ nên được lấp đầy bằng NOPcác câu lệnh lắp ráp, chỉ tạm dừng trong một vài chu kỳ đồng hồ
TheDoctor

Câu trả lời:


12

Dự đoán ban đầu của tôi là sai. Tôi đã nghĩ rằng nó chỉ đơn giản là quay trở lại từ vòng lặp và thư viện lõi sẽ chỉ gọi lại loop (). Tuy nhiên, tôi thấy đoạn mã sau đã được tạo. Nhận thấy rằng __stop_program là một vòng lặp cứng ...

Một trích xuất danh sách của Blink.ino, với lối ra (0) được thêm vào:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
  exit(0);
}

Việc tháo gỡ ở trên:

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
 100:   80 91 00 01     lds r24, 0x0100
 104:   61 e0           ldi r22, 0x01   ; 1
 106:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 10a:   68 ee           ldi r22, 0xE8   ; 232
 10c:   73 e0           ldi r23, 0x03   ; 3
 10e:   80 e0           ldi r24, 0x00   ; 0
 110:   90 e0           ldi r25, 0x00   ; 0
 112:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
 116:   80 91 00 01     lds r24, 0x0100
 11a:   60 e0           ldi r22, 0x00   ; 0
 11c:   0e 94 ca 01     call    0x394   ; 0x394 <digitalWrite>
  delay(1000);               // wait for a second
 120:   68 ee           ldi r22, 0xE8   ; 232
 122:   73 e0           ldi r23, 0x03   ; 3
 124:   80 e0           ldi r24, 0x00   ; 0
 126:   90 e0           ldi r25, 0x00   ; 0
 128:   0e 94 f7 00     call    0x1ee   ; 0x1ee <delay>
  exit(0);
 12c:   80 e0           ldi r24, 0x00   ; 0
 12e:   90 e0           ldi r25, 0x00   ; 0
 130:   0e 94 1e 02     call    0x43c   ; 0x43c <_exit>

...

0000043c <_exit>:
 43c:   f8 94           cli

0000043e <__stop_program>:
 43e:   ff cf           rjmp    .-2         ; 0x43e <__stop_program>

Lưu ý rằng nếu _exit không được gọi là cli, các ngắt sẽ có thể thực hiện công cụ. Nhưng đó không phải là trường hợp.


avr-objdump -S {compiled *.elf file}tạo ra một tệp bao gồm mã C dẫn đến từng phần của mã lắp ráp. Nó dễ dàng hơn nhiều để làm theo.
Sói Connor

Tôi đã thử nó và nó không phát ra mã C nội tuyến cho hàm loop. Cái quái gì thế?
Sói Connor

Whoa, vô cùng lạ. Tôi đã biên dịch dự án với Stino thay vì trình soạn thảo arduino, dịch ngược *.elftừ đó và sau đó tôi nhận được các biểu tượng gỡ lỗi thích hợp. Tôi nghĩ rằng Arduino soạn thảo văn bản / nút vĩ mô (tôi từ chối để gọi nó là một IDE vì nó không) điều được tước các thông tin gỡ lỗi từ chỉ các tập tin ++ C chính biên soạn, vì một lý do kỳ lạ và ngớ ngẩn.
Sói Connor

một lời giải thích, và nó là để làm với cách các bản sao IDE tập tin của bạn đến một vị trí tạm thời. Bạn có thể "sửa" điều đó bằng cách cho avr-objdump biết nguồn là : avr-objdump -S -I/path/to/the/sketch/folder xxx.elf . Đó là đường dẫn thư mục phác thảo , không phải chính tệp .ino. Sau đó, bạn nên lấy nguồn C trong bãi chứa.
Nick Gammon

11

Vâng, tôi vừa thử nó với Arduino Uno của tôi và nó chỉ dừng hoàn toàn mã và để lại tất cả các đầu ra như khi mã ngừng chạy (vì vậy nó để lại một đèn LED tôi đã bật). Dường như không có dọn dẹp IO khi bạn gọi thoát. Đây là những gì tôi mong đợi vì Arduino IDE cung cấp các chức năng thiết lập và vòng lặp, nếu bạn lập trình ATMEGA * 28 với bất kỳ IDE IDE nào khác, bạn bắt đầu với chức năng chính như tất cả các chương trình C / C ++. Các chức năng thiết lập và vòng lặp không phải là tiêu chuẩn trên AVR MCU.

Lưu ý: Việc nhấn nút đặt lại sẽ khởi động lại mã, nếu bạn đang tự hỏi.


Tốt để biết. Tôi đang tìm kiếm một cái gì đó chi tiết hơn và ở mức độ thấp hơn . Trên gọi exit(0)các hướng dẫn tháo rời được (IIRC) __stop_program, clivà một spinlock. Tôi muốn xác minh xem điều đó có đúng không với lời giải thích về cách điều khiển được thông qua tức là gọi ngăn xếp pop?, Cuộc gọi ISR?
asheeshr

À, tôi chưa xem xét arduino ở mức độ thấp như vậy, vì thông tin đó bạn có thể muốn kiểm tra trang web của Atmel.
Jesse Laning
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.