ZED“ (27.11.2010 12:55, просмотров: 2584)
Начал разбираться с 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();
}