Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: DMA и SGDMA в NIOS системе
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
AlexBalan
Занимаюсь изучением ALT DMA и SGDMA (memory to memory) и столкнулся со следующей проблемой: память копируется некорректно - то есть часть инфы копируется а часть - нет, "островками". И DMA и SGDMA завершают работу без ошибок, success типо, а вот memcmp() и ыввод содержимого буферов на экран открывают печальную картину. Буфера src и dst (это так, для учебы rolleyes.gif ) организованы onchip, отдельно друг от друга и от основной onchip ram. Ниже приведу пример программы (взято из alt man'a и слегка изменено) и ее результат;

Будьте добры, помогите разобраться, наверно есть какие то грабли..

Код
#include <stdio.h>
#include "system.h"
#include "sys/alt_dma.h"

typedef unsigned int uint;
typedef unsigned char byte;

// Количество копируемых байт (на самом деле, буфера объемом 1к каждый)
#define    BUFFER_SIZE        256

// Флаг завершения ДМА операции
static volatile uint rx_done = 0;

// Обработчик прерывания ДМА
static void done(void* handle, void* data)
{
    ++rx_done;
}

int main()
{
    int rc;

    alt_dma_txchan txchan;
    alt_dma_rxchan rxchan;

    byte* tx_buffer = (void*)SRS_BUFF_BASE;
    byte* rx_buffer = (void*)DST_BUFF_BASE;

        // предварительно зануляю приемник и заполняю источник
    uint i;
    for(i = 0; i < BUFFER_SIZE; i++)
    {
        tx_buffer[i] = i;
        rx_buffer[i] = 0;
    }

        /// Далее - работа с ДМА

    if((txchan = alt_dma_txchan_open(DMA_0_NAME)) == NULL)
    {
        printf("failed to open transmit channel\n");
        return 1;
    }

    if((rxchan = alt_dma_rxchan_open(DMA_0_NAME)) == NULL)
    {
        printf("failed to open receive channel\n");
        return 1;
    }

    if((rc = alt_dma_txchan_send(txchan , tx_buffer, BUFFER_SIZE, NULL, NULL)) < 0)
    {
        printf("Failed to post transmit request, reason = %i\n", rc);
        return 1;
    }

    if((rc = alt_dma_rxchan_prepare(rxchan , rx_buffer, BUFFER_SIZE, done, NULL)) < 0)
    {
        printf("Failed to post receive request, reason = %i\n", rc);
        return 1;
    }

        // Жду окончания транзакции
    while(!rx_done);

    printf("Transfer successful!\n");

        // Принтую содержимое буферов и факт совпадения/несовпадения
    for(i = 0; i < BUFFER_SIZE; i++)
    {
        if(rx_buffer[i] != tx_buffer[i])
        {
            printf("neq! : rx_buffer[%d] = %x, tx_buffer[%d] = %x\n",i,rx_buffer[i],i,tx_buffer[i]);
        }
        else
        {
            printf("eq! : rx_buffer[%d] = %x, tx_buffer[%d] = %x\n",i,rx_buffer[i],i,tx_buffer[i]);
        }
    }

        // Изначально думал обойтись только memcmp() но наличие ошибок ДМА заставило добавить
        // вышеприведенный код отображения содержимого памяти на консоль..
    if(memcmp(tx_buffer, rx_buffer, BUFFER_SIZE))
    {
        printf("not equal!\n");
    }
    else
    {
        printf("ok.\n");
    }

    return 0;
}


И вот результат ее работы:

Код
Transfer successful!
eq! : rx_buffer[0] = 0, tx_buffer[0] = 0
neq! : rx_buffer[1] = 0, tx_buffer[1] = 1
neq! : rx_buffer[2] = 0, tx_buffer[2] = 2
neq! : rx_buffer[3] = 0, tx_buffer[3] = 3
neq! : rx_buffer[4] = 0, tx_buffer[4] = 4
neq! : rx_buffer[5] = 0, tx_buffer[5] = 5
neq! : rx_buffer[6] = 0, tx_buffer[6] = 6
neq! : rx_buffer[7] = 0, tx_buffer[7] = 7
neq! : rx_buffer[8] = 0, tx_buffer[8] = 8
neq! : rx_buffer[9] = 0, tx_buffer[9] = 9
neq! : rx_buffer[10] = 0, tx_buffer[10] = a
neq! : rx_buffer[11] = 0, tx_buffer[11] = b
neq! : rx_buffer[12] = 0, tx_buffer[12] = c
neq! : rx_buffer[13] = 0, tx_buffer[13] = d
neq! : rx_buffer[14] = 0, tx_buffer[14] = e
neq! : rx_buffer[15] = 0, tx_buffer[15] = f
neq! : rx_buffer[16] = 0, tx_buffer[16] = 10
neq! : rx_buffer[17] = 0, tx_buffer[17] = 11
neq! : rx_buffer[18] = 0, tx_buffer[18] = 12
neq! : rx_buffer[19] = 0, tx_buffer[19] = 13
neq! : rx_buffer[20] = 0, tx_buffer[20] = 14
neq! : rx_buffer[21] = 0, tx_buffer[21] = 15
neq! : rx_buffer[22] = 0, tx_buffer[22] = 16
neq! : rx_buffer[23] = 0, tx_buffer[23] = 17
neq! : rx_buffer[24] = 0, tx_buffer[24] = 18
neq! : rx_buffer[25] = 0, tx_buffer[25] = 19
neq! : rx_buffer[26] = 0, tx_buffer[26] = 1a
neq! : rx_buffer[27] = 0, tx_buffer[27] = 1b
neq! : rx_buffer[28] = 0, tx_buffer[28] = 1c
neq! : rx_buffer[29] = 0, tx_buffer[29] = 1d
neq! : rx_buffer[30] = 0, tx_buffer[30] = 1e
neq! : rx_buffer[31] = 0, tx_buffer[31] = 1f
eq! : rx_buffer[32] = 20, tx_buffer[32] = 20
eq! : rx_buffer[33] = 21, tx_buffer[33] = 21
eq! : rx_buffer[34] = 22, tx_buffer[34] = 22
eq! : rx_buffer[35] = 23, tx_buffer[35] = 23
eq! : rx_buffer[36] = 24, tx_buffer[36] = 24
eq! : rx_buffer[37] = 25, tx_buffer[37] = 25
eq! : rx_buffer[38] = 26, tx_buffer[38] = 26
eq! : rx_buffer[39] = 27, tx_buffer[39] = 27
eq! : rx_buffer[40] = 28, tx_buffer[40] = 28
eq! : rx_buffer[41] = 29, tx_buffer[41] = 29
eq! : rx_buffer[42] = 2a, tx_buffer[42] = 2a
eq! : rx_buffer[43] = 2b, tx_buffer[43] = 2b
eq! : rx_buffer[44] = 2c, tx_buffer[44] = 2c
eq! : rx_buffer[45] = 2d, tx_buffer[45] = 2d
eq! : rx_buffer[46] = 2e, tx_buffer[46] = 2e
eq! : rx_buffer[47] = 2f, tx_buffer[47] = 2f
eq! : rx_buffer[48] = 30, tx_buffer[48] = 30
eq! : rx_buffer[49] = 31, tx_buffer[49] = 31
eq! : rx_buffer[50] = 32, tx_buffer[50] = 32
eq! : rx_buffer[51] = 33, tx_buffer[51] = 33
eq! : rx_buffer[52] = 34, tx_buffer[52] = 34
eq! : rx_buffer[53] = 35, tx_buffer[53] = 35
eq! : rx_buffer[54] = 36, tx_buffer[54] = 36
eq! : rx_buffer[55] = 37, tx_buffer[55] = 37
eq! : rx_buffer[56] = 38, tx_buffer[56] = 38
eq! : rx_buffer[57] = 39, tx_buffer[57] = 39
eq! : rx_buffer[58] = 3a, tx_buffer[58] = 3a
eq! : rx_buffer[59] = 3b, tx_buffer[59] = 3b
eq! : rx_buffer[60] = 3c, tx_buffer[60] = 3c
eq! : rx_buffer[61] = 3d, tx_buffer[61] = 3d
eq! : rx_buffer[62] = 3e, tx_buffer[62] = 3e
eq! : rx_buffer[63] = 3f, tx_buffer[63] = 3f
eq! : rx_buffer[64] = 40, tx_buffer[64] = 40
eq! : rx_buffer[65] = 41, tx_buffer[65] = 41
eq! : rx_buffer[66] = 42, tx_buffer[66] = 42
eq! : rx_buffer[67] = 43, tx_buffer[67] = 43
eq! : rx_buffer[68] = 44, tx_buffer[68] = 44
eq! : rx_buffer[69] = 45, tx_buffer[69] = 45
eq! : rx_buffer[70] = 46, tx_buffer[70] = 46
eq! : rx_buffer[71] = 47, tx_buffer[71] = 47
eq! : rx_buffer[72] = 48, tx_buffer[72] = 48
eq! : rx_buffer[73] = 49, tx_buffer[73] = 49
eq! : rx_buffer[74] = 4a, tx_buffer[74] = 4a
eq! : rx_buffer[75] = 4b, tx_buffer[75] = 4b
eq! : rx_buffer[76] = 4c, tx_buffer[76] = 4c
eq! : rx_buffer[77] = 4d, tx_buffer[77] = 4d
eq! : rx_buffer[78] = 4e, tx_buffer[78] = 4e
eq! : rx_buffer[79] = 4f, tx_buffer[79] = 4f
eq! : rx_buffer[80] = 50, tx_buffer[80] = 50
eq! : rx_buffer[81] = 51, tx_buffer[81] = 51
eq! : rx_buffer[82] = 52, tx_buffer[82] = 52
eq! : rx_buffer[83] = 53, tx_buffer[83] = 53
eq! : rx_buffer[84] = 54, tx_buffer[84] = 54
eq! : rx_buffer[85] = 55, tx_buffer[85] = 55
eq! : rx_buffer[86] = 56, tx_buffer[86] = 56
eq! : rx_buffer[87] = 57, tx_buffer[87] = 57
eq! : rx_buffer[88] = 58, tx_buffer[88] = 58
eq! : rx_buffer[89] = 59, tx_buffer[89] = 59
eq! : rx_buffer[90] = 5a, tx_buffer[90] = 5a
eq! : rx_buffer[91] = 5b, tx_buffer[91] = 5b
eq! : rx_buffer[92] = 5c, tx_buffer[92] = 5c
eq! : rx_buffer[93] = 5d, tx_buffer[93] = 5d
eq! : rx_buffer[94] = 5e, tx_buffer[94] = 5e
eq! : rx_buffer[95] = 5f, tx_buffer[95] = 5f
neq! : rx_buffer[96] = 0, tx_buffer[96] = 60
neq! : rx_buffer[97] = 0, tx_buffer[97] = 61
neq! : rx_buffer[98] = 0, tx_buffer[98] = 62
neq! : rx_buffer[99] = 0, tx_buffer[99] = 63
neq! : rx_buffer[100] = 0, tx_buffer[100] = 64
neq! : rx_buffer[101] = 0, tx_buffer[101] = 65
neq! : rx_buffer[102] = 0, tx_buffer[102] = 66
neq! : rx_buffer[103] = 0, tx_buffer[103] = 67
neq! : rx_buffer[104] = 0, tx_buffer[104] = 68
neq! : rx_buffer[105] = 0, tx_buffer[105] = 69
neq! : rx_buffer[106] = 0, tx_buffer[106] = 6a
neq! : rx_buffer[107] = 0, tx_buffer[107] = 6b
neq! : rx_buffer[108] = 0, tx_buffer[108] = 6c
neq! : rx_buffer[109] = 0, tx_buffer[109] = 6d
neq! : rx_buffer[110] = 0, tx_buffer[110] = 6e
neq! : rx_buffer[111] = 0, tx_buffer[111] = 6f
neq! : rx_buffer[112] = 0, tx_buffer[112] = 70
neq! : rx_buffer[113] = 0, tx_buffer[113] = 71
neq! : rx_buffer[114] = 0, tx_buffer[114] = 72
neq! : rx_buffer[115] = 0, tx_buffer[115] = 73
neq! : rx_buffer[116] = 0, tx_buffer[116] = 74
neq! : rx_buffer[117] = 0, tx_buffer[117] = 75
neq! : rx_buffer[118] = 0, tx_buffer[118] = 76
neq! : rx_buffer[119] = 0, tx_buffer[119] = 77
neq! : rx_buffer[120] = 0, tx_buffer[120] = 78
neq! : rx_buffer[121] = 0, tx_buffer[121] = 79
neq! : rx_buffer[122] = 0, tx_buffer[122] = 7a
neq! : rx_buffer[123] = 0, tx_buffer[123] = 7b
neq! : rx_buffer[124] = 0, tx_buffer[124] = 7c
neq! : rx_buffer[125] = 0, tx_buffer[125] = 7d
neq! : rx_buffer[126] = 0, tx_buffer[126] = 7e
neq! : rx_buffer[127] = 0, tx_buffer[127] = 7f
eq! : rx_buffer[128] = 80, tx_buffer[128] = 80
eq! : rx_buffer[129] = 81, tx_buffer[129] = 81
eq! : rx_buffer[130] = 82, tx_buffer[130] = 82
eq! : rx_buffer[131] = 83, tx_buffer[131] = 83
eq! : rx_buffer[132] = 84, tx_buffer[132] = 84
eq! : rx_buffer[133] = 85, tx_buffer[133] = 85
eq! : rx_buffer[134] = 86, tx_buffer[134] = 86
eq! : rx_buffer[135] = 87, tx_buffer[135] = 87
eq! : rx_buffer[136] = 88, tx_buffer[136] = 88
eq! : rx_buffer[137] = 89, tx_buffer[137] = 89
eq! : rx_buffer[138] = 8a, tx_buffer[138] = 8a
eq! : rx_buffer[139] = 8b, tx_buffer[139] = 8b
eq! : rx_buffer[140] = 8c, tx_buffer[140] = 8c
eq! : rx_buffer[141] = 8d, tx_buffer[141] = 8d
eq! : rx_buffer[142] = 8e, tx_buffer[142] = 8e
eq! : rx_buffer[143] = 8f, tx_buffer[143] = 8f
eq! : rx_buffer[144] = 90, tx_buffer[144] = 90
eq! : rx_buffer[145] = 91, tx_buffer[145] = 91
eq! : rx_buffer[146] = 92, tx_buffer[146] = 92
eq! : rx_buffer[147] = 93, tx_buffer[147] = 93
eq! : rx_buffer[148] = 94, tx_buffer[148] = 94
eq! : rx_buffer[149] = 95, tx_buffer[149] = 95
eq! : rx_buffer[150] = 96, tx_buffer[150] = 96
eq! : rx_buffer[151] = 97, tx_buffer[151] = 97
eq! : rx_buffer[152] = 98, tx_buffer[152] = 98
eq! : rx_buffer[153] = 99, tx_buffer[153] = 99
eq! : rx_buffer[154] = 9a, tx_buffer[154] = 9a
eq! : rx_buffer[155] = 9b, tx_buffer[155] = 9b
eq! : rx_buffer[156] = 9c, tx_buffer[156] = 9c
eq! : rx_buffer[157] = 9d, tx_buffer[157] = 9d
eq! : rx_buffer[158] = 9e, tx_buffer[158] = 9e
eq! : rx_buffer[159] = 9f, tx_buffer[159] = 9f
neq! : rx_buffer[160] = 0, tx_buffer[160] = a0
neq! : rx_buffer[161] = 0, tx_buffer[161] = a1
neq! : rx_buffer[162] = 0, tx_buffer[162] = a2
neq! : rx_buffer[163] = 0, tx_buffer[163] = a3
neq! : rx_buffer[164] = 0, tx_buffer[164] = a4
neq! : rx_buffer[165] = 0, tx_buffer[165] = a5
neq! : rx_buffer[166] = 0, tx_buffer[166] = a6
neq! : rx_buffer[167] = 0, tx_buffer[167] = a7
neq! : rx_buffer[168] = 0, tx_buffer[168] = a8
neq! : rx_buffer[169] = 0, tx_buffer[169] = a9
neq! : rx_buffer[170] = 0, tx_buffer[170] = aa
neq! : rx_buffer[171] = 0, tx_buffer[171] = ab
neq! : rx_buffer[172] = 0, tx_buffer[172] = ac
neq! : rx_buffer[173] = 0, tx_buffer[173] = ad
neq! : rx_buffer[174] = 0, tx_buffer[174] = ae
neq! : rx_buffer[175] = 0, tx_buffer[175] = af
neq! : rx_buffer[176] = 0, tx_buffer[176] = b0
neq! : rx_buffer[177] = 0, tx_buffer[177] = b1
neq! : rx_buffer[178] = 0, tx_buffer[178] = b2
neq! : rx_buffer[179] = 0, tx_buffer[179] = b3
neq! : rx_buffer[180] = 0, tx_buffer[180] = b4
neq! : rx_buffer[181] = 0, tx_buffer[181] = b5
neq! : rx_buffer[182] = 0, tx_buffer[182] = b6
neq! : rx_buffer[183] = 0, tx_buffer[183] = b7
neq! : rx_buffer[184] = 0, tx_buffer[184] = b8
neq! : rx_buffer[185] = 0, tx_buffer[185] = b9
neq! : rx_buffer[186] = 0, tx_buffer[186] = ba
neq! : rx_buffer[187] = 0, tx_buffer[187] = bb
neq! : rx_buffer[188] = 0, tx_buffer[188] = bc
neq! : rx_buffer[189] = 0, tx_buffer[189] = bd
neq! : rx_buffer[190] = 0, tx_buffer[190] = be
neq! : rx_buffer[191] = 0, tx_buffer[191] = bf
eq! : rx_buffer[192] = c0, tx_buffer[192] = c0
eq! : rx_buffer[193] = c1, tx_buffer[193] = c1
eq! : rx_buffer[194] = c2, tx_buffer[194] = c2
eq! : rx_buffer[195] = c3, tx_buffer[195] = c3
eq! : rx_buffer[196] = c4, tx_buffer[196] = c4
eq! : rx_buffer[197] = c5, tx_buffer[197] = c5
eq! : rx_buffer[198] = c6, tx_buffer[198] = c6
eq! : rx_buffer[199] = c7, tx_buffer[199] = c7
eq! : rx_buffer[200] = c8, tx_buffer[200] = c8
eq! : rx_buffer[201] = c9, tx_buffer[201] = c9
eq! : rx_buffer[202] = ca, tx_buffer[202] = ca
eq! : rx_buffer[203] = cb, tx_buffer[203] = cb
eq! : rx_buffer[204] = cc, tx_buffer[204] = cc
eq! : rx_buffer[205] = cd, tx_buffer[205] = cd
eq! : rx_buffer[206] = ce, tx_buffer[206] = ce
eq! : rx_buffer[207] = cf, tx_buffer[207] = cf
eq! : rx_buffer[208] = d0, tx_buffer[208] = d0
eq! : rx_buffer[209] = d1, tx_buffer[209] = d1
eq! : rx_buffer[210] = d2, tx_buffer[210] = d2
eq! : rx_buffer[211] = d3, tx_buffer[211] = d3
eq! : rx_buffer[212] = d4, tx_buffer[212] = d4
eq! : rx_buffer[213] = d5, tx_buffer[213] = d5
eq! : rx_buffer[214] = d6, tx_buffer[214] = d6
eq! : rx_buffer[215] = d7, tx_buffer[215] = d7
eq! : rx_buffer[216] = d8, tx_buffer[216] = d8
eq! : rx_buffer[217] = d9, tx_buffer[217] = d9
eq! : rx_buffer[218] = da, tx_buffer[218] = da
eq! : rx_buffer[219] = db, tx_buffer[219] = db
eq! : rx_buffer[220] = dc, tx_buffer[220] = dc
eq! : rx_buffer[221] = dd, tx_buffer[221] = dd
eq! : rx_buffer[222] = de, tx_buffer[222] = de
eq! : rx_buffer[223] = df, tx_buffer[223] = df
eq! : rx_buffer[224] = e0, tx_buffer[224] = e0
eq! : rx_buffer[225] = e1, tx_buffer[225] = e1
eq! : rx_buffer[226] = e2, tx_buffer[226] = e2
eq! : rx_buffer[227] = e3, tx_buffer[227] = e3
eq! : rx_buffer[228] = e4, tx_buffer[228] = e4
eq! : rx_buffer[229] = e5, tx_buffer[229] = e5
eq! : rx_buffer[230] = e6, tx_buffer[230] = e6
eq! : rx_buffer[231] = e7, tx_buffer[231] = e7
eq! : rx_buffer[232] = e8, tx_buffer[232] = e8
eq! : rx_buffer[233] = e9, tx_buffer[233] = e9
eq! : rx_buffer[234] = ea, tx_buffer[234] = ea
eq! : rx_buffer[235] = eb, tx_buffer[235] = eb
eq! : rx_buffer[236] = ec, tx_buffer[236] = ec
eq! : rx_buffer[237] = ed, tx_buffer[237] = ed
eq! : rx_buffer[238] = ee, tx_buffer[238] = ee
eq! : rx_buffer[239] = ef, tx_buffer[239] = ef
eq! : rx_buffer[240] = f0, tx_buffer[240] = f0
eq! : rx_buffer[241] = f1, tx_buffer[241] = f1
eq! : rx_buffer[242] = f2, tx_buffer[242] = f2
eq! : rx_buffer[243] = f3, tx_buffer[243] = f3
eq! : rx_buffer[244] = f4, tx_buffer[244] = f4
eq! : rx_buffer[245] = f5, tx_buffer[245] = f5
eq! : rx_buffer[246] = f6, tx_buffer[246] = f6
eq! : rx_buffer[247] = f7, tx_buffer[247] = f7
eq! : rx_buffer[248] = f8, tx_buffer[248] = f8
eq! : rx_buffer[249] = f9, tx_buffer[249] = f9
eq! : rx_buffer[250] = fa, tx_buffer[250] = fa
eq! : rx_buffer[251] = fb, tx_buffer[251] = fb
eq! : rx_buffer[252] = fc, tx_buffer[252] = fc
eq! : rx_buffer[253] = fd, tx_buffer[253] = fd
eq! : rx_buffer[254] = fe, tx_buffer[254] = fe
eq! : rx_buffer[255] = ff, tx_buffer[255] = ff
not equal!


vadimuzzz
в процессоре есть кэш данных?
AlexBalan
Да, есть : 4k instruction + 2k data.. Проблема с volatile........?
vadimuzzz
Цитата(AlexBalan @ Jun 22 2011, 20:29) *
Да, есть : 4k instruction + 2k data.. Проблема с volatile........?

возможно, это легко проверить - отключите кэш данных и сравните результаты
AlexBalan
Спасибо, проверю)
AlexBalan
to vadimuzzz

Большое Вам Спасибо!! Заработало!!!! 08.gif Поражен вашей проницательностью..! a14.gif
AlexBalan
Еще один вопрос: как обойти эту проблему, используя проц с кэшем? Пробовал volatile применить по отношению к буферам и указателям на них:

Код
    volatile byte* volatile tx_buffer = (volatile void* volatile)SRS_BUFF_BASE;
    volatile byte* volatile rx_buffer = (volatile void* volatile)DST_BUFF_BASE;
        // итп варианты


Но результат один и тот же..
vadimuzzz
надо вовремя кэш сбрасывать. см. Nios II Software Developer’s Handbook в сторону alt_dcache_flush() и подобных функций. возможно, есть перевод от nalivator (см. в шапке). volatile - это указание компилятору, чтобы он от некоторых оптимизаций воздержался. а в данном случае чисто процессорная фича, не баг.
AlexBalan
Еще раз благодарю sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.