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

 
 
> 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
Ответов
kan35
сообщение Feb 8 2012, 17:15
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



JTAG/SWD что показывает? - доходит до части где взводится семафор?
Go to the top of the page
 
+Quote Post
Acvarif
сообщение Feb 9 2012, 06:55
Сообщение #3


Знающий
****

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



Цитата(kan35 @ Feb 8 2012, 21:15) *
JTAG/SWD что показывает? - доходит до части где взводится семафор?

Спасибо.
Запустил через SWD с точками останова и только тогда увидел ошибки.
Функция прерывание не взводила семафор. Вот (предварительно) верный вариант
CODE
void ADC_IRQHandler(void)
{

// Заполнение AdcBuff1
if(BuffIntCount == 0)
{
if(AdcIntCount%2 == 0)
AdcBuff1[AdcIntCount] = ADC1ConvertedValue;
else
AdcBuff1[AdcIntCount] = ADC1ConvertedValue >> 8;
// Инкремент счетчика байт
AdcIntCount++;
}
// Заполнение AdcBuff1
else if (BuffIntCount == 1)
{
if(AdcIntCount%2 == 0)
AdcBuff2[AdcIntCount] = ADC1ConvertedValue;
else
AdcBuff2[AdcIntCount] = ADC1ConvertedValue >> 8;
// Инкремент счетчика байт
AdcIntCount++;
}
// Если заполнился один из буферов
if(AdcIntCount == 100)
{
// Обнуление счетчика байт
AdcIntCount = 0;
// Смена признака буфера
if(BuffIntCount == 0) BuffIntCount = 1;
else BuffIntCount = 0;
// установка xHigherPriorityTaskWoken в pdFALSE
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;

/* ADC1 received */
// if (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == SET)
// {
/* Give the semaphore to wakeup ADC task */
xSemaphoreGiveFromISR( d_xSemaphore, &xHigherPriorityTaskWoken );
// }

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

/* Clear the interrupt flag. */
ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

}

Немного не понятно назначение этого
Код
    /* Switch tasks if necessary. */    
    if( xHigherPriorityTaskWoken != pdFALSE )
    {
      portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
    }

и в самой задачке неясно как лучше делать так (периодически разбуживать задачку)
Код
     if (xSemaphoreTake( d_xSemaphore, (250)) == pdPASS)
или так (не будить до прихода семафора)
Код
      if (xSemaphoreTake( d_xSemaphore, portMAX_DELAY )==pdTRUE)

Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 15:09
Рейтинг@Mail.ru


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