Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32_USB-FS-Device_Driver usb_mem.c
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
klen
Это код исходника

от кода в циклах у меня шерсть дыбом встает. у компиллера кстате тоже.
это можно написать по простому а не так заумно?

сижу - гадаю, тодлько у меня отторжение вызовет это или нет smile.gif
есть ощущение что как пойму че тут имели ввиду c указателями перепишу на асме smile.gif
по логике всегото - перекопировать байты из одного место в другое.. но как витиевато, с двумя временными переменными! изготовлено то...



Код
/*******************************************************************************
* Function Name  : UserToPMABufferCopy
* Description    : Copy a buffer from user memory area to packet memory area (PMA)
* Input          : - pbUsrBuf: pointer to user memory area.
*                  - wPMABufAddr: address into PMA.
*                  - wNBytes: no. of bytes to be copied.
* Output         : None.
* Return         : None    .
*******************************************************************************/
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;   /* n = (wNBytes + 1) / 2 */
  uint32_t i, temp1, temp2;
  uint16_t *pdwVal;
  pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
  for (i = n; i != 0; i--)
  {
    temp1 = (uint16_t) * pbUsrBuf;
    pbUsrBuf++;
    temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
    *pdwVal++ = temp2;
    pdwVal++;
    pbUsrBuf++;
  }
}
/*******************************************************************************
* Function Name  : PMAToUserBufferCopy
* Description    : Copy a buffer from user memory area to packet memory area (PMA)
* Input          : - pbUsrBuf    = pointer to user memory area.
*                  - wPMABufAddr = address into PMA.
*                  - wNBytes     = no. of bytes to be copied.
* Output         : None.
* Return         : None.
*******************************************************************************/
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;/* /2*/
  uint32_t i;
  uint32_t *pdwVal;
  pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
  for (i = n; i != 0; i--)
  {
    *(uint16_t*)pbUsrBuf++ = *pdwVal++;
    pbUsrBuf++;
  }
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
d__
Конечно кривовато написано, но вся фишка состоит в том, что усеровский буфер байтный, а PMAшный вордный. вот он перепаковывает байты в слова, а потом слова вытаcкивает на выход. И наоборот. Скорее всего побайтное обращение в PMA буфер не допускается. Прямых аналогоф таких функций в стандартной библиотеке не наблюдается...

isochronous and double-buffered
bulk endpoints have special handling of packet buffers (Refer to Section 17.5.4: Isochronous
transfers and Section 17.5.3: Double-buffered endpoints respectively).
klen
ну а копировать тупо uint16_t без всякого шаманства? юзеровский это ведь на RAM, туда можно тыкатся 8,16,32 бита, как нравится от сутуации, объявить указатель на pbUsrBuf как uint16_t*, в случае если число байтов в копировании нечетное то один в виде хвостика крайнего полуслова пролетит. разве не получится?

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

In the following pages two location addresses are reported: the one to be used by
application software while accessing the packet memory, and the local one relative to USB
Peripheral access. To obtain the correct STM32F10xxx memory address value to be used in
the application software while accessing the packet memory, the actual memory location
address must be multiplied by two. The first packet memory location is located at
0x4000 6000. The buffer descriptor table entry associated with the USB_EPnR registers is
described below.
klen
Цитата(d__ @ Nov 27 2009, 16:31) *
Ну дык назад они как раз проще вываливают, правда я не разбирался как они обрабатывают пакеты с нечетным количеством байтов...
Ну а что можно требовать от смуглолицых програмеров, начитались книжек по 150$ за штуку и хренячат не разбираясь что как и почем...

с нечетными они лишний байт копируют - никому зло от этого не причиняется.

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


переписал таки... вот


код было
Код
void UserToPMABufferCopySTM(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;   /* n = (wNBytes + 1) / 2 */
  uint32_t i, temp1, temp2;
  uint16_t *pdwVal;
  pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
  for (i = n; i != 0; i--)
  {
    temp1 = (uint16_t) * pbUsrBuf;
    pbUsrBuf++;
    temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
    *pdwVal++ = temp2;
    pdwVal++;
    pbUsrBuf++;
  }
}


стало
Код
void UserToPMABufferCopy(uint16_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
  uint32_t n = (wNBytes + 1) >> 1;
  uint32_t *pma = (uint32_t *)((uint32_t)wPMABufAddr * 2 + PMAAddr);
  while(n--)
    *pma++ = *pbUsrBuf++;
}



листинг асм
Код
UserToPMABufferCopy:
    add    r3, r1, #536870912
    add    r1, r3, #12288
    adds    r2, r2, #1
    lsls    r1, r1, #1
    asrs    r2, r2, #1
    movs    r3, #0
    b    .L2
.L3:    ldrh    ip, [r0], #2
    adds    r3, r3, #1
    str    ip, [r1], #4
.L2:    cmp    r3, r2
    bcc    .L3
    bx    lr


