реклама на сайте
подробности

 
 
> stm32+ FreeRtos семафоры для Ethernet и ADC
Acvarif
сообщение Feb 5 2012, 13:09
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Несколько раз перечитал мануал по FreeRTOS в части бинарных семафоров и так до конца и не понял, если имеются два прерывания (например ETH_IRQHandler и ADC_IRQHandler) то для каждого из них нужен свой бинарный семафор или бинарный семафор может быть только один на всех (или вообще только один)?

Суть задачки: Имеется готовый пример использования (FreeRTOS+LwIP) для STM32F217 http://electronix.ru/forum/index.php?showt...98347&st=30 в котором неплохо работает прием по UDP по прерываниям с использованием бинарного семафора
CODE
void ETH_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* Frame received */
if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
{
/* Give the semaphore to wakeup LwIP task */
xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
}

/* Clear the interrupt flags. */
/* Clear the Eth DMA Rx IT pending bits */
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
ETH_DMAClearITPendingBit(ETH_DMA_IT_NIS);

/* Switch tasks if necessary. */
if( xHigherPriorityTaskWoken != pdFALSE )
{
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}

сам таск выглядит так
void ethernetif_input( void * pvParameters )
{
struct pbuf *p;

for( ;; )
{
if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
{
p = low_level_input( s_pxNetIf );
if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
{
pbuf_free(p);
p=NULL;
}
}
}
}



Имеется необходимость передавать по Ethernet выборки ADC1 (каждую выборку или накапливать небольшой буфер пока неясно)
Наверняка выгодно для этой цели создать task в заторможенном состоянии которая будет разблокироваться прерыванием
по ADC1
Код
void ADC_IRQHandler(void)
{
  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

  /* ADC1 received */
  if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET)
  {
    /* Give the semaphore to wakeup ADC1 task */
    xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );  
  }
    
  /* Clear the interrupt flag. */
  ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
}
и затем уже в таске, которая будет разбужена семафором передавать UDP пакет с выборкой.

Вот и непонятно можно ли использовать один и тот же бинарный семафор для разных тасков? Если да то как будет выглядеть таск который будет выполнен по прерыванию ADC1? Может так?
CODE
void AdcUdpSend(void * pvParameters)
{
struct netconn *connn;
struct netbuf *buf1;
struct ip_addr addr;
static char text[2];

// create a new connection
connn = netconn_new(NETCONN_UDP);
// set up the IP address of the remote host
IP4_ADDR(&addr, DIP_ADDR0, DIP_ADDR1, DIP_ADDR2, DIP_ADDR3);
// connect the connection to the remote host
netconn_connect(connn, &addr, 7);
// create a new netbuf
buf1 = netbuf_new();

while(1)
{
test = xnetif.ip_addr.addr;
//check if IP address assigned
if (test !=0)
{
for( ;; )
{
if (xSemaphoreTake( s_xSemaphore, emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
{
text[1] = ADC1ConvertedValue;
text[0] = ADC1ConvertedValue >> 8;

netbuf_ref(buf1, text, sizeof(text));
// послать Eth пакет
netconn_send(connn, buf1);
}
}
}
}
}

В этом случае
emacBLOCK_TIME_WAITING_FOR_INPUT определен как
#define emacBLOCK_TIME_WAITING_FOR_INPUT ( ( portTickType ) 100 )
(оставил так же как и для таска приема Eth пакетов)
Как лучше определить блокировку для этой задачи - задачи передачи Eth пакетов по прерыванию ADC1?
Поскольку прерывания от ADC будут приходить довольно часто (~ 10 мкс) не будет ли это тормозом для Ethernet приемника и вобще для всего приложения?

Сообщение отредактировал Acvarif - Feb 5 2012, 15:35
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
unkier
сообщение Feb 7 2012, 03:19
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 24
Регистрация: 20-01-08
Пользователь №: 34 249



насколько я понял когда разбирался с lwip, s_xSemaphore отпускается в прерывании от сетевухи когда пришли данные, стек ловит этот семафор и принимает пакет. какой смысл отпускать этот семафор в прерывании от adc ?
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Feb 7 2012, 08:44
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 998
Регистрация: 27-08-08
Пользователь №: 39 850



Цитата(unkier @ Feb 7 2012, 06:19) *
насколько я понял когда разбирался с lwip, s_xSemaphore отпускается в прерывании от сетевухи когда пришли данные, стек ловит этот семафор и принимает пакет. какой смысл отпускать этот семафор в прерывании от adc ?

Так оно и есть - s_xSemaphore отдает прерывание по приему Ethernet. Берет его таск стека, который до того находится в заторможенном состоянии.
Согласен нет смысла этот семафор использовать и для ADC (хотя хочется)
А как тогда быть?

Прерывания ADC идут через ~ 10 мкс. Они должны вызывать таск который будет засовывать данные в некоторый буфер. При достижении нужного количества данных они должны быть выплюнуты по Lwip UDP на комп.
Если не использовать семафор от lwip то как быть, как технически постоить такую операцию не мешая стеку ловить пакеты на прием и в то же время по прерываниям ADC накапливать данные для пакета на передачус последующей их передачей?
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 19:32
Рейтинг@Mail.ru


Страница сгенерированна за 0.02898 секунд с 7
ELECTRONIX ©2004-2016