Şu anda Cortex M0 / M4 için kodlama yapıyorum ve C ++'da kullandığımız yaklaşım (C ++ etiketi yok, bu yüzden bu cevap konu dışı olabilir) aşağıdaki gibidir:
CInterruptVectorTable
Denetleyicinin gerçek kesme vektöründe saklanan tüm kesme hizmeti rutinlerini içeren bir sınıf kullanırız :
#pragma location = ".intvec"
extern "C" const intvec_elem __vector_table[] =
{
{ .__ptr = __sfe( "CSTACK" ) }, // 0x00
__iar_program_start, // 0x04
CInterruptVectorTable::IsrNMI, // 0x08
CInterruptVectorTable::IsrHardFault, // 0x0C
//[...]
}
Sınıf CInterruptVectorTable
, kesme vektörlerinin bir soyutlamasını uygular, böylece çalışma sırasında kesme vektörlerine farklı işlevler bağlayabilirsiniz.
Bu sınıfın arayüzü şöyle görünür:
class CInterruptVectorTable {
public :
typedef void (*IsrCallbackfunction_t)(void);
enum InterruptId_t {
INTERRUPT_ID_NMI,
INTERRUPT_ID_HARDFAULT,
//[...]
};
typedef struct InterruptVectorTable_t {
IsrCallbackfunction_t IsrNMI;
IsrCallbackfunction_t IsrHardFault;
//[...]
} InterruptVectorTable_t;
typedef InterruptVectorTable_t* PinterruptVectorTable_t;
public :
CInterruptVectorTable(void);
void SetIsrCallbackfunction(const InterruptId_t& interruptID, const IsrCallbackfunction_t& isrCallbackFunction);
private :
static void IsrStandard(void);
public :
static void IsrNMI(void);
static void IsrHardFault(void);
//[...]
private :
volatile InterruptVectorTable_t virtualVectorTable;
static volatile CInterruptVectorTable* pThis;
};
Vektör tablosunda saklanan işlevleri yapmanız gerekir, static
çünkü this
vektör tablosu bir nesne olmadığından denetleyici bir- işareti sağlayamaz . Bu sorunun pThis
üstesinden gelmek için, içinde statik- işaretçi var CInterruptVectorTable
. Statik kesme fonksiyonlarından birine girildiğinde pThis
, bir nesnenin üyelerine erişmek için -pointer öğesine erişebilir CInterruptVectorTable
.
Şimdi programda, bir kesme meydana geldiğinde çağrılacak SetIsrCallbackfunction
bir static
işleve bir işlev işaretçisi sağlamak için kullanabilirsiniz . İşaretçiler InterruptVectorTable_t virtualVectorTable
.
Ve bir kesme fonksiyonunun uygulanması şöyle görünür:
void CInterruptVectorTable::IsrNMI(void) {
pThis->virtualVectorTable.IsrNMI();
}
Böylece bu static
, başka bir sınıfın (bu olabilir private
) bir yöntemini çağırır ve daha sonra static
this
o nesnenin üye değişkenlerine (yalnızca bir) erişmek için başka bir- işaretçisi içerebilir .
Sanırım IInterruptHandler
nesneler için işaretçiler oluşturup saklayabilirsiniz, böylece static
this
tüm bu sınıflarda -pointer'a ihtiyacınız yoktur . (belki bunu mimarimizin bir sonraki tekrarında deneriz)
Diğer yaklaşım bizim için iyi static
this
sonuç verir , çünkü bir kesme işleyicisi uygulamak için izin verilen tek nesneler donanım soyutlama katmanının içindeki nesnelerdir ve genellikle her donanım bloğu için sadece bir nesnemiz vardır , bu yüzden -pointers ile iyi çalışır. Ve donanım soyutlama katmanı, daha ICallback
sonra donanımın üstündeki cihaz katmanında uygulanan denilen kesintilere başka bir soyutlama sağlar .
Global verilere erişiyor musunuz? Tabii ki yaparsınız, ancak gerekli global verilerin this
çoğunu -pointler ve kesme işlevleri gibi özel yapabilirsiniz.
Kurşun geçirmez değildir ve ek yük getirir. Bu yaklaşımı kullanarak bir IO-Link yığını uygulamak için mücadele edeceksiniz. Ancak zamanlamalar konusunda son derece sıkı değilseniz, her yerden erişilebilen global değişkenler kullanmadan modüllerde esnek bir kesinti ve iletişim soyutlaması elde etmek için oldukça iyi çalışır.