MPC8308RM DMA
От: Harvat  
Дата: 22.04.19 13:23
Оценка:
Доброго времени суток.
Подскажите как правильно использовать DMA на этом звере(MPC8308).
Делаю так:
    pMPC8308_D    = (uint32_t*)mmap(0, 0x00100000, PROT_READ | PROT_WRITE , MAP_SHARED, hCPLD, CONFIG_SYS_IMMR);
    DMAC = (DMAC_str *)mmap(0, 0x001000, PROT_READ   MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset);
    TCD_ = (tcd_ctrl *)mmap(0, 0x001000, PROT_READ   | PROT_WRITE, MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset + 0x1000);

    char *pp = new char[100];
    memset(pp,0xFF,100);
    TCD_->daddr = CONFIG_SYS_IMMR + DMAC_str_Offset;
    TCD_->nbytes = 16;
    TCD_->citer.citer = TCD_->biter.biter = 1;
    TCD_->soff = 1;
    TCD_->attr.ssize = 0;
    TCD_->slast = 0;
    TCD_->saddr = (uint32_t)pp;
    TCD_->doff = 4;
    TCD_->attr.dsize = 2;
    TCD_->dlast_sga = -16;
    TCD_->ccr.int_maj = 1;
    TCD_->ccr.start = 1;

Но в итоге , по выполнению этого кода, массив "pp" никак не меняется. Что делаю не так??
Re: MPC8308RM DMA
От: Zhendos  
Дата: 22.04.19 13:55
Оценка:
Здравствуйте, Harvat, Вы писали:

H>Доброго времени суток.

H>Подскажите как правильно использовать DMA на этом звере(MPC8308).
H>Делаю так:
H>
H>    pMPC8308_D    = (uint32_t*)mmap(0, 0x00100000, PROT_READ | PROT_WRITE , MAP_SHARED, hCPLD, CONFIG_SYS_IMMR);
H>    DMAC = (DMAC_str *)mmap(0, 0x001000, PROT_READ   MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset);
H>    TCD_ = (tcd_ctrl *)mmap(0, 0x001000, PROT_READ   | PROT_WRITE, MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset + 0x1000);

H>    char *pp = new char[100];
H>    memset(pp,0xFF,100);
    TCD_->>daddr = CONFIG_SYS_IMMR + DMAC_str_Offset;
    TCD_->>nbytes = 16;
    TCD_->>citer.citer = TCD_->biter.biter = 1;
    TCD_->>soff = 1;
    TCD_->>attr.ssize = 0;
    TCD_->>slast = 0;
    TCD_->>saddr = (uint32_t)pp;
    TCD_->>doff = 4;
    TCD_->>attr.dsize = 2;
    TCD_->>dlast_sga = -16;
    TCD_->>ccr.int_maj = 1;
    TCD_->>ccr.start = 1;
H>

H>Но в итоге , по выполнению этого кода, массив "pp" никак не меняется. Что делаю не так??

Код довольно странный, вы работаете напрямую с железом или нет,
используете MMU или нет?

Судя по mmap используется виртуальная память и даже есть какая-то ОС или ее подобие,
тогда `TCD_->>saddr = (uint32_t)pp;` это какая-та фигня, DMA контролер обычно с физическими адресами
работает, почему ему виртуальный адрес передается, плюс вы уверены что выделенный блок с помощью new
имеет правильно выравнивание? Плюс где "volatile"? Как компилятор поймет что все эти чтения и записи
в память не стоит оптимизировать иными словами переупорядочить, половину выкинуть как ненужные и т.п.?
Re[2]: MPC8308RM DMA
От: Harvat  
Дата: 23.04.19 04:37
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, Harvat, Вы писали:


H>>Доброго времени суток.

H>>Подскажите как правильно использовать DMA на этом звере(MPC8308).
H>>Делаю так:
H>>
H>>    pMPC8308_D    = (uint32_t*)mmap(0, 0x00100000, PROT_READ | PROT_WRITE , MAP_SHARED, hCPLD, CONFIG_SYS_IMMR);
H>>    DMAC = (DMAC_str *)mmap(0, 0x001000, PROT_READ   MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset);
H>>    TCD_ = (tcd_ctrl *)mmap(0, 0x001000, PROT_READ   | PROT_WRITE, MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset + 0x1000);

