Доброго всем здравия!!!
Начал разбираться с
EMAC для
AT91SAM9260. Имеется документация на сам контроллер и тестовый пример для
IAR под названием
basic-emac-uip-webserver-project-at91sam9260-ek. В этой теме планируется задавать вопросы, которые касаются проблемы запуска Ethernet на вышеупомянутом контроллере и просто непонятные вещи.
Первый вопрос заключается в следующем. В файле
emac.h имеются некоторые указатели на функции:
Код
/// Callback used by send function
typedef void (*EMAC_TxCallback)(unsigned int status); // EMAC_TxCallback - указатель на функцию, возвращающую void и принимающую unsigned int
typedef void (*EMAC_RxCallback)(unsigned int status); // EMAC_RxCallback - указатель на функцию, возвращающую void и принимающую unsigned int
typedef void (*EMAC_WakeupCallback)(void); // EMAC_WakeupCallback - указатель на функцию, возвращающую void и принимающую void
Далее они используются, например в функции
EMAC_Handler, которая управляет прерываниями, расположенной в
emac.c:
Код
volatile EmacTxTDescriptor *pTxTd;
volatile EMAC_TxCallback *pTxCb;
Код
if (rxTd.rxCb) {
rxTd.rxCb(rxStatusFlag);
}
Код
if (*pTxCb) {
(*pTxCb)(txStatusFlag);
}
Я так понял это так называемые обратные функции, но что они делают нигде не определено (по-крайней мере я не нашел). Вопрос собственно для чего они нужны?
Еще один вопрос, что выполняет следующий кусок кода в той же функции
EMAC_Handler и для чего он нужен? Можно ли обойтись без всего этого?
Код
// Check the buffers
while (CIRC_CNT(txTd.head, txTd.tail, TX_BUFFERS)) {
pTxTd = txTd.td + txTd.tail;
pTxCb = txTd.txCb + txTd.tail;
// Exit if buffer has not been sent yet
if ((pTxTd->status & EMAC_TX_USED_BIT) == 0) {
break;
}
// Notify upper layer that packet has been sent
if (*pTxCb) {
(*pTxCb)(txStatusFlag);
}
CIRC_INC( txTd.tail, TX_BUFFERS );
}
// If a wakeup has been scheduled, notify upper layer that it can send
// other packets, send will be successfull.
if( (CIRC_SPACE(txTd.head, txTd.tail, TX_BUFFERS) >= txTd.wakeupThreshold)
&& txTd.wakeupCb) {
txTd.wakeupCb();
}