Multi-master система или «черная пятница»

DSCN6115

Уже в четырех записях я упомянул чудесный параллельный интерфейс EBI. Он идентичен, что у STM32, что у ATSAM. Некоторые называют интерфейс асинхронным, но это не так: отсутствует лишь порт тактовой частоты, однако периферии на этот счет хватает.

 

 

Суть вопроса?

МК — управляющий, а все остальные — подчиненные.

В своих проектах я сталкивался с низкой скоростью передачи данных между двумя устройствами, ввиду отсутствия всякого DMA и буфера внутри контроллера.

Ashampoo_Snap_2015.04.20_15h58m46s_001_

 

Это будет долго, в любом случае. Почему бы не соорудить на ПЛИС внешний DMA контроллер? Ко всему прочему будет возможность развить его во что-то большее, чем простой пересыльщик. Здесь всплывают следующие проблемы:

  • У МК нету средства отсоединения от передающей шины, когда ее использует DMA. Произойдут короткие замыкания.
  • Кто и как будет решать, чью шина?
  • Как передавать данные «пересыльщику»?

Мы приходим к системе с двумя управляющими (Master) или ее называют Multi-master системой.

Ashampoo_Snap_2015.04.20_16h26m01s_002_

Микроконтроллер может также свободно работать с шиной, отдавать команды DMA для пересылок и автоматически отключаться от шины. Все конфликты урегулируются новым блоком — Арбитр.

Арбитр

Независимое устройство, которое всеми силами пытается избежать ситуации, когда два управляющих подключаются к шине одновременно. Здесь его задача проста:

  1. Не пускать DMA в шину, пока с ней работает МК.
  2. Не пускать МК в шину, пока с ней работает DMA.

У обоих есть для этого специальные сигналы типа WAIT (подожди!). Отдельная ситуации — это когда контроллер будет передавать данные контроллеру пересылок.

Ворота

Для того, чтобы переключать линии между устройствами необходимо что-то в роде мультиплексора. Да! Но в нашем случае необходим двунаправленный и четырехпортовый.

Ashampoo_Snap_2015.04.20_16h51m36s_003_

Необходима микросхема с параметром tpd < 7ns, иначе образуется слишком большая латентность.

Реализация 

Ниже представлены многоплатная система, состоящая из: ATSAM4C (МК), EP1C3 (ПЛИС), Арбитр (кучка логики и FET) и внешние модули: видеопроцессор и память.

DSCN612177777s

Демонстрация

Наглядное переключение шин, при захвате DMA. Прошу прощения за помехи.

Пример использования в качестве усовершенствованного DMA с некоторыми графическими функциями.

Все картинки (спрайты) хранятся в модуле внешней памяти, куда их загружает микроконтроллер при старте.

Почему «черная пятница»?

Из-за сбоя в питании, естественно по моей вине, вся система целиком и полностью сгорела. Резкий запах пластмассы дал понять, что это был последний эксперимент. В связи с этим, я не могу продолжать  цикл обучающих статей по ARM Cortex-M4, увы. Это также касается FPGA.

Вы можите оставить комментарий, или поставить трэкбек со своего сайта.

