для проверки работы 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);
}
вот такая функция транзакции пакета{
/* 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 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]);
}
}
вот такой главный цикл
Код
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;
}
{
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 ни после записи туда инкремента.
получается, что либо не инициализируется память, либо не пишется, а вообще и то и другое

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!!!
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?