roboforum.ru

Технический форум по робототехнике.

Проблема с доступом к памяти из DMA

ARM7, ARM9, ARM11 etc.

Проблема с доступом к памяти из DMA

Сообщение Andruhass » 09 дек 2011, 02:04

Я получаю через uart данные которые требуются записать на sd карту(простой регистратор).
Есть 2 массива по 64кБ в которые DMA записывает принимаемые данные и функция которая записывает, переданный ей массив, на карточку. DMA работает с массивами поочередно, тоесть пока оно заполняет один, другой в это время записывается на карту.

Проблема заключается в следующем:
Сначала DMA заполняет первый массив (mass_1);
Назначаю DMA второй массив (mass_2), записываю mass_1 на флешку;
И вот теперь, когда я назначаю DMA mass_1, оно записывает в mass_1 новые данные, но при этом пропускает в некоторых местах последовательности из 32 байтов(тоесть там остаются данные с предыдущего заполнения).
Так же и с mass_2. Если же я переключаюсь между тремя массивами, то такие дырки есть, но реже.

Такое ощущение что, что-то блокирует эти 32 байтовые последовательности для доступа из DMA.
Помогите понять причину

С уважением
Андрей
Andruhass
 
Сообщения: 2
Зарегистрирован: 05 июл 2011, 01:27

Re: Проблема с доступом к памяти из DMA

Сообщение boez » 09 дек 2011, 12:08

Телепаты ушли работать в ЦРУ и Газпром. Проц какой? Код инициализации DMA и самого обмена выложить можно?
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Проблема с доступом к памяти из DMA

Сообщение Andruhass » 09 дек 2011, 12:20

Забыл написать что работаю с ARM9 Samsung S3C2440 c MMU.

ОК, сегодня прийду домой, и выложу код инициализации

UPD: вот и код:

Записываю я на флешку в формате FAT32 с помощью функций из сторонней библиотеки.
Надеюсь нормально оформил
Код: Выделить всёРазвернуть
// Переменные
  unsigned char Rx_buffer1[65536];
  unsigned char Rx_buffer2[65536];  // Массивы 64кБ

  volatile int mass_1 = 1, mass_2 = 0, mass_3 = 0;  // Переменные для определения состояния массивов: 0 - не записывается и не
                                                    // готово для записи на флеш, 1 - в процессе заполнения DMA, 2 -
                                                    // заполнено и готово для записи на флеш
  int co = 50; // Количество записываемых массивов

// Кусок кода отвечающий за запись
file = fl_fopen("/file.txt", "c"); // открываем файл для записи
   if (file)
   {
           pISR_DMA0=(unsigned)DMA_end; // сохраняем адрес функции обработчика прерывания dma в таблицу прерываний (код
                                         // обработчика внизу)
           rINTMSK &= ~(BIT_DMA0);  // Разрешаем прерывание

           // DMA configuration
   
       rDISRC0=(U32)(URXH0);   // Источник данных для DMA = Rx регистр UARTа
       rDISRCC0=(1<<1)+(1<<0);   // DMA initial source control reg.:  [0] - address increment(1=fixed);
                                        // [1] - location of source (1=peripheral bus (APB))
       if(mass_1 == 1)
       {
          rDIDST0=(U32)(&Rx_buffer1);   // DMA destination адрес = 1й 64кБ массив
       }
        else if(mass_2 == 1)
       {
          rDIDST0=(U32)(&Rx_buffer2);   // DMA destination адрес = 2й 64кБ массив
       }
            
       rDIDSTC0=(0<<1)+(0<<0);   // DMA destination control reg.: [0] - address increment(1=increment);
                                        // [1] - location of source (1=system bus (AHB))

       rDCON0=(1<<31)+(0<<30)+(1<<29)+(0<<28)+(0<<27)+(1<<24)+(1<<23)+(1<<22)+(0<<20)+65536; // DMA config. reg.
                                    // [31] Demand or handshake mode;  [30] Dreq synchronization;  [29] Enable interrupt
                                  // [28] size of an atomic transfer; [27] service mode; [26:24]DMA request souce(001= uart0);
                                 // [22] reload on/off; [19:0] initial transfer count
           
            rDMASKTRIG0=(0<<2)+(1<<1)+0;  // [2] STOP; [1] ON_OFF; [0] SW_TRIG;
                                          //no-stop, DMA0 channel on, no-sw trigger

   while(co>0)
     {
      if(mass_1 == 2)  // Массив1 готов к записи
        {
         if (fl_fwrite(&Rx_buffer1, 1, sizeof(Rx_buffer1), file) != sizeof(Rx_buffer1)) //Записываем готовый массив на флешку
       Uart_Printf("ERROR: Write file failed\n");
                
       for(i=0;i<65535;i++)   //Чистим rx buffer1
      Rx_buffer1[i] = 0;
            
            mass_1 = 0; // Массив 1 отключен
            mass_2 = 1; // Массив 2 - заполняется DMA            
            co--;            
   }
            
      if(mass_2 == 2)
   {
         if (fl_fwrite(&Rx_buffer2, 1, sizeof(Rx_buffer2), file) != sizeof(Rx_buffer2))   //Записываем массив на флешку
       Uart_Printf("ERROR: Write file failed\n");
                
          for(i=0;i<65535;i++)   //Чистим rx buffer2
          Rx_buffer2[i] = 0;
                     
            mass_2 = 0;  // Массив 1 отключен
            mass_1 = 1;  // Массив 2 - заполняется DMA
            co--;            
   }
    rINTMSK |= (BIT_DMA0);  // Выключаем прерывания от DMA
    rDMASKTRIG0=(1<<2);   //DMA0 stop       
     }
  fl_fclose(file);  // Закрываем файл       
          
// Обработчик прерывания DMA   
void __irq DMA_end(void)
{
    ClearPending(BIT_DMA0);
   
    if(mass_1 == 1)
    {
       mass_1 = 2; // Массив 1 заполнен и готов к записи на флешку      
       rDIDST0=(U32)(&Rx_buffer2);  // Подставляем массив 2
    }
    else if(mass_2 == 1)
    {
        mass_2 = 2;    // Массив 2 заполнен и готов к записи на флешку     
       rDIDST0=(U32)(&Rx_buffer1);  // Подставляем массив 1
    }
}
Andruhass
 
Сообщения: 2
Зарегистрирован: 05 июл 2011, 01:27


Вернуться в ARM

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6