Есть 1 комментарий. к “Multi-master система или «черная пятница»”

  1. Оставлю это здесь. Исходный код ATSAM4C:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    
    /*
     * BlinkApp.cpp
     *
     * Created: 27.05.2014 9:35:41
     *  Author: Кирилл
     */ 
     
    #include "sam.h"
     
    #include "sys/types.h"
    #include <string.h>
    #include <stdlib.h>
    #include "bmp.h"       //Набор тайлов
    #include "ebi.h"
    #include "matilda.h"
    #include "memcpy.c"
    #include <stdio.h>
    #include <tgmath.h>
     
    #define SCREEN_W 288
    #define SCREEN_H 208
     
    uint8_t *external_ram = (uint8_t*)EBI_CS2_ADDR;    //Внешняя память
    uint8_t *video_ram = (uint8_t*)EBI_CS1_ADDR;       //Видео память (ГПУ)
    uint8_t *dma_ = (uint8_t*)EBI_CS1_ADDR + 65536;    //Контроллер на FPGA
     
    bool rw_test(uint8_t* c) {  //Тест чтения и записи
    	uint8_t mass[2048];
     
    	for (int i=0; i<sizeof(mass); ++i) mass[i] = rand()%256;
    	memcpy(c, mass, sizeof(mass));
    	for (int i=0; i<sizeof(mass); ++i) {
    		if (mass[i]!=c[i]) return false;
    	}
     
    	return true;
    }
     
    typedef struct {
    	float r;
    	float angle;
    	float delta;
    	bool dir;
     
    	unsigned char id;
    } sprite;
     
    sprite mass[64];
    volatile int pre_init = 0;
     
     
    int main(void)
    {
        /* Initialize the SAM system */
        SystemInit();
     
    	PMC->PMC_WPMR = 0x504D43;
    	system_init_flash(177000000);
    	PMC->CKGR_MOR = CKGR_MOR_MOSCXTEN;
    	PMC->CKGR_PLLAR = CKGR_PLLAR_PLLACOUNT(0) | CKGR_PLLAR_PLLAEN(0);
    	PMC->CKGR_PLLAR = CKGR_PLLAR_MULA(249) | CKGR_PLLAR_PLLAEN(1);
    	PMC->CKGR_PLLBR = CKGR_PLLBR_PLLBCOUNT(0);
    	PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(8) | CKGR_PLLBR_DIVB(1) | CKGR_PLLBR_SRCB_PLLA_IN_PLLB;
    	PMC->PMC_MCKR = PMC_PCK_CSS_PLLB_CLK | PMC_PCK_PRES_CLK_1;
    	SystemCoreClockUpdate();
     
    	PMC->PMC_PCK[2] = PMC_PCK_CSS_MCK | PMC_PCK_PRES_CLK_1; 
    	PMC->PMC_SCER = PMC_SCER_PCK2; 
     
    	PMC->PMC_PCER0 = PMC_PCER0_PID10 | PMC_PCER0_PID12 | PMC_PCER0_PID23 | PMC_PCER0_PID24 | PMC_PCER0_PID11;
     
    	initPIO();
     
    	SMC0->SMC_WPMR = 0x534D43;
     
    	SMC0->SMC_CS_NUMBER[1].SMC_CYCLE = SMC_CYCLE_NRD_CYCLE(4) | SMC_CYCLE_NWE_CYCLE(2);
    	SMC0->SMC_CS_NUMBER[1].SMC_PULSE = SMC_PULSE_NCS_RD_PULSE(3) | SMC_PULSE_NCS_WR_PULSE(1) | SMC_PULSE_NRD_PULSE(3) | SMC_PULSE_NWE_PULSE(1);
    	SMC0->SMC_CS_NUMBER[1].SMC_SETUP = SMC_SETUP_NCS_RD_SETUP(0) | SMC_SETUP_NCS_WR_SETUP(0) | SMC_SETUP_NRD_SETUP(0) | SMC_SETUP_NWE_SETUP(0);
    	SMC0->SMC_CS_NUMBER[1].SMC_MODE = SMC_MODE_DBW_8_BIT | SMC_MODE_WRITE_MODE | SMC_MODE_READ_MODE | SMC_MODE_EXNW_MODE_FROZEN;
     
    	SMC0->SMC_CS_NUMBER[2].SMC_CYCLE = SMC_CYCLE_NRD_CYCLE(4) | SMC_CYCLE_NWE_CYCLE(2);
    	SMC0->SMC_CS_NUMBER[2].SMC_PULSE = SMC_PULSE_NCS_RD_PULSE(3) | SMC_PULSE_NCS_WR_PULSE(1) | SMC_PULSE_NRD_PULSE(3) | SMC_PULSE_NWE_PULSE(1);
    	SMC0->SMC_CS_NUMBER[2].SMC_SETUP = SMC_SETUP_NCS_RD_SETUP(0) | SMC_SETUP_NCS_WR_SETUP(0) | SMC_SETUP_NRD_SETUP(0) | SMC_SETUP_NWE_SETUP(0);
    	SMC0->SMC_CS_NUMBER[2].SMC_MODE = SMC_MODE_DBW_8_BIT | SMC_MODE_WRITE_MODE | SMC_MODE_READ_MODE | SMC_MODE_EXNW_MODE_FROZEN;
     
    	if (!rw_test(external_ram)) while(1); //Проходим тест чтения/записи
    	memcpy_(external_ram, tiles, 32*320); //Загружаем набор тайлов во внешнюю память
     
    	 for (int i = 0; i < 30; i++) {
    		  mass[i].r = rand()%80;
     
    		  int a = rand()%6284;
     
    		  mass[i].angle = a/1000;
    		  mass[i].delta = 0.0314 + (rand()%100 - 50)/850;
    		  mass[i].dir = bool(rand()%2);
    		  mass[i].id = rand()%10;
    	 }
     
    	PIOA->PIO_AIMER = PIO_AIMER_P15;      //Прерывание от ГПУ
    	PIOA->PIO_ESR = PIO_ESR_P15;
    	PIOA->PIO_REHLSR = PIO_REHLSR_P15;
    	PIOA->PIO_IER = PIO_IER_P15;
     
    	pre_init = 0;
    	NVIC_EnableIRQ(PIOA_IRQn);
     
    	while(true) {
    		//Nothing
    	}
    }
     
    float rx;
    float ry;
     
    void ro(sprite* g) {
    	rx = cos(g->angle)*g->r - sin(g->angle)*g->r;
    	ry = sin(g->angle)*g->r + cos(g->angle)*g->r;
     
    	if (g->dir)
    		g->angle+=g->delta;
    	else
    		g->angle-=g->delta;
     
    	uint8_t packet[6]; uint16_t xx16, yy16; 
    	//Готовим пакет данных для DMA (FPGA)
     
    	packet[0] = 0x44; //Magic 'D' (DMA)
     
    	xx16 = int(rx+130);
    	yy16 = int(ry+92);
    	//XY
    	packet[1] = (xx16 >> 8) & 0xFF;
    	packet[2] = xx16 & 0xFF;
    	packet[3] = (yy16 >> 8) & 0xFF;
    	packet[4] = yy16 & 0xFF;
    	//Tile id
    	packet[5] = g->id;
    	//FixMe 0x44
    	for (int i=1; i<6; ++i)
    	  if (packet[i]==0x44) packet[i]+=1;
     
    	memcpy_(dma_, packet, sizeof(packet));
    }
     
    void PIOA_Handler() {	
    	if (PIOA->PIO_ISR & PIO_ISR_P15) { //Конец текущего кадра
    		if (pre_init<2) {
    			memcpy_(video_ram+59904, tiles+10240, 768);    //Загружаем палитру
    		} else if (pre_init<3) {
    			memset(video_ram, 0, 59904/2);	
    		} else if (pre_init<4) {
    			memset(video_ram+59904/2, 0, 59904/2);		   //Очищаем экран
    		} else if (pre_init<5) {
    			for (int i=0; i<10; ++i) ro(&mass[i]); //Отправляем запросы DMA
    		//} else if (pre_init<300) {		
    		} else if (pre_init>137) {
    			for (int i=0; i<10; ++i) ro(&mass[i]); //Отправляем запросы DMA
    		}
     
    		pre_init++;	
     
    	}
    }

    Thumb up 1 Thumb down 0

Написать комментарий

XHTML: Вы можете использовать эти теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Bug Report
Локализовано: шаблоны Wordpress