H>>    char *pp = new char[100];
H>>    memset(pp,0xFF,100);
    TCD_->>>daddr = CONFIG_SYS_IMMR + DMAC_str_Offset;
    TCD_->>>nbytes = 16;
    TCD_->>>citer.citer = TCD_->biter.biter = 1;
    TCD_->>>soff = 1;
    TCD_->>>attr.ssize = 0;
    TCD_->>>slast = 0;
    TCD_->>>saddr = (uint32_t)pp;
    TCD_->>>doff = 4;
    TCD_->>>attr.dsize = 2;
    TCD_->>>dlast_sga = -16;
    TCD_->>>ccr.int_maj = 1;
    TCD_->>>ccr.start = 1;
H>>

H>>Но в итоге , по выполнению этого кода, массив "pp" никак не меняется. Что делаю не так??

Z>Код довольно странный, вы работаете напрямую с железом или нет,

Z>используете MMU или нет?

Z>Судя по mmap используется виртуальная память и даже есть какая-то ОС или ее подобие,

Z>тогда `TCD_->>saddr = (uint32_t)pp;` это какая-та фигня, DMA контролер обычно с физическими адресами
Z>работает, почему ему виртуальный адрес передается, плюс вы уверены что выделенный блок с помощью new
Z>имеет правильно выравнивание? Плюс где "volatile"? Как компилятор поймет что все эти чтения и записи
Z>в память не стоит оптимизировать иными словами переупорядочить, половину выкинуть как ненужные и т.п.?

Да, работаю напрямую с железом. Стоит там Power PC e300 с урезанным линуксом.
MMU не использую.
volatile попробовал, но ничего не изменилось.
Собственно до этого я с DMA не работал, но примеров по этому MPC8308RM найти не удалось.
По этому и спросил тут.
Может у кого пример есть....
Re[3]: MPC8308RM DMA
От: Zhendos  
Дата: 23.04.19 10:53
Оценка:
Здравствуйте, Harvat, Вы писали:

H>Здравствуйте, Zhendos, Вы писали:


Z>>Здравствуйте, Harvat, Вы писали:


H>>>Доброго времени суток.

H>>>Подскажите как правильно использовать DMA на этом звере(MPC8308).
H>>>Делаю так:
H>>>
H>>>    pMPC8308_D    = (uint32_t*)mmap(0, 0x00100000, PROT_READ | PROT_WRITE , MAP_SHARED, hCPLD, CONFIG_SYS_IMMR);
H>>>    DMAC = (DMAC_str *)mmap(0, 0x001000, PROT_READ   MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset);
H>>>    TCD_ = (tcd_ctrl *)mmap(0, 0x001000, PROT_READ   | PROT_WRITE, MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset + 0x1000);

H>>>    char *pp = new char[100];
H>>>    memset(pp,0xFF,100);
    TCD_->>>>daddr = CONFIG_SYS_IMMR + DMAC_str_Offset;
    TCD_->>>>nbytes = 16;
    TCD_->>>>citer.citer = TCD_->biter.biter = 1;
    TCD_->>>>soff = 1;
    TCD_->>>>attr.ssize = 0;
    TCD_->>>>slast = 0;
    TCD_->>>>saddr = (uint32_t)pp;
    TCD_->>>>doff = 4;
    TCD_->>>>attr.dsize = 2;
    TCD_->>>>dlast_sga = -16;
    TCD_->>>>ccr.int_maj = 1;
    TCD_->>>>ccr.start = 1;
H>>>

H>>>Но в итоге , по выполнению этого кода, массив "pp" никак не меняется. Что делаю не так??

Z>>Код довольно странный, вы работаете напрямую с железом или нет,

Z>>используете MMU или нет?

Z>>Судя по mmap используется виртуальная память и даже есть какая-то ОС или ее подобие,

Z>>тогда `TCD_->>saddr = (uint32_t)pp;` это какая-та фигня, DMA контролер обычно с физическими адресами
Z>>работает, почему ему виртуальный адрес передается, плюс вы уверены что выделенный блок с помощью new
Z>>имеет правильно выравнивание? Плюс где "volatile"? Как компилятор поймет что все эти чтения и записи
Z>>в память не стоит оптимизировать иными словами переупорядочить, половину выкинуть как ненужные и т.п.?

H>Да, работаю напрямую с железом. Стоит там Power PC e300 с урезанным линуксом.

H>MMU не использую.
H>volatile попробовал, но ничего не изменилось.

Надеюсь понятно, что volatile нужен для всего не только для "pp", но и для работы с "DMAC",
TCD и т.д., посмотрите как например драйверы Linux написаны, макросы writel/readl,
и работайте только через них.
Плюс ведь есть еще кэш процессора, он учитывается когда вы проверяете,
что ничего не изменилось? DMA обычно пишет мимо кэша, и нужно "форсировать" чтение из памяти,
вместо кэша. Опять в исходниках Linux есть примеры.
Ну еще для некоторых IP блоков нужно включить питание, с помощью записи в какой-нибудь регистр,
так как по умолчанию они выключены.

