Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Вновь о DMA
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Farsch
Уважаемые знатоки! Прошу о волшебном пинке.

для проверки работы DMA я создал довольно тривиальную систему
Нажмите для просмотра прикрепленного файла
следующим шагом станет замена onchip_memory2_1 на sdram_0 ну и далее добавление своего компонента.

вот так инициализирую DMA
Код
void init_dma (void)
{
    /* Create the transmit channel */
      if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL)
     {
       printf ("Failed to open transmit channel\n");
       //exit (1);
       }
      else printf ("Open transmit channel.. success\n");
       /* Create the receive channel */
       if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL)
       {
         printf ("Failed to open receive channel\n");
       //  exit (1);
       }
       else printf ("Open receive channel.. success\n");
       alt_dma_rxchan_ioctl(rxchan, ALT_DMA_SET_MODE_32, 0);
       alt_dma_txchan_ioctl(txchan, ALT_DMA_SET_MODE_32, 0);
}
вот такая функция транзакции пакета
Код
int dma_send (void* from, void* to, alt_u32 length)
{
    int dma_ret;
    if ((dma_ret = alt_dma_txchan_send (txchan,
            from,
            length,
            NULL,
            NULL)) < 0)
       {
       printf ("Failed to post transmit request, reason = %i\n", dma_ret);
       return 1;
       }
   if ((dma_ret = alt_dma_rxchan_prepare (rxchan,
               to/*rx_buffer*/,
            length,
            done,
            NULL)) < 0)
       {
       printf ("Failed to post read request, reason = %i\n", dma_ret);
       return 2;
       }
       /* wait for transfer to complete */
       while (!rx_done);
       printf ("Transfer successful!\n");
       rx_done--;
       printf ("rx_done = %u\n", (unsigned int) rx_done);
       return 0;
}

void ram2ram (void* tx_data_num, void* ram_data){   // передать тестовый пакет в onchip_memory2_1
    int dma_trans = 0;
    dma_trans = dma_send(tx_data_num, ram_data, TR_SZ);
        if (dma_trans){
            printf("result of operation is %u\n", (unsigned int) dma_trans);
        }
        else printf("ram2ram transfer succeed\n");
}

void ram2check (void* rx_buffer_check, void* ram_data){ // забрать пакет из onchip_memory2_1 в проверочную область и вывести в консоль
    int dma_trans = 0;
    int i;
    dma_trans = dma_send(ram_data, rx_buffer_check, TR_SZ);
        if (dma_trans){
                printf("result of operation is %u\n", (unsigned int) dma_trans);
            }
        else {
            printf("ram2check transfer succeed\n");
            printf ("rx_buffer_check:\n");
                    for (i = 0; i < TR_SZ/sizeof(int); i++)
                        printf("%u: %u\n",i,((unsigned int *) rx_buffer_check)[i]);
        }
}
done - инкрементирует rx_done

вот такой главный цикл
Код
int main (void)
{

  int i;
  int my_reg = 0;
  int my_val = 5;
void* tx_data_num =  (void*) alt_uncached_malloc(TR_SZ);  // указатель на начало тестового пакета
void* rx_buffer_check = (void*) alt_uncached_malloc(TR_SZ); // указатель на начало проверочного пакета
void* ram_data = (void*) 0x44000; // указатель на ONCHIP_MEMORY2_1_BASE

    for (i = 0; i < TR_SZ/sizeof(int); i++) // инициализация тестового пакета
       ((int *) tx_data_num)[i] = i;

    printf ("  ----====  APPLICATION START  ====----\n");

    init_dma();

    ram2check(ram_data, rx_buffer_check); // загрузить пакет из onchip_memory2_1 в проверочный,
                                                                 //printf(rx_buffer_check)

    print_num (tx_data_num);                    //printf(tx_data_num)
    ram2ram(tx_data_num, ram_data);       // загрузить тестовый пакет в начало onchip_memory2_1
    ram2check(ram_data, rx_buffer_check); // см. выше

    printf ("  ----====  APPLICATION FINISH  ====----\n");
    printf("tx_data_num = %x\n",(unsigned int)tx_data_num);
    printf("rx_buffer_check = %x\n",(unsigned int)rx_buffer_check);
    printf("ram_data = %x\n",(unsigned int)ram_data);

    for (i=0; i<4;i++){                          //а вот такой подход через макросы IOWR/IORD работает без помех
        setparam(my_reg+i,my_val+i);
        if ((int)getparam(my_reg+i)==my_val+i)
                        printf("Reg %d check success!!!\n",i+1);
                    else
                        printf("Reg %d check fail...\n",i+1);
    }

    return 0;
}