Код
UserToPMABufferCopySTM:
    add    r3, r1, #536870912
    add    r1, r3, #12288
    adds    r2, r2, #1
    push    {r4, lr}
    lsls    r1, r1, #1
    asrs    r2, r2, #1
    movs    r3, #0
    b    .L9
.L10:    ldrb    r4, [r0, #-1]    @ zero_extendqisi2
    ldrb    ip, [r0, #-2]    @ zero_extendqisi2
    orr    ip, ip, r4, lsl #8
    strh    ip, [r1, r3, lsl #2]    @ movhi
    adds    r3, r3, #1
.L9:    adds    r0, r0, #2
    cmp    r3, r2
    bcc    .L10
    pop    {r4, pc}


на выходе компиллера не сильно то и большая разница ( 5 иструкций из 17 по размеру, а по скорости подъем и лив двух регистров в стек, то при большом числе байтов теряются на общем фоне ), но зато пусть в меня кинет камнем тот кто скажет что исходник не читается с первого раза!
вот так

гдето когдато я слышал что индусам платят за количество строк ! во как. если так то разработчики железа(еще большей памяти и еще более быстрого процессора) никогда без работы не останутся smile.gif
d__
Ты не прав Аркаша! У тебя подпись функции поменялась...
klen
Цитата(d__ @ Nov 27 2009, 21:57) *
Ты не прав Аркаша! У тебя подпись функции поменялась...

А че?! какая подпись начальника?

я же не библию переписал ..... задача было сделать понятнее и по возможности быстрее и компактнее. че не так ?
на самом деле я залез сюда потому что компиллер тупо падал segmentation fault на этом бреде. пришлось применить скальпель и к библиотеке и к компиллеру. теперь не падает и с STшным кодом.

а вообще в понедельник своим товарищам программерам подсуну "ихний" UserToPMABufferCopy - они типа С++ крутни, мосмотрим как они указатели разберут. я если честно час потерял на разбор. через два опять заработал USB на девайсе. пятницв - тугой день, солнца опятьже нехватает организму.
d__
Дык счас строчка с типами параметров и типом возвращаемого значения запоминается где-то внутри обьектного модуля и при линковке линкер начинает скрипеть что типы не совпадают и типа эта фигня называется подписью функции. Ну где-то может я переврал, пусть меня поправят...
klen
Цитата(d__ @ Nov 27 2009, 22:16) *
Дык счас строчка с типами параметров и типом возвращаемого значения запоминается где-то внутри обьектного модуля и при линковке линкер начинает скрипеть что типы не совпадают и типа эта фигня называется подписью функции. Ну где-то может я переврал, пусть меня поправят...

линкер скрипеть не будет - перекомпиляция всего спасет от этой беды. хидер я тоже естественно подправил
ar__systems
Цитата(d__ @ Nov 27 2009, 14:16) *
Дык счас строчка с типами параметров и типом возвращаемого значения запоминается где-то внутри обьектного модуля и при линковке линкер начинает скрипеть что типы не совпадают и типа эта фигня называется подписью функции. Ну где-то может я переврал, пусть меня поправят...


Не где-то, а в имени функции. И делает это компилятор только в C++ режиме
d__
Цитата(ar__systems @ Nov 27 2009, 23:26) *
Не где-то, а в имени функции. И делает это компилятор только в C++ режиме


Может быть, может быть, у меня ИАР так скрипит, что сил нет... Что с плюсами, что без плюсов...

Я бы написал вот так, по моему так ближе к оригиналу:
CODE
void UserToPMABufferCopySTM(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
register int nw= (wNBytes + 1) >> 1;
register uint16_t *pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
do
{
*pdwVal=(uint16_t)pbUsrBuf[0]|((uint16_t)pbUsrBuf[1]<<8);
pdwVal+=2;pbUsrBuf+=2;
}
while((--nw)!=0);
}


Пожалуйста скомпилируй и поругай, а то под руками у меня нет твоего компилера под Кортекс...
...
Пришлось устанавливать RIDE7:
CODE

void UserToPMABufferCopySTM(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
0: f101 5100 add.w r1, r1, #536870912 ; 0x20000000
4: 3201 adds r2, #1
6: f501 5140 add.w r1, r1, #12288 ; 0x3000
a: b510 push {r4, lr}
c: 0049 lsls r1, r1, #1
e: 4604 mov r4, r0
10: f04f 0c00 mov.w ip, #0 ; 0x0
14: 1050 asrs r0, r2, #1
16: eb04 030c add.w r3, r4, ip
1a: 785a ldrb r2, [r3, #1]
1c: f814 300c ldrb.w r3, [r4, ip]
20: f110 30ff adds.w r0, r0, #4294967295 ; 0xffffffff
24: ea43 2302 orr.w r3, r3, r2, lsl #8
28: f821 301c strh.w r3, [r1, ip, lsl #1]
2c: f10c 0c02 add.w ip, ip, #2 ; 0x2
30: d1f1 bne.n 16 <UserToPMABufferCopySTM+0x16>
32: bd10 pop {r4, pc}
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.