Bu, babamın hep bana sorduğu bir soru. “ Neden sadece tüm talimatları yerine getirmiyor ve sonunda bitmiyor? ”
Patolojik bir örneğe bakalım. Aşağıdaki kod, PIC18 için Microchip'in C18 derleyicisinde derlendi:
void main(void)
{
}
Aşağıdaki assembler çıktısını üretir:
addr opco instruction
---- ---- -----------
0000 EF63 GOTO 0xc6
0002 F000 NOP
0004 0012 RETURN 0
.
. some instructions removed for brevity
.
00C6 EE15 LFSR 0x1, 0x500
00C8 F000 NOP
00CA EE25 LFSR 0x2, 0x500
00CC F000 NOP
.
. some instructions removed for brevity
.
00D6 EC72 CALL 0xe4, 0 // Call the initialisation code
00D8 F000 NOP //
00DA EC71 CALL 0xe2, 0 // Here we call main()
00DC F000 NOP //
00DE D7FB BRA 0xd6 // Jump back to address 00D6
.
. some instructions removed for brevity
.
00E2 0012 RETURN 0 // This is main()
00E4 0012 RETURN 0 // This is the initialisation code
Gördüğünüz gibi main () denir ve sonunda bir dönüş ifadesi içerir, ancak açıkça kendimiz koymadık. Ana döndüğünde, CPU kodun başına geri dönmek için sadece GOTO olan bir sonraki komutu çalıştırır. main () sadece tekrar tekrar denir.
Şimdi, bunu söyledikten sonra, bu insanların genellikle işleri yapma şekli değildir. Main () 'in böyle çıkmasına izin verecek herhangi bir gömülü kod yazmadım. Çoğunlukla, kodum şuna benzer:
void main(void)
{
while(1)
{
wait_timer();
do_some_task();
}
}
Böylece normalde main () 'in çıkmasına asla izin vermem.
"Tamam tamam" diyorsun. Tüm bunlar, derleyicinin asla son bir dönüş beyanı olmadığından emin olmasını çok ilginç. Ama konuyu zorlarsak ne olur? El montajcımı kodladıysam ve en başa bir sıçrama yapmadıysa?
Belli ki CPU bir sonraki talimatları yerine getirmeye devam edecek. Şunun gibi bir şeye benzeyeceklerdi:
addr opco instruction
---- ---- -----------
00E6 FFFF NOP
00E8 FFFF NOP
00EA FFFF NOP
00EB FFFF NOP
.
. some instructions removed for brevity
.
7EE8 FFFF NOP
7FFA FFFF NOP
7FFC FFFF NOP
7FFE FFFF NOP
Main () 'deki son komuttan sonra bir sonraki hafıza adresi boştur. FLASH belleğe sahip bir mikrodenetleyicide, boş bir komut 0xFFFF değerini içerir. En azından bir PIC'de, bu op kodu bir "hayır" veya "işlem yok" olarak yorumlanır. Bu sadece hiçbir şey yapmaz. CPU bu nops'ları bellekten sonuna kadar yürütmeye devam edecektir.
Bundan sonra ne var?
Son komutta, CPU'nun talimat göstericisi 0x7FFe'dir. CPU, komut göstergesine 2 eklediğinde, yalnızca 32k FLASH ile bir PIC'de taşma olarak kabul edilen 0x8000 değerini alır ve böylece 0x0000'e geri sarılır ve CPU mutlu bir şekilde kodun başlangıcında talimatları yerine getirmeye devam eder. , tıpkı sıfırlanmış gibi.
Ayrıca güç kapatmanın gerekliliği hakkında da sorular sordunuz. Temelde ne istersen yapabilirsin, ve bu uygulamana bağlı.
Açtıktan sonra yalnızca bir şeyi yapmanız gereken bir uygulamanız varsa ve sonra bir süre koyabileceğiniz başka bir şey yapmazsanız (1); main'in sonunda () CPU dikkat çeken bir şey yapmayı bırakır.
Uygulama CPU'nun kapanmasını gerektiriyorsa, CPU'ya bağlı olarak, muhtemelen çeşitli uyku modları olacaktır. Ancak, CPU'ların tekrar uyanma alışkanlığı vardır, bu nedenle uyku için zaman sınırı olmadığından ve Watch Dog Timer'ın aktif olmadığından emin olmalısınız.
İşlem tamamlandıktan sonra CPU'nun kendi gücünü tamamen kesmesini sağlayacak bazı harici devreler bile organize edebilirsiniz. Bu soruya bakın: Mandal açma açma / kapatma düğmesi olarak anlık bir buton kullanma .