Перейти к содержанию
    

сборка usb модуля(*.ko) под самодельное устройство на (st91sam7s256) - вот я и заткнулся!!!

Устройство должно подключаться по USB к raspberry 3. Для платы(at91sam7s256 от olimex). Драйвер боьирается на основе usb-skeleton.c на самой малине. Загружается, регистрируется устройство, работает запись в устройство (оно в /dev есть при подключении), но вот чтение не работает. Для доступа к устройству написан тест на Си. Всё запускается. Но вот точка отстановки на чтение в Keil не активируется ни тут:

Spoiler
//--- фрагмент из usbuser.c

/*
 *  USB Endpoint 1 Event Callback
 *   Called automatically on USB Endpoint 1 Event
 *    Parameter:       event
 */

//тут передаём малине
void USB_EndPoint1 (DWORD event) {
	//GetInReport();
  USB_WriteEP(USB_ENDPOINT_IN(1), &InReport[0], sizeof(_sz_report));
}


/*
 *  USB Endpoint 2 Event Callback
 *   Called automatically on USB Endpoint 2 Event
 *    Parameter:       event
 */
//тут принимаем от малины точка остановки срабатывает
void USB_EndPoint2 (DWORD event) {
	DWORD cnt;
	cnt = USB_ReadEP(USB_ENDPOINT_OUT(2), &OutReport[0]);
	if(cnt > 0) SetOutReport(cnt);
}

 

ни тут:

Spoiler
//фрагмент из usbhw.c  