дело в том, что onchip_memory2_1 инициализируется из hex-файла.

но я не вижу прочитанных из неё данных ни после первого ram2check ни после записи туда инкремента.
получается, что либо не инициализируется память, либо не пишется, а вообще и то и другое help.gif
alt_dma_txchan_send, alt_dma_rxchan_prepare отвечают 0

но при этом отлично работают функции setparam, getparam написанные на макросах

вот что выдаёт консоль:
Цитата
----==== APPLICATION START ====----
Open transmit channel.. success
Open receive channel.. success
rx_done = 1
Transfer successful!
rx_done = 0
ram2check transfer succeed
rx_buffer_check: -------показывает пустой буфер в котором должны были быть числа из инициализационного hex
0: 0
1: 0
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
10: 0
11: 0
12: 0
13: 0
14: 0
15: 0
16: 0
17: 0
18: 0
19: 0
20: 0
21: 0
22: 0
23: 0
24: 0
25: 0
26: 0
27: 0
28: 0
29: 0
30: 0
31: 0
tx_data_num: ---- показывает тестовый пакет
0: 0
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9
10: 10
11: 11
12: 12
13: 13
14: 14
15: 15
16: 16
17: 17
18: 18
19: 19
20: 20
21: 21
22: 22
23: 23
24: 24
25: 25
26: 26
27: 27
28: 28
29: 29
30: 30
31: 31
rx_done = 1
Transfer successful!
rx_done = 0
ram2ram transfer succeed
rx_done = 1
Transfer successful!
rx_done = 0
ram2check transfer succeed
rx_buffer_check: -------показывает пустой буфер в котором должны был быть тестовый пакет
0: 0
1: 0
2: 0
3: 0
4: 0
5: 0
6: 0
7: 0
8: 0
9: 0
10: 0
11: 0
12: 0
13: 0
14: 0
15: 0
16: 0
17: 0
18: 0
19: 0
20: 0
21: 0
22: 0
23: 0
24: 0
25: 0
26: 0
27: 0
28: 0
29: 0
30: 0
31: 0
----==== APPLICATION FINISH ====----
tx_data_num = 80031f10 ---- вывод указателей полученный malloc
rx_buffer_check = 80031f98
ram_data = 44000
CTRL register WRITE operation
CTRL register READ operation
CTRLreg = 5
Reg 1 check success!!! ----- IOWR/IORD работают безотказно
TSIP register WRITE operation
TSIP register READ operation
TSIPreg = 6
Reg 2 check success!!!
L register WRITE operation
L register READ operation
Lreg = 7
Reg 3 check success!!!
D register WRITE operation
D register READ operation
Dreg = 8
Reg 4 check success!!!

пожалуйста, подскажите, где я неправильно сделал. может не всё так просто с подключением в SOPC Builder?
alexPec
А что DMA выбрали? Староват компонент вроде. SGDMA поновее будет. SGDMA работал без проблем, при создании нового проекта ниос было даже что-то вроде "Test memory template", точно не помню. Так вот кроме обычного чтения-записи там проверялись и каналы DMA. Это у меня в Q9.1 было.
Farsch
Цитата(alexPec @ May 21 2012, 22:21) *
А что DMA выбрали? Староват компонент вроде. SGDMA поновее будет. SGDMA работал без проблем, при создании нового проекта ниос было даже что-то вроде "Test memory template", точно не помню. Так вот кроме обычного чтения-записи там проверялись и каналы DMA. Это у меня в Q9.1 было.

не подскажете дельного примера по подключению SGDMA в SOPC_Builder и пример кода для работы с ним?
barabek
Цитата(AlexPec)
А что DMA выбрали? Староват компонент вроде. SGDMA поновее будет. SGDMA работал без проблем

Не согласен. DMA тоже нормально работает. Это несколько разные компоненты по массе. Обратите внимание, сколько занимает SGDMA, а сколько просто DMA. Так что выбирать нужно с головой. Там где справится просто DMA его и следует применять. С библиотеками от DMA я не разобрался. Какие то они показались избыточно сложные. Там регистров всего пару, с ними проще. настраивается на ура.
gosu-art
Цитата(Farsch @ May 22 2012, 00:23) *
не подскажете дельного примера по подключению SGDMA в SOPC_Builder и пример кода для работы с ним?

В ветке Ethernet + Cyclone + Nios
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.