H>Собственно до этого я с DMA не работал, но примеров по этому MPC8308RM найти не удалось.


А зачем собственно по-нему искать, обычно у всего семейства похожие IP блоки с очень похожим
расположением регистров,
см. например

https://github.com/search?l=C&q=MPC8308+dma&type=Code

куча же примеров?
Re[4]: MPC8308RM DMA
От: Harvat  
Дата: 23.04.19 12:50
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>Здравствуйте, Harvat, Вы писали:


H>>Здравствуйте, Zhendos, Вы писали:


Z>>>Здравствуйте, Harvat, Вы писали:


H>>>>Доброго времени суток.

H>>>>Подскажите как правильно использовать DMA на этом звере(MPC8308).
H>>>>Делаю так:
H>>>>
H>>>>    pMPC8308_D    = (uint32_t*)mmap(0, 0x00100000, PROT_READ | PROT_WRITE , MAP_SHARED, hCPLD, CONFIG_SYS_IMMR);
H>>>>    DMAC = (DMAC_str *)mmap(0, 0x001000, PROT_READ   MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset);
H>>>>    TCD_ = (tcd_ctrl *)mmap(0, 0x001000, PROT_READ   | PROT_WRITE, MAP_SHARED, hCPLD, CONFIG_SYS_IMMR + DMAC_str_Offset + 0x1000);

H>>>>    char *pp = new char[100];
H>>>>    memset(pp,0xFF,100);
    TCD_->>>>>daddr = CONFIG_SYS_IMMR + DMAC_str_Offset;
    TCD_->>>>>nbytes = 16;
    TCD_->>>>>citer.citer = TCD_->biter.biter = 1;
    TCD_->>>>>soff = 1;
    TCD_->>>>>attr.ssize = 0;
    TCD_->>>>>slast = 0;
    TCD_->>>>>saddr = (uint32_t)pp;
    TCD_->>>>>doff = 4;
    TCD_->>>>>attr.dsize = 2;
    TCD_->>>>>dlast_sga = -16;
    TCD_->>>>>ccr.int_maj = 1;
    TCD_->>>>>ccr.start = 1;
H>>>>

H>>>>Но в итоге , по выполнению этого кода, массив "pp" никак не меняется. Что делаю не так??

Z>>>Код довольно странный, вы работаете напрямую с железом или нет,

Z>>>используете MMU или нет?

Z>>>Судя по mmap используется виртуальная память и даже есть какая-то ОС или ее подобие,

Z>>>тогда `TCD_->>saddr = (uint32_t)pp;` это какая-та фигня, DMA контролер обычно с физическими адресами
Z>>>работает, почему ему виртуальный адрес передается, плюс вы уверены что выделенный блок с помощью new
Z>>>имеет правильно выравнивание? Плюс где "volatile"? Как компилятор поймет что все эти чтения и записи
Z>>>в память не стоит оптимизировать иными словами переупорядочить, половину выкинуть как ненужные и т.п.?

H>>Да, работаю напрямую с железом. Стоит там Power PC e300 с урезанным линуксом.

H>>MMU не использую.
H>>volatile попробовал, но ничего не изменилось.

Z>Надеюсь понятно, что volatile нужен для всего не только для "pp", но и для работы с "DMAC",

Z>TCD и т.д., посмотрите как например драйверы Linux написаны, макросы writel/readl,
Z>и работайте только через них.
Z>Плюс ведь есть еще кэш процессора, он учитывается когда вы проверяете,
Z>что ничего не изменилось? DMA обычно пишет мимо кэша, и нужно "форсировать" чтение из памяти,
Z>вместо кэша. Опять в исходниках Linux есть примеры.
Z>Ну еще для некоторых IP блоков нужно включить питание, с помощью записи в какой-нибудь регистр,
Z>так как по умолчанию они выключены.

H>>Собственно до этого я с DMA не работал, но примеров по этому MPC8308RM найти не удалось.


Z>А зачем собственно по-нему искать, обычно у всего семейства похожие IP блоки с очень похожим

Z>расположением регистров,
Z>см. например

Z>https://github.com/search?l=C&q=MPC8308+dma&type=Code


Z>куча же примеров?



Да
static volatile DMAC_str *DMAC;
static volatile tcd_ctrl *TCD_;
Спасибо, буду там искать
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.