/* Endpoint Interrupts */
    for (n = 0; n < USB_EP_NUM; n++) {
      if (isr & (1 << n)) {

        csr = pUDP->UDP_CSR[n]; //тут срабатывет точка остановки при подключении устройства и приеме от малмны

        /* Setup Packet Received Interrupt */
        if (csr & AT91C_UDP_RXSETUP) {
          if (USB_P_EP[n]) {
            USB_P_EP[n](USB_EVT_SETUP);
          }
          /* Setup Flag is already cleared in USB_DirCtrlEP */
          /* pUDP->UDP_CSR[n] &= ~AT91C_UDP_RXSETUP; */
        }

 

между тем lsusb на малине(вроде нормально - устройство т.е. дескрипторы сделаны по аналогии от USB-WIFI):

Spoiler
Bus 001 Device 038: ID d362:2312  
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0xd362 
  idProduct          0x2312 
  bcdDevice            1.00
  iManufacturer           4 
  iProduct               32 
  iSerial                66 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              32

 

Вот дескриптор(ы) устройства в Keil:

Spoiler
/* USB Standard Device Descriptor */
const BYTE USB_DeviceDescriptor[] = {
  USB_DEVICE_DESC_SIZE,              /* bLength */
  USB_DEVICE_DESCRIPTOR_TYPE,        /* bDescriptorType */
  WBVAL(0x0110), /* 1.10 */          /* bcdUSB */
  0x00,                              /* bDeviceClass */
  0x00,                              /* bDeviceSubClass */
  0x00,                              /* bDeviceProtocol */
  USB_MAX_PACKET0,                   /* bMaxPacketSize0 */
  WBVAL(0xD362),                     /* idVendor */
  WBVAL(0x2312),                     /* idProduct */
  WBVAL(0x0100), /* 1.00 */          /* bcdDevice */
  0x04,                              /* iManufacturer */
  0x20,                              /* iProduct */
  0x42,                              /* iSerialNumber */
  0x01                               /* bNumConfigurations */
};

/* USB Configuration Descriptor */
/*   All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */
const BYTE USB_ConfigDescriptor[] = {
/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
  WBVAL(                             /* wTotalLength */
    USB_CONFIGUARTION_DESC_SIZE +
    USB_INTERFACE_DESC_SIZE     +
    //HID_DESC_SIZE               +
    USB_ENDPOINT_DESC_SIZE			+
		USB_ENDPOINT_DESC_SIZE
  ),
  0x01,                              /* bNumInterfaces */
  0x01,                              /* bConfigurationValue */
  0x00,                              /* iConfiguration */
  USB_CONFIG_BUS_POWERED /*|*/       /* bmAttributes */
/*USB_CONFIG_REMOTE_WAKEUP*/,
  USB_CONFIG_POWER_MA(100),          /* bMaxPower */

/* Interface 0, Alternate Setting 0, HID Class */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
  0x00,                              /* bInterfaceNumber */
  0x00,                              /* bAlternateSetting */
  0x02,                              /* bNumEndpoints */
  USB_DEVICE_CLASS_VENDOR_SPECIFIC, //USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
  0xFF, //HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
  0xFF, //HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
  0x00, //0x5C,                              /* iInterface */

/* HID Class Descriptor */
/* HID_DESC_OFFSET = 0x0012 */
//  HID_DESC_SIZE,                     /* bLength */
//  HID_HID_DESCRIPTOR_TYPE,           /* bDescriptorType */
//  WBVAL(0x0100), /* 1.00 */          /* bcdHID */
//  0x00,                              /* bCountryCode */
//  0x02,                              /* bNumDescriptors */
//  USB_DEVICE_CLASS_VENDOR_SPECIFIC, //HID_REPORT_DESCRIPTOR_TYPE,        /* bDescriptorType */
//  WBVAL(HID_REPORT_DESC_SIZE),       /* wDescriptorLength */

/* Endpoint, HID Interrupt In */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(1),                /* bEndpointAddress */
  //USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
	USB_ENDPOINT_TYPE_BULK,
  WBVAL(_sz_report),                     /* wMaxPacketSize (было 4 стало 64*/
  0x20,          /* 32ms */          /* bInterval */
/* Endpoint, HID Interrupt Out */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(2),                /* bEndpointAddress */
  //USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
	USB_ENDPOINT_TYPE_BULK,
  WBVAL(_sz_report),                     /* wMaxPacketSize (было 4 стало 64*/
  0x20,          /* 32ms */          /* bInterval */
/* Terminator */
  0                                  /* bLength */
};

/* USB String Descriptor (optional) */
const BYTE USB_StringDescriptor[] = {
/* Index 0x00: LANGID Codes */
  0x04,                              /* bLength */
  USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
  WBVAL(0x0409), /* US English */    /* wLANGID */
/* Index 0x04: Manufacturer */
  0x1C,                              /* bLength */
  USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
  'S',0,
  'e',0,
  'r',0,
  'v',0,
  'o',0,
  'A',0,
  'n',0,
  'd',0,
  'M',0,
  'o',0,
  't',0,
  'o',0,
  'r',0,
/* Index 0x20: Product */
  0x22,                              /* bLength */
  USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
  'D',0,
  'e',0,
  'v',0,
  ' ',0,
  'f',0,
  'o',0,
  'r',0,
  ' ',0,
  'B',0,
  'o',0,
  't',0,
  'G',0,
  'r',0,
  'a',0,
  'y',0,
  ' ',0,
/* Index 0x42: Serial Number */
  0x1A,                              /* bLength */
  USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '0',0,
  '.',0,
  '0',0,
  '0',0,
  '.',0,
  '0',0,
  '1',0,
/* Index 0x5C: Interface 0, Alternate Setting 0 */
  0x0C,                              /* bLength */
  USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
  'v',0,
  'e',0,
  'n',0,
	'd',0,
	'.',0,
};

 

Косоль тестовой прграммы:

Spoiler

root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release# ./samhid --default --testrd
Starting samhid...
Test чтения из устройства (/dev/samhid0): открытие...
Test чтения из устройства : открытие res=0
Test чтения из устройства : чтение...
^C
root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release# ./samhid --default --testrd
Starting samhid...
Test чтения из устройства (/dev/samhid0): открытие...
Test чтения из устройства : открытие res=0
Test чтения из устройства : чтение...
^C^C
root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release# ./samhid --default --testwr
Starting samhid...
Test записи в устройство (/dev/samhid0): открытие...
Test записи в устройство : открытие res=0

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F

Test записи в устройство : звпись...
Test записи в устройство : звпись res=64
Test записи в устройство : закрытие
root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release#

 

вот dmesg  (на малинее - в драйвере я намусорил для отладки):

Spoiler

Функция: samhid_probe..
[20308.877894] samhip_probe: step 1 ...
[20308.877903] samhip_probe: step 2 ...
[20308.877913] samhip_probe: ENDPOINTS : 2  ...
[20308.877920] samhip_probe step LOOP: ...
[20308.877929] samhip_probe loop=0  ...
[20308.877938] samhip_probe endoint[0]: bLength=7
[20308.877948] samhip_probe endoint[0]: bDescriptorType=5
[20308.877957] samhip_probe endoint[0]: bEndpointAddress=01(hex) (IN)
[20308.877967] samhip_probe endoint[0]: bmAttributes=02(hex)
[20308.877977] samhip_probe endoint[0]: wMaxPacketSize=64(bytes)
[20308.877986] samhip_probe endoint[0]: bInterval=32
[20308.877994] -- samhip_probe : we found a bulk in endpoint
[20308.878004] -- samhip_probe : dev->bulk_in_endpointAddr=81
[20308.878013] -- samhip_probe : dev->bulk_out_endpointAddr=00
[20308.878021] samhip_probe loop=1  ...
[20308.878031] samhip_probe endoint[1]: bLength=7
[20308.878043] samhip_probe endoint[1]: bDescriptorType=5
[20308.878052] samhip_probe endoint[1]: bEndpointAddress=02(hex) (OUT)
[20308.878061] samhip_probe endoint[1]: bmAttributes=02(hex)
[20308.878071] samhip_probe endoint[1]: wMaxPacketSize=64(bytes)
[20308.878080] samhip_probe endoint[1]: bInterval=32
[20308.878088] -- samhip_probe : we found a bulk out endpoint
[20308.878097] -- samhip_probe : dev->bulk_in_endpointAddr=81
[20308.878106] -- samhip_probe : dev->bulk_out_endpointAddr=02
[20308.878114] samhip_probe step 3 ...
[20308.878122] samhip_probe : bulk_in_endpointAddr=1
[20308.878130] samhip_probe : bulk_out_endpointAddr=2
[20308.878437] samhid 1-1.3:1.0: USB samhid device now attached to USBsamhid-192
[20308.878578] usbcore: registered new interface driver samhid
[20319.772550]
Функция: samhid_open..
[20319.772756]
Функция: samhid_read..
[20319.772862] samhid_read : step 1
[20319.772873] samhid_read : bulk_in_size=64
[20319.772882] samhid_read : bulk_in_endpointAddr=1
[20319.772909] samhid_read : count=64
[20319.772916] samhid_read : step 2
[20319.772924] samhid_read : count=64
[20319.772942] samhid_read : step 3
[20319.772951] samhid_read : count=64
[20319.772970] samhid_read : rv=0
[20319.773012] samhid_read : step 10
[20319.773038] samhid_read : count=64
[20319.773046] samhid_read : call -> samhid_do_read_io
[20319.773055]
Функция: samhid_do_read_io..
[20319.773065] samhid_do_read_io step 1 ...
[20319.773074] samhid_do_read_io bulk_in_endpointAddr=1
[20319.773083] samhid_do_read_io count=64
[20319.773091] samhid_do_read_io dev->bulk_in_size=64
[20319.773100] samhid_do_read_io step 2 ...
[20319.773968] samhid_do_read_io step 3 ...
[20319.773982] ---!!! samhid_do_read_io: Ok!
[20319.773992] samhid_do_read_io : END rv=0
[20319.774000] samhid_read : step 11
[20319.774008] samhid_read : rv=0
[20319.774015] samhid_read : goto retry
[20319.774023] samhid_read : step 4
[20319.774032] samhid_read : dev->bulk_in_wait=0
[20369.145714]
Функция: samhid_flush..
[20369.145741]
Функция: samhid_draw_down..
[20369.145768]
Функция: samhid_read_bulk_callback..
[20369.145802]
Функция: samhid_release..
[22963.928271]
Функция: samhid_open..
[22963.928421]
Функция: samhid_read..
[22963.928434] samhid_read : step 1
[22963.928443] samhid_read : bulk_in_size=64
[22963.928454] samhid_read : bulk_in_endpointAddr=1
[22963.928462] samhid_read : count=64
[22963.928470] samhid_read : step 2
[22963.928478] samhid_read : count=64
[22963.928486] samhid_read : step 3
[22963.928494] samhid_read : count=64
[22963.928502] samhid_read : rv=0
[22963.928510] samhid_read : step 10
[22963.928518] samhid_read : count=64
[22963.928526] samhid_read : call -> samhid_do_read_io
[22963.928534]
Функция: samhid_do_read_io..
[22963.928545] samhid_do_read_io step 1 ...
[22963.928553] samhid_do_read_io bulk_in_endpointAddr=1
[22963.928562] samhid_do_read_io count=64
[22963.928571] samhid_do_read_io dev->bulk_in_size=64
[22963.928580] samhid_do_read_io step 2 ...
[22963.928625] samhid_do_read_io step 3 ...
[22963.928634] ---!!! samhid_do_read_io: Ok!
[22963.928643] samhid_do_read_io : END rv=0
[22963.928650] samhid_read : step 11
[22963.928658] samhid_read : rv=0
[22963.928666] samhid_read : goto retry
[22963.928674] samhid_read : step 4
[22963.928682] samhid_read : dev->bulk_in_wait=196611
[22971.121470]
Функция: samhid_flush..
[22971.121497]
Функция: samhid_draw_down..
[22971.121522]
Функция: samhid_read_bulk_callback..
[22971.121556]
Функция: samhid_release..
[22979.609327]
Функция: samhid_open..
[22979.609623]
Функция: samhid_write..
[22979.609636] samhid_write : step 1
[22979.609646] -- samhid_write : dev->bulk_out_endpointAddr=2
[22979.609655] -- samhid_write : dev->bulk_out_size=64
[22979.609664] -- samhid_write : count=64
[22979.609671] samhid_write : step 2
[22979.609680] samhid_write : step 3
[22979.609693] samhid_write : step 4
[22979.609743] samhid_write : step 5...
[22979.609756] samhid_write : writesize=64
[22979.609768]
Функция: samhid_flush..
[22979.609780]
Функция: samhid_draw_down..
[22979.609877]
Функция: samhid_write_bulk_callback..
[22979.609925]
Функция: samhid_release..
igor@pi01:~ $

 

драйвер samhid.ko собран на сонове usb-skeleton.c. Если с записью в /dev/samhid0 всё нормально, то чтение - беда. Если надо подробнее - попробую через yndex.disk

Изменено пользователем Igor68

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот испытание с изменением "ПРОБА" - тут сделана вставка для пробы и выход:

tatic ssize_t samhid_read(struct file *file, char *buffer, size_t count,
			 loff_t *ppos)
{
	struct usb_samhid *dev;
	int rv;
	bool ongoing_io;

	uint8_t buf[64];
	int actual_size;
	struct usb_device* udev;


	dev = file->private_data;
	//struct usb_endpoint_descriptor *endpoint;
	if(count > dev->bulk_in_size) count = dev->bulk_in_size;

	#if (_debug > 0)
	printk( KERN_INFO "\nФункция: samhid_read..\n" );
	printk( KERN_INFO "samhid_read : step 1\n" );
	printk( KERN_INFO "samhid_read : bulk_in_size=%d\n", dev->bulk_in_size );
	printk( KERN_INFO "samhid_read : bulk_in_endpointAddr=%d\n", (dev->bulk_in_endpointAddr & 0x0F) );
	printk( KERN_INFO "samhid_read : count=%d\n", count );
	#endif

	//!!! - ПРОБА из примера
	//if(count > dev->bulk_in_size) count = dev->bulk_in_size;
	udev = interface_to_usbdev(dev->interface);
	rv = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 1), buf, 64, &actual_size, HZ);
	printk( KERN_INFO "\nФункция: samhid_read !!! : rv=%d\n", rv );
	printk( KERN_INFO "samhid_read : count=%d\n", count );
	printk( KERN_INFO "samhid_read : dev-..>bulk_in_wait=%d\n", dev->bulk_in_wait );
	return rv;
  

вот консоль отладки(одноимённая с модулем прграмма теста):

root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release# ./samhid --default --testrd
Starting samhid...
Test чтения из устройства (/dev/samhid0): открытие...
Test чтения из устройства : открытие res=0
Test чтения из устройства : чтение...
Test чтения из устройства : чтение res=0
Test чтения из устройства : закрытие
root@pi01:/home/igor/sdb/MOUNT_RPI4/coding/codelite/samhid/samhid/samhid/Release# 

вот dmesg:

ункция: samhid_open..
[28164.562863] 
Функция: samhid_read..
[28164.562877] samhid_read : step 1
[28164.562886] samhid_read : bulk_in_size=64
[28164.562895] samhid_read : bulk_in_endpointAddr=1
[28164.562904] samhid_read : count=64
[28164.670824] 
Функция: samhid_read !!! : rv=-110
[28164.670844] samhid_read : count=64
[28164.670854] samhid_read : dev->bulk_in_wait=0
[28164.671048] 
Функция: samhid_flush..
[28164.671063] 
Функция: samhid_draw_down..
[28164.671083] 
Функция: samhid_release..
igor@pi01:~ $ 

вот уже неделю пилю - чтение ну совыем никак - что за код ошибки -110 для

PS: может какой-то Endpoint (у меня для чтения №1) на плате - может на at91sam7s256 где - то косяк. Свободный остался №3 - может поменять чтение на 3. №2 работает на запись. В даташмте конечных точел четыре.

Изменено пользователем Igor68

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Доброго времени суток! Скажу прямо: с USB практически не знаком. Но при создании устройства (на at91sam7s256, которое подключается к малине) возникли проблемы с чтением из этого самого устройства. В устройство записываю без проблем, но чтение из него совсем никак. Скажу честно книга Агурова по USB в наличии... но как я ни крутил не понятно производить чтение. Сами конечные точки в устройстве:

...
/* Endpoint, HID Interrupt In */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_IN(1),                /* bEndpointAddress */
  //USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
	USB_ENDPOINT_TYPE_BULK,
  WBVAL(_sz_report),                     /* wMaxPacketSize (было 4 стало 64*/
  0x0,          /* 32ms */          /* bInterval */
/* Endpoint, HID Interrupt Out */
  USB_ENDPOINT_DESC_SIZE,            /* bLength */
  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType */
  USB_ENDPOINT_OUT(2),                /* bEndpointAddress */
  //USB_ENDPOINT_TYPE_INTERRUPT,       /* bmAttributes */
	USB_ENDPOINT_TYPE_BULK,
  WBVAL(_sz_report),                     /* wMaxPacketSize (было 4 стало 64*/
  0x0,          /* 32ms */          /* bInterval */
...

т.е. не USB_ENDPOINT_TYPE_INTERRUPT, а USB_ENDPOINT_TYPE_BULK! Так вон не могу понять (наверное я глуп) последовательность действий со стороны устройства. Уже месяц крвыряюсь.

Что надо сдерать и в какой последовательности, тобы драйвер на основе usb-skeleton.c  активировал:

void USB_EndPoint1 (DWORD event) {
	//GetInReport();
  USB_WriteEP(USB_ENDPOINT_IN(1), &InReport[0], sizeof(_sz_report));
	//!!! use !!! - глупые опыты
	//USB_SetStallEP(1) - глупые опыты
	pSetStallEP = 0;

в то время как :

void USB_EndPoint2 (DWORD event) {
	DWORD cnt = 0;
	cnt = USB_ReadEP(USB_ENDPOINT_OUT(2), &OutReport[0]);
	if(cnt > 0) memcpy(MyInBuf, OutReport, cnt);//SetOutReport(cnt);
}

отрабатывает - точка остановки нормально отрабатывает.

Заранее благодарен!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...