Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: проблемы с байтовым инструкциями
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
klen
Здравствуюйте.
Начал осваивать F7
компилятор генерит код:
Код
NOP();
08000684:   nop    
08000686:   ldrb    r5, [r6, #0]
08000688:   orr.w   r4, r5, #1
0800068c:   strb    r4, [r6, #0]
08000684:   nop


содержание регистров r4,r5,r6
Цитата
r4 268436096
r5 640
r6 0x40026010 (Hex)


байтовая инструкция ldrb r5, [r6, #0] вызывает вываливание в hard fault? в тоже время переписанный код который организован как чтение слова по томуже адресу не вызывает исключительной ситуации. чтение регистра DMA_CR. при этом же такое же байтовое чтение модификация записm проканывает с регистром RCC AHB1

так должно быть - неможеn он байтовый кусок вычитать из переферийного адреса?
Genadi Zawidowski
заглянул в RM0410.PDF.
Регистра DMA_CR не нашел, но на странице 262 встретилось вот такое:
Цитата
8.5 DMA registers
The DMA registers have to be accessed by words (32 bits).

Как оно могло такое нагенерить, если регистр volatile и 32 бита?

Из другого места (опять не понятно про что вопрос - с регистром RCC AHB1):
Цитата
5.3.10 RCC APB1 peripheral clock enable register (RCC_APB1ENR)
Address offset: 0x40
Reset value: 0x0000 0000
Access: no wait state, word, half-word and byte access.


А hard fault как-бы намекает, что так (байтом) нельзя.
klen
Цитата(Genadi Zawidowski @ Feb 13 2017, 03:02) *
заглянул в RM0410.PDF.
Регистра DMA_CR не нашел, но на странице 262 встретилось вот такое:

Как оно могло такое нагенерить, если регистр volatile и 32 бита?

Из другого места (опять не понятно про что вопрос - с регистром RCC AHB1):


А hard fault как-бы намекает, что так (байтом) нельзя.

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

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

но я придумал как обойти это ограничение.

еще раз убеждаемся - не просто читать даташит а читать ВНИМАТЕЛЬНО! в моем случае выло как обычно - смотриш в книгу - видиш фигу sm.gif вечер воскресения бесполезно убит этой глупостью.
adnega
Цитата(klen @ Feb 13 2017, 14:13) *
ну он думает если ты бит изменяеш в слове то достаточно только байт модифицировать.

А как вы описываете бит? По моему так не должно быть.
Я описываю так
Код
DWORD none:1;
и надеюсь увидеть 32-битный доступ.
ViKo
Цитата(klen @ Feb 13 2017, 14:13) *
... в моем случае выло как обычно - смотриш в книгу - видиш фигу sm.gif ...

При всем уважении, меня не удивляет. laughing.gif
SasaVitebsk
Цитата(klen @ Feb 13 2017, 14:13) *
тема связана с тем что я делаю такую штуку - описываю регистры как структуры с битовыми полями. так удобнее писать код.

IAR так делает. У него там несколько разных хидеров. И такой тоже есть.
Alechek
Цитата(SasaVitebsk @ Feb 13 2017, 19:53) *
IAR так делает.

Раньше пользовал. Сейчас стараюсь использовать заголовочники под процессор в с стиле CMSIS.
Так более универсальней получается и меньше кода если несколько бит одновременно изменить надо.
Forger
Цитата(klen @ Feb 13 2017, 14:13) *
тема связана с тем что я делаю такую штуку - описываю регистры как структуры с битовыми полями. так удобнее писать код.

Может быть, я стал старый и дремучий, но никак не пойму чем не устраивает уже готовые h-файлы, где самим производителем проца уже описаны соотв. структурами и дефайнами все регистры и битовые поля???
В данном случае на объем кода это никак не влияет, а времени и нервов экономит вагон и маленькую тележку...
Ей богу не пойму, зачем изобретать велосипед в данном случае ... laughing.gif
KRS
IAR - делает!
но у него запись битовых полей в 32 разрядные регистры не приводит к байтовым операциям!
klen
Цитата(KRS @ Feb 13 2017, 20:20) *
IAR - делает!
но у него запись битовых полей в 32 разрядные регистры не приводит к байтовым операциям!

ну я еще придумаю как это обустроить sm.gif

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

например теперь невозможно записать в поля номера канала регистра DMAx_STREAMy.channel канал которого нет - его не будет в перечислении sm.gif

велосипед вещь фундаментальная как инь и янь! подозреваю что велосипед это средство перемещения в будующее где у тебя уже будет опыт им не пользоватся
Forger
Цитата(klen @ Feb 14 2017, 01:02) *
в случае с битовыми полями компилятор обнаружит несоответствие типов и ругнется застатвив все сделать правильно.

Для этого есть готовый HAL, а для особо ленивых есть "куб".

Если HAL и куб не кошерно, то можно просто написать свою либу:
надрать кусков из примеров под HAL, отладить их, наделав своих примеров и торжественно закопать все эти сомнительные вещи единожды пройдя путь библиотеко-писателя .... wacko.gif

У меня самописная библиотека есть тока для пинов, т. к. дрыгать ногами лучше с минимальных оверхедом - HAL в этом смысле сильно проигрывает прямому обращению к соотв. регистрам.

Все остальное даже с использованием куба не шибко влияет на производительность - периферия инициализируется обычно единожды при старте камня, а далее юзаются лишь примитивные функции и относительно редко.
Оверхед на старте проца не критичен, там можно тупо пользовать HAL как есть, а далее в коде (когда проц уже долбит во всю) для пущей производительности можно нагло выдрать код из HAL и напихать его в свой проект.

Цитата
например теперь невозможно записать в поля номера канала регистра DMAx_STREAMy.channel канал которого нет - его не будет в перечислении sm.gif

Но при этом появляется возможно наступать на такие детские грабли, как описано начале темы....
Сергей Борщ
QUOTE (klen @ Feb 14 2017, 00:02) *
например теперь невозможно записать в поля номера канала регистра DMAx_STREAMy.channel канал которого нет - его не будет в перечислении sm.gif
Ой ли. На каком языке вы пишете? Дело в том, что "голый" Си должен делать неявное преобразование enum->int и дальше тоже неявное int->другой enum. Поэтому в "голом" Си enumы практически бесполезны. Максимум, чего от них можно ожидать - указание конкретного символического имени для комбинации битов в отладчике. В плюсах неявное преобразование int->enum запрещено, поэтому такой номер проходит. Но следующим этапом встает проблема области видимости - нельзя иметь два enum со значением, скажем, OFF. Эта проблема решена в C++11 (enum class), но там они родили другую - у них enum class не лезет в битовое поле.


Просто я в свое время тоже пытался решить эту проблему, но рабочего решения так и не нашел. Понял, что это реализуемо через гору писанины на шаблонах, но на такой подвиг я пока не готов.
scifi
Цитата(klen @ Feb 14 2017, 01:02) *
зачем это надо?
при расписывании полей можно указать тип этого поля и в перечислении все его допустимые значения.
в таком виде при написании кода пропадает возможность наступить на мои любимые грабли - записать задефайненый бит одного похоженго регистра в другой похожий регистр или перепутать флаги ...

Сие есть страдание от безделья. Этот класс ошибок совсем не страшный, ибо обнаруживается сразу же по факту того, что код просто не работает.
Ну и да, язык не даёт никаких гарантий, что не будет использован побайтовый доступ, поэтому раскидывать себе грабли на этом поле едва ли разумно.
Kabdim
Цитата(Forger @ Feb 14 2017, 01:22) *
единожды пройдя путь библиотеко-писателя .... wacko.gif

Истинный программист не может пройти этот путь, тем более единожды. sm.gif

А все проблемы с байтовым доступом от ленности. Когда переделываешь регистры на такой манер нужно как мантру использовать:
Код
reg_struct temp = *reg;
<work>
*reg = temp;

Атомарность много для каких регистром важна и лучше даже не начинать крутить биты "на горячую". Понятное дело это можно и нужно по вкусу обернуть в макросы/raii.
Forger
Цитата(Kabdim @ Feb 14 2017, 10:37) *
Истинный программист не может пройти этот путь, тем более единожды. sm.gif
То был сарказм sm.gif

Kabdim
Не мог не продолжить sm.gif .
Сергей Борщ
QUOTE (scifi @ Feb 14 2017, 09:08) *
Ну и да, язык не даёт никаких гарантий, что не будет использован побайтовый доступ
Да ладно? Если underlying type у битового поля объявлен как uint32_t - это как раз прямое указание использовать 32-битный доступ, а volatile в объявлении структуры - "и не фантазировать".
SasaVitebsk
Цитата(Alechek @ Feb 13 2017, 18:34) *
Раньше пользовал. Сейчас стараюсь использовать заголовочники под процессор в с стиле CMSIS.
Так более универсальней получается и меньше кода если несколько бит одновременно изменить надо.

Слушайте, ну незнание не освобождает и далее по тексту....
Там имеется и то и другое...

Цитата(KRS @ Feb 13 2017, 20:20) *
IAR - делает!
но у него запись битовых полей в 32 разрядные регистры не приводит к байтовым операциям!

ну да. Не сталкивался... ))


Цитата(klen @ Feb 14 2017, 01:02) *
например теперь невозможно записать в поля номера канала регистра DMAx_STREAMy.channel канал которого нет - его не будет в перечислении sm.gif

И это тоже сделано за вас, заметьте... ))
Причём я не предлагаю вам пользоваться IAR. Возьмите хидер готовый... ))
scifi
Цитата(Сергей Борщ @ Feb 14 2017, 11:00) *
Да ладно? Если underlying type у битового поля объявлен как uint32_t - это как раз прямое указание использовать 32-битный доступ, а volatile в объявлении структуры - "и не фантазировать".

Ну, это примерно такая же гарантия, что и переменная, объявленная как register, будет размещена в регистре laughing.gif
Можете надеяться, конечно, но стандарт на этот счёт молчит, как рыба об лёд. Может быть, я что-то пропустил, тогда прошу привести цитату из стандарта.
AHTOXA
Цитата(Сергей Борщ @ Feb 14 2017, 11:58) *
Просто я в свое время тоже пытался решить эту проблему, но рабочего решения так и не нашел. Понял, что это реализуемо через гору писанины на шаблонах, но на такой подвиг я пока не готов.

Напомню про моё решение этой проблемы: вот.
SasaVitebsk
Вот хидер на 407 камень
вот первое попавшиеся ...
Код
typedef struct
{
  __IO uint32_t              MCR;                 /*!< CAN master control register,         Address offset: 0x00          */
  __IO uint32_t              MSR;                 /*!< CAN master status register,          Address offset: 0x04          */
  __IO uint32_t              TSR;                 /*!< CAN transmit status register,        Address offset: 0x08          */
  __IO uint32_t              RF0R;                /*!< CAN receive FIFO 0 register,         Address offset: 0x0C          */
  __IO uint32_t              RF1R;                /*!< CAN receive FIFO 1 register,         Address offset: 0x10          */
  __IO uint32_t              IER;                 /*!< CAN interrupt enable register,       Address offset: 0x14          */
  __IO uint32_t              ESR;                 /*!< CAN error status register,           Address offset: 0x18          */
  __IO uint32_t              BTR;                 /*!< CAN bit timing register,             Address offset: 0x1C          */
  uint32_t                   RESERVED0[88];       /*!< Reserved, 0x020 - 0x17F                                            */
  CAN_TxMailBox_TypeDef      sTxMailBox[3];       /*!< CAN Tx MailBox,                      Address offset: 0x180 - 0x1AC */
  CAN_FIFOMailBox_TypeDef    sFIFOMailBox[2];     /*!< CAN FIFO MailBox,                    Address offset: 0x1B0 - 0x1CC */
  uint32_t                   RESERVED1[12];       /*!< Reserved, 0x1D0 - 0x1FF                                            */
  __IO uint32_t              FMR;                 /*!< CAN filter master register,          Address offset: 0x200         */
  __IO uint32_t              FM1R;                /*!< CAN filter mode register,            Address offset: 0x204         */
  uint32_t                   RESERVED2;           /*!< Reserved, 0x208                                                    */
  __IO uint32_t              FS1R;                /*!< CAN filter scale register,           Address offset: 0x20C         */
  uint32_t                   RESERVED3;           /*!< Reserved, 0x210                                                    */
  __IO uint32_t              FFA1R;               /*!< CAN filter FIFO assignment register, Address offset: 0x214         */
  uint32_t                   RESERVED4;           /*!< Reserved, 0x218                                                    */
  __IO uint32_t              FA1R;                /*!< CAN filter activation register,      Address offset: 0x21C         */
  uint32_t                   RESERVED5[8];        /*!< Reserved, 0x220-0x23F                                              */
  CAN_FilterRegister_TypeDef sFilterRegister[28]; /*!< CAN Filter Register,                 Address offset: 0x240-0x31C   */
} CAN_TypeDef;

Ну и далее по тексту для любителей якобы CMSIS
Код
/*!<CAN control and status registers */
/*******************  Bit definition for CAN_MCR register  ********************/
#define  CAN_MCR_INRQ                        ((uint32_t)0x00000001)        /*!<Initialization Request */
#define  CAN_MCR_SLEEP                       ((uint32_t)0x00000002)        /*!<Sleep Mode Request */
#define  CAN_MCR_TXFP                        ((uint32_t)0x00000004)        /*!<Transmit FIFO Priority */
#define  CAN_MCR_RFLM                        ((uint32_t)0x00000008)        /*!<Receive FIFO Locked Mode */
#define  CAN_MCR_NART                        ((uint32_t)0x00000010)        /*!<No Automatic Retransmission */
#define  CAN_MCR_AWUM                        ((uint32_t)0x00000020)        /*!<Automatic Wakeup Mode */
#define  CAN_MCR_ABOM                        ((uint32_t)0x00000040)        /*!<Automatic Bus-Off Management */
#define  CAN_MCR_TTCM                        ((uint32_t)0x00000080)        /*!<Time Triggered Communication Mode */
#define  CAN_MCR_RESET                       ((uint32_t)0x00008000)        /*!<bxCAN software master reset */
#define  CAN_MCR_DBF                         ((uint32_t)0x00010000)        /*!<bxCAN Debug freeze */
/*******************  Bit definition for CAN_MSR register  ********************/
#define  CAN_MSR_INAK                        ((uint32_t)0x0001)            /*!<Initialization Acknowledge */
#define  CAN_MSR_SLAK                        ((uint32_t)0x0002)            /*!<Sleep Acknowledge */
#define  CAN_MSR_ERRI                        ((uint32_t)0x0004)            /*!<Error Interrupt */
#define  CAN_MSR_WKUI                        ((uint32_t)0x0008)            /*!<Wakeup Interrupt */
#define  CAN_MSR_SLAKI                       ((uint32_t)0x0010)            /*!<Sleep Acknowledge Interrupt */
#define  CAN_MSR_TXM                         ((uint32_t)0x0100)            /*!<Transmit Mode */
#define  CAN_MSR_RXM                         ((uint32_t)0x0200)            /*!<Receive Mode */
#define  CAN_MSR_SAMP                        ((uint32_t)0x0400)            /*!<Last Sample Point */
#define  CAN_MSR_RX                          ((uint32_t)0x0800)            /*!<CAN Rx Signal */

Ну и так далее ....
Обращаю внимание, что в битовой маске сразу указаны и устройство и регистры...
Forger
Цитата(SasaVitebsk @ Feb 14 2017, 12:40) *
Вот хидер на 407 камень
Все вполне наглядно и читаемо. Сложно что-то напутать.
И главное - что это уже написано и проверено самим производителем проца!
Грех не воспользоваться такой халявой wink.gif
Сергей Борщ
QUOTE (AHTOXA @ Feb 14 2017, 11:38) *
Напомню про моё решение этой проблемы: вот.
Я его помню, но это "гора писанины на шаблонах".

QUOTE (SasaVitebsk @ Feb 14 2017, 11:40) *
Обращаю внимание, что в битовой маске сразу указаны и устройство и регистры...
Что не мешает ее записать не туда. Вот чесслово, сам у себя не так давно подобную описку нашел.
Alechek
Цитата(SasaVitebsk @ Feb 14 2017, 14:33) *
Слушайте, ну незнание не освобождает и далее по тексту....
Там имеется и то и другое...


Цитата(SasaVitebsk @ Feb 14 2017, 14:40) *
Вот хидер на 407 камень
вот первое попавшиеся ...

И где такое интересно дают?
IAR 7.7
inc/ST

файлов stm*.h вообще не наблюдаю
есть только вида iostm*.h
scifi
Цитата(Alechek @ Feb 14 2017, 17:07) *
И где такое интересно дают?

В интернете: тынц.
Alechek
Цитата(scifi @ Feb 14 2017, 19:20) *
В интернете: тынц.

В интернете это понятно. Там речь про IAR шла.
Forger
Цитата(Alechek @ Feb 14 2017, 17:53) *
речь про IAR шла.

Неужели в IAR не С/C++, а что-то свое, нестандартное? sm.gif


оффффф. В свое время пытался по-юзать IAR, он мне оказался жутко нестандатной IDE (вот уж стоило где изобретать лисапет), поплевался, поматерился и в итоге удалил ... не жалею ни разу )))
Keil тоже не конфетка, но под нетолстые ARMы это пока что самое нормальное с привычным интерфейсом (имхо!), особенно после кроссворкса ...
Alechek
Цитата(Forger @ Feb 14 2017, 20:06) *
Неужели в IAR не С/C++, а что-то свое, нестандартное? sm.gif


Примерно так
Код
/* Clock configuration register (RCC_CFGR) */
typedef struct {
  __REG32  SW             : 2;
  __REG32  SWS            : 2;
  __REG32  HPRE           : 4;
  __REG32  PPRE1          : 3;
  __REG32  PPRE2          : 3;
  __REG32  ADC_PRE        : 2;
  __REG32  PLLSRC         : 1;
  __REG32  PLLXTPRE       : 1;
  __REG32  PLLMUL         : 4;
  __REG32  USBPRE         : 1;
  __REG32                 : 1;
  __REG32  MCO            : 3;
  __REG32                 : 5;
} __rcc_cfgr_bits;

....
__IO_REG32_BIT(RCC_CFGR,          0x40021004,__READ_WRITE ,__rcc_cfgr_bits);


Использовать как
Код
  RCC_CFGR_bit.PLLMUL = 2;
Forger
Цитата(Alechek @ Feb 15 2017, 07:18) *
Примерно так..

Я имел ввиду скормить ИАРу стандартные h файлы (от производителя чипа), которые должен понимать даже самый чахлый С компилятор.
klen
все коллеги были правы но меня не поняли. я чуть позже выложу для обозрения велосипед и тогда можно будет кинуть в меня какахой предметно. наверно будет очень похоже на иар
естественно для мня только С++, С - это тоже самое на выходе кодогенератора но куча фатальных граблей для программиста. полагаю что если не писать код достаточно большой который пишут >10 человек и сложный то этого не понять потому что не заметить.

почему не использую иар? а у меня есть деньги на него?
Obam
Цитата(klen @ Feb 16 2017, 13:49) *
почему не использую иар? а у меня есть деньги на него?


У мну тоже нет, а я в образовательных целях, кроме того без support-а столько усилилий затрачено, что они мне приплатить обязаны (по поводу приплатить - шутка).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.