Gömülü sistemler için dişli alternatifleri
Şu anda elektrik mühendisliği okuyorum. Pandemiler nedeniyle derslerim askıya alındı ve bu sefer elektronik ve programlama hakkında daha fazla şey öğreniyorum.
Şu anda Pic16f628a
bazı özelliklere sahip bir dijital saat oluşturmak için bir ve genel bir dijital ekran kullanmaya çalışıyorum . Mesele şu ki, saat görüntülenirken yürütme zamanında bir düğmeye basarak bir menüye erişmek zorunda kaldım. Normalde saat gösterimi için bir iş parçacığı çağırırdım ve ana iş parçacığı girdileri izlerdi, ancak pic denetleyicinin basitliği nedeniyle kaynağı kullanamıyorum.
Yani, benim C kodum (henüz özellikle resme uygulanmadı) şöyle bir şey:
void display_timer(){
static struct current_time timer;
static int is_time_set = 0;
set_current_time(&timer, &is_time_set);
while (is_time_set){
system("clear");
printf("########\n");
printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
printf("########\n");
sleep(1);
update_timer(&timer, &is_time_set);
}
}
int main ()
{
while (1){
display_menu();
}
}
Uyku sırasında (), kontrolör yeni girişleri izleyebilmeli ve buna göre hareket edebilmelidir.
Düşündüğüm bir alternatif, bir düğmeye basmak için bir durum makinesi kullanmaktı, uyku işlevini 4 veya 8 aralığa böldü, buna benzer bir şey:
while (is_time_set){
system("clear");
printf("########\n");
printf("%d:%d:%d\n", timer.HOURS, timer.MINUTES, timer.SECONDS);
printf("########\n");
for (int i = 0; i<8; i++){
if (state_machine_input == 1){state_machine_input = 0; break;}
sleep(1/8);
}
update_timer(&timer, &is_time_set);
Yapılabilir, ancak projeye daha fazla karmaşıklık katmak zorunda kalmazsam, örneğin başka bir durum makinesi eklersem memnun olurum. Bu işlevselliği uygulamak için yazılımın bir kısmında ne yapabilirim?
Yanıtlar
İş parçacığı, mikro denetleyici programlamasından daha yüksek seviyeli bir kavramdır. Basitçe söylemek gerekirse, iş parçacıkları zamanlayıcı kesintilerini kullanan bir zamanlayıcı olarak uygulanır, bu da program sayacını + yığın işaretçisini vb. Kaydeder ve bunları farklı konumlara ayarlar. Böylelikle, benzer bir konsepti kesintileri kullanarak uygulamak oldukça mümkün ve kolaydır - genel çoklu iş parçacığı yerine özel kesmeler almanız avantajıyla.
Bu, yığın kullanımı söz konusu olduğunda son derece sınırlı olan PIC gibi kısıtlı bir eski 8 bitter ile yapmanın tek mantıklı yolu ile ilgili. Mikro denetleyiciler için yazılanlar da dahil olmak üzere iş parçacığı kitaplıklarını kullanmayı unutun. Bu, elde edilen hiçbir şey için yalnızca aşırı şişkinlik ve karmaşıklık ekleyecektir. Genel olarak PC programlama kavramlarını gömülü dünyaya sürüklemek kötü bir fikirdir.
Yapmanız gereken şey, düğme taramanızı 10 ms'de bir veya daha fazla bir kez yürütülen döngüsel bir zamanlayıcı kesintisinin içine koymaktır. Kesmenin içinden, düğmeleri yok saymak için düğmeleri yoklar ve bir önceki ile okunan düğmeyi karşılaştırırsınız. Bunun sonucu, ana programla paylaşılan bir değişkende saklanır volatile
, yarış koşulları olarak ilan edilir ve bu koşullardan korunur. Değişkene sadece kesmelerin içinden yazdığınız için, okumaların 8 bit olmasını sağlamak için yeterli koruma olabilir, ancak emin olmak için sökmeniz gerekir. Bununla ilgili daha fazla bilgi burada: Gömülü C geliştirmede uçucu kullanma .
Kesmeleri kullan
Bir düğmeye bastığınızda biraz kod çalıştırmak ister misiniz? Bir pin değiştirme-kesme kullanın
Belirli aralıklarla bir şeyler yapmak ister misin? Bir zamanlayıcı kesme kullanın
Bir bakıma, mikro denetleyicinin donanımı, kesme kaynaklarını izleyen ve her olay için bir "geri arama" veya kesme rutini çalıştıran bir "iş parçacığı" çalıştırır.
Kesinti yürütülürken ana program otomatik olarak duraklatılır.
Kesintiler ve ana kod arasında veri paylaşmanın yaygın bir yolu, volatile
genel değişkenler aracılığıyla ve denetleyicinin kelime boyutundan daha büyük olduklarında (neredeyse her zaman 8 bitlik bir denetleyicide) bu küresellerden veri okurken kesintileri geçici olarak devre dışı bırakmaktır
Muhtemelen ortak bir çoklu görev kütüphanesi öneririm. Geçmişte kullandığım biri Protothreads:http://www.dunkels.com/adam/pt/
Herhangi bir iyi kooperatif çoklu görev kütüphanesi, olayları takip etmek için gereken örtük durum makinesini soyutlamaya yardımcı olacaktır.
İyi şanslar.
Gömülü sistem söz konusu olduğunda, genel olarak çoklu görev ile farklı yaklaşımlar vardır:
- Yoklama veya İşbirliğine Dayalı Çoklu Görev : Her şey tek bir sonsuz döngüde yapılır ve görevler gecikmeyi önlemek için mümkün olan minimum süreyi alacak ve ana uygulamaya olabildiğince hızlı dönecek şekilde tasarlanmıştır. Bu mimari için uygun görevlerin, üst düzey kavram açısından düşündüğünüz gibi olmayabileceğini unutmayın, örneğin uygulamanızda bir görev
update_display
ve başka bir görev olabilircheck_button
ve aşağıdaki gibi bir döngü oluşturursunuz:
while(1){
check_buttons();
update_display();
sleep(0.1); //seconds
}
Kesmeler : Donanım kesintilerine bağlı olarak olası tüm girişler ve ana yürütme, kesintiye uğratılamayan şeyler için bırakılır (hiçbir şey olmayabilir, bu durumda genellikle mikro denetleyici güç tüketimini azaltmak için uyku moduna alınır. genellikle kullanılan mikro denetleyiciye ve derleyiciye bağlıdır.
RTOS : Mikrodenetleyicinin ne kadar güç sağladığına bağlı olarak, görevler veya hatta iş parçacıkları oluşturmak için API sağlayabilen bir Gerçek Zamanlı İşletim Sistemi (RTOS) çalıştırmak mümkün olabilir. Bu, uygulamaya ve donanım yeteneklerine bağlıdır ve eğitim için örnekler gerekli olmamalıdır (veya tavsiye edilebilir, imo)
Ayrıca, uygulamanın genel mimarisine karar vermenin bir diğer önemli kısmının da görevler ve nasıl işbirliği yaptıklarıdır. Kullanılan paradigmalardan biri Durum Makineleri'dir (bağlantı ezici olabilecek genel wikipedia sayfasına bağlantıdır, gömülü programlamaya özgü daha basit kaynaklar ders kitabınızda veya google'da bulunabilir).
Çoğunlukla, 8 bitlik cihazlarda sınırlı kaynak vardır. 8 bit PIC'lerde daha basit çözümün daha iyi bir çözüm olduğunu düşünüyorum.
2 farklı görev için donanım Zamanlayıcıları oluşturabilirsiniz. Bir bayrak ayarlayın ve sonsuz döngünüzdeki bayrağı kontrol edin, görevi yapın ve bayrağı sıfırlayın. Gecikmeleri kullanmayın. Bu yöntem, bayraklarınız artarsa, görevlerinizi sonsuz döngünüzde tamamlamayı garanti eder.
Ancak, görevlerin bayraklar yükseldiğinde tam olarak yerine getirilmediğini bilmelisiniz. Aynı anda ayarlanmış iki bayrak varsa, hangisinin önce yürütüldüğünü bilemezsiniz. Çünkü sonsuz döngünün nerede olduğunu bilmiyorsunuz. Ancak, zaman açısından kritik olmayan arabirim uygulamaları için çoğunlukla sorun yoktur .