|
|
  |
реализация булевых переменных в bit-band, кто до чего дошел |
|
|
|
Oct 16 2015, 07:00
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Привет Вижу для родного gcc - самое правильное Код typedef uint32_t __attribute__((section(".bitmap"))) bit; Какбы вопросы, возникающие в связи с этим: 1. Как избежать использование области памяти в не bit-band в линкер скрипте? 2. Как наоборот, - проще получить параметры этой области или ее части для быстрого обнуления? Спасибо. ps вот увидел такое http://stackoverflow.com/questions/1655271...ection-in-c-gccКод /** * Assuming you've tagged some stuff earlier with: * __attribute((__section__("my_custom_section"))) */
struct thing *iter = &__start_my_custom_section;
for (; iter < &__stop_my_custom_section; ++iter) { /* do something with *iter */ } т.е. получается, что я могу выделить под битмап что-то и его размер будет Код extern char bitmap[((uint) __stop_my_custom_section - __start_my_custom_section)/32]; а как мне на этапе компиляции назначить адрес этой области?
Сообщение отредактировал _Pasha - Oct 16 2015, 07:12
|
|
|
|
|
Oct 16 2015, 08:28
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Цитата(_Pasha @ Oct 16 2015, 14:00)  а как мне на этапе компиляции назначить адрес этой области? CODE Bit-band - via a linker. Код для GCC - линкер. xxx_sram/flash.ld
MEMORY { ROM (rx) : ORIGIN = 0x08000000, LENGTH = __ RAM (rwx) : ORIGIN = 0x20000000, LENGTH = __ BITRAM (rw) : ORIGIN = 0x22000000, LENGTH = 2048K // - LENGTH(RAM) * 128 } ---- /* SRAM base address in the bit-band region*/ _sramflag = .; sflagadres = ((_sramflag - ORIGIN(RAM)) << 5 ); .flag (NOLOAD): { . += sflagadres; . = ALIGN(4); _sflag = .; KEEP(*(.flag)) . = ALIGN(128); _eflag = .; } > BITRAM _eramflag = ((_eflag - _sflag) >> 5); /* SRAM base address in the bit-band region*/ .bss (NOLOAD): { __bss_start__ = .; . += _eramflag; *(.bss*) *(COMMON) __bss_end__ = .; } > RAM
С код. #define _FLAG __attribute__ ((section(".flag")))
Далее по коду С. volatile uint32_t temp_name_flag _FLAG;
|
|
|
|
|
Oct 16 2015, 08:59
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
гран мерси. т.е. суть приема в том, что назначаем область битовых флагов в начале доступной области SRAM и корректируем начало .bss в соответствии с использованием секции флагов отдельное спасибо за Код . = ALIGN(128); гарантированно сидел бы фтыкал  -- а, ну и по _FLAG - все-таки bit через typedef uint32_t итд правильнее.
Сообщение отредактировал _Pasha - Oct 16 2015, 09:18
|
|
|
|
|
Oct 16 2015, 16:05
|
Частый гость
 
Группа: Участник
Сообщений: 182
Регистрация: 16-10-15
Пользователь №: 88 894

|
Код typedef uint32_t __attribute__((section(".bitmap"))) bit; Вы уверенны что смена названия типа переменной лучше макроса? У меня GCC матерится на смену типа.
|
|
|
|
|
Oct 19 2015, 09:05
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 2-03-05
Из: Санкт-Петербург
Пользователь №: 3 012

|
Можно обычным дифайном обойтись. Например у меня в одном из проектов. Код #define PortF_Bit0 (*((volatile unsigned long *) 0x43D00000)) //PortF_Bit0 = 1;//установить бит 0 в единицу //PortF_Bit0 = 0;//установить бит 0 в ноль
#define PortF_Bit1 (*((volatile unsigned long *) 0x43D00004)) //PortF_Bit1 = 1;//установить бит 1 в единицу //PortF_Bit1 = 0;//установить бит 1 в ноль
|
|
|
|
|
Oct 21 2015, 07:50
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 2-03-05
Из: Санкт-Петербург
Пользователь №: 3 012

|
Цитата(jcxz @ Oct 21 2015, 08:23)  Это обычная память. Для которой есть область - алиас. Человек пишет в алиас-область, при этом опущено выделение этой памяти по настоящим адресам. По настоящим адресам и есть обращение. Например: (*((volatile unsigned long *) 0x43D00000)) И не надо ничего выдумывать, такой вариант работает в компиляторах для ARM и для любых других.
|
|
|
|
|
Oct 21 2015, 08:36
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Golikov A. @ Oct 21 2015, 11:20)  пробил дефайнами нужные биты и сиди ими щелкай, чего я не учитываю? 1) Атомарности операции. 2) Затрат времени исполение дополнительной кучи команд. Учитесь думать самостоятельно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 08:41
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Golikov A. @ Oct 21 2015, 11:33)  ПЛАКАТЬ ХОЧЕТСЯ  ... нафига памяти то выделятся? Вы же когда в периферию обращаетесь вы же не делаете выделения памяти, а запись в регистры идет тоже просто по адресам, зачем тут чего то выделять? Товарищ не понимааает (с) Если у Вас есть возможность заводить static bool в разных модулях, то это гораздо интереснее чем вручную и глобально их определять. Насчет BSRR - история давняя, типа масляного масла получается, неудивительно что там конфликты возникают.
|
|
|
|
|
Oct 21 2015, 09:05
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Если у Вас есть возможность заводить static bool в разных модулях Ну то есть я правильно понял, это просто для создания переменных через которые писать аля удобнее, чем через прямой указатель... Цитата Слезами делу не поможешь. Так что наморщите ум и подумайте. Цитата Учитесь думать самостоятельно. Есть подозрения среднеуважаемый zltigo что вы испытываете некие комплексы, связанные с вашим уровнем интеллекта, и потому по поводу и без пытаетесь словами всем объяснить что вы умнее%).... Однако как показала практика с понималкой у вас не очень, потому я вам разжую: я предлагал дефайном пробить область в битбанде, чтобы как бы непонятному адресу поставить в соответствие понятное название бита, и задефайнить прямо макрос, чтобы писать по его имени прямо в эту область. Как делают с регистрами периферии. Теперь поняли?
|
|
|
|
|
Oct 21 2015, 09:47
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(AVI-crak @ Oct 16 2015, 19:05)  Код typedef uint32_t __attribute__((section(".bitmap"))) bit; Вы уверенны что смена названия типа переменной лучше макроса? У меня GCC матерится на смену типа. Здравствуйте. Еще не добрался до проекта. Но обязательно проверю и сообщу.
|
|
|
|
|
Oct 21 2015, 10:06
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(copov @ Oct 21 2015, 13:50)  По настоящим адресам и есть обращение. Например: (*((volatile unsigned long *) 0x43D00000)) И не надо ничего выдумывать, такой вариант работает в компиляторах для ARM и для любых других. Опять 25... Я писал не про обращение, а про выделение. Чувствуете разницу? Если разжевать: когда Вы так обратились к какому-то флагу, соответственно - изменился некий байт адреса в области RAM. Вот чтобы этот байт не оказался занятым чем-то полезным, нужно выделить на его месте переменную, в которой и хранится этот флаг.
|
|
|
|
|
Oct 21 2015, 10:11
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Golikov A. @ Oct 21 2015, 14:20)  чего читать то? Я не понимаю зачем возня и почему нельзя писать напрямую через адрес, ну типа вот так (*((volatile unsigned long *) 0x43D00000)) ? пробил дефайнами нужные биты и сиди ими щелкай, чего я не учитываю? Не учитываете, что когда Вы делаете: *((volatile unsigned long *) 0x43D00000) = 1, то в реальной ОЗУ, соответсвующей этому адресу, меняется этот бит. И где этот бит находится? Куда попадает? Вы всё своё ПО пишете так: *((volatile unsigned long *)addr_XXX = y; или всё-таки выделяете память для переменной и делаете так: int XXX; XXX = y; ?
|
|
|
|
|
Oct 21 2015, 10:20
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(zltigo @ Oct 21 2015, 13:12)  Увы, удручающему большинству здесь выступающих, понять эту очевидный факт не по силам  . Цитата(jcxz @ Oct 21 2015, 13:16)  И не говорите..... Такое ощущение, что многие из здесь присутствующих не знают что такое распределение памяти под переменные и для чего нужен линкёр, а пишут весь свой код как: *(int *)0x000XXX = y Нет. Зато есть ощущение, что некоторые из здесь присутствующих выражаются недостаточно чётко, их понимают превратно, а они списывают это на скудоумие аудитории и своё интеллектуальное превосходство.
|
|
|
|
|
Oct 21 2015, 12:03
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(_Pasha @ Oct 21 2015, 12:47)  Еще не добрался до проекта. Но обязательно проверю и сообщу. ааа. Понятно. Действительно, аттрибут к typedef неприменим Код gcc -Wall -c "tst.c" -I. --std=gnu99 tst.c:18:61: error: section attribute not allowed for ‘bit’ typedef volatile uint32_t __attribute__((section(".bss"))) bit; ^ Compilation failed. Так что только дефайном.
Сообщение отредактировал _Pasha - Oct 21 2015, 12:04
|
|
|
|
|
Oct 21 2015, 12:05
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Golikov A. @ Oct 21 2015, 16:50)  Погодите-погодите... а зачем регион бит-банда включен в общую оперативную память? А если он не включен, то как линкер там может разместить какие-то переменные? Чего то я реально не понимаю, вот с сайта арма В Cortex есть регион адресного пространства (в котором может находиться физическое ОЗУ), такой особенный регион (назовём его регион_A), что для каждого его бита в другом регионе адресного пространства (назовём его регион_B) существует 32битное слово, при записи в которое некоторых значений, меняется этот бит (это слово является псевдонимом этого бита). Таким образом, чтобы задействовать эту фичу, надо в регионе_A объявить переменную достаточной ёмкости, хранящую набор битовых флагов, а работать с этими флагами надо через слова-алиасы для этих битов из региона_B. Хотя в то же время эти же биты можно читать/модифицировать и через регион_A. Но если делать запись их через алиасы, то эти записи атомарны, в этом и кроется вся соль bit-banding-а. scifi, если и это описание ещё недостаточно чёткое, то я уже не знаю как ещё объяснить. И всё это можно прочиать в документации на ядро Cortex, к которой я отсылал ещё вначале.
|
|
|
|
|
Oct 21 2015, 12:58
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (Golikov A. @ Oct 21 2015, 13:50)  Погодите-погодите... а зачем регион бит-банда включен в общую оперативную память? А если он не включен, то как линкер там может разместить какие-то переменные? Чего то я реально не понимаю, вот с сайта арма CODE #define MAILBOX 0x20004000 Теперь включаем наконец мозг, пробуем читать написанное и думаем что-же за адрес такой "0x20004000" и с чего-бы это вдруг линкеру не разместить там все, что угодно на свое усмотрение? Заодно следует подумать c какого бодуна вывалили такой дивного уродства пример работы с исключительно фиксированным адресом  . Для демонстрации работы могли-бы хоть что-то такое накропать: CODE unsigned int mailbox;
#define BITBAND_SRAM_REF (0x20000000) #define BITBAND_SRAM_BASE (0x22000000) #define MBX( bit ) \ *(unsigned int *)( (BITBAND_SRAM_BASE) + ( (unsigned int)&mailbox - (BITBAND_SRAM_REF) ) * 32 + ((bit) * 4) )
MBX(0) = TRUE; Ну а за такие комментарии: CODE #define MBX_B0 *((volatile unsigned int *)(BITBAND_SRAM(MAILBOX,0)))// Mailbox bit 7 .... MBX_B0 = 1; // Word write говнокодерам сляпавшим сей "пример" отдельное спасибо
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 21 2015, 13:09
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата (назовём его регион_A), что для каждого его бита в другом регионе адресного пространства (назовём его регион_B) все я понял... битбанд для области реальной памяти, я все никак не мог понять что вы с линкером договариваетесь об области реальной памяти, а не об регионе битбанда  на самом деле не сразу понятно.... теперь я понял почему регион у ТС битмапом завется  ))) Цитата говнокодерам сляпавшим сей "пример" отдельное спасибо Когда у человека все вокруг дибилы, ему стоит подумать о своей роли. Ваш статус снижен со среднеуважаемого до малоуважаемого. На форуме есть люди которые иногда или всегда хамят, но иногда они профессионалы своего дела, и иногда стоит потерпеть чтобы узнать что-то ценное. Вы же малоуважаемый zltigo - хамло без выхлопа. Ваши сообщения - это шум, который раздражает и мешает. Пример я взял с официального сайта арма, он строгий, четкий и понятный, а вы идите лесом!
|
|
|
|
|
Oct 22 2015, 08:47
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(copov @ Oct 22 2015, 11:33)  Зарезервировать в обычной SRAM по разному в разных средах. В Keil можно так: volatile uint32_t Var_for_bit __attribute__((at(0x20000000))); Это точно резервирование? После этого точно нельзя сделать вот так? : volatile uint32_t Var_for_bit1 __attribute__((at(0x20000000))); volatile uint32_t Var_for_bit2 __attribute__((at(0x20000001))); volatile uint32_t Var_for_bit3 __attribute__((at(0x20000000)));
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 22 2015, 09:00
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (copov @ Oct 22 2015, 10:05)  Область bit-band и так лежит вне области ОЗУ для данных... Разумеется это абсолютно не так. Посему, все что Вы написали далее не верно. Читайте документацию или хотя-бы то, что здесь разжевывали ( безрезультатно  , как вижу ) Голикову и Вам. QUOTE (copov @ Oct 22 2015, 11:33)  просто и в голову не приходило, что биты могут понадобиться не для обращения к периферии. Биты, как и байты и вообще любые структры, используюся для всего чего нужно. При этом при работе с битами чрезе bit-band получаем два ВАЖНЕЙШИХ эффекта: 1) Атомарность операци; 2) Выигрыш по скорости. Об этом уже тоже здесь писалось
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Oct 22 2015, 10:59
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 2-03-05
Из: Санкт-Петербург
Пользователь №: 3 012

|
Цитата(Сергей Борщ @ Oct 22 2015, 11:47)  Это точно резервирование?
После этого точно нельзя сделать вот так? : volatile uint32_t Var_for_bit1 __attribute__((at(0x20000000))); volatile uint32_t Var_for_bit2 __attribute__((at(0x20000001))); volatile uint32_t Var_for_bit3 __attribute__((at(0x20000000))); Нельзя переменные uint32_t должны располагаться по адресам кратным 4
|
|
|
|
|
Oct 22 2015, 11:18
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(copov @ Oct 22 2015, 13:59)  Нельзя переменные uint32_t должны располагаться по адресам кратным 4 Да, про это я не подумал, но вопрос был о другом. Пусть будет так: volatile uint32_t Var_for_bit1 __attribute__((at(0x20000000))); volatile uint32_t Var_for_bit2 __attribute__((at(0x20000004))); volatile uint32_t Var_for_bit3 __attribute__((at(0x20000000)));
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 22 2015, 13:32
|
Частый гость
 
Группа: Свой
Сообщений: 118
Регистрация: 2-03-05
Из: Санкт-Петербург
Пользователь №: 3 012

|
Цитата(Сергей Борщ @ Oct 22 2015, 14:18)  Да, про это я не подумал, но вопрос был о другом. Пусть будет так:
volatile uint32_t Var_for_bit1 __attribute__((at(0x20000000))); volatile uint32_t Var_for_bit2 __attribute__((at(0x20000004))); volatile uint32_t Var_for_bit3 __attribute__((at(0x20000000))); volatile uint32_t Var_for_bit1 __attribute__((at(0x20001000))); volatile uint32_t Var_for_bit2 __attribute__((at(0x20001004))); volatile uint32_t Var_for_bit3 __attribute__((at(0x20001000))); В Keil комплилятор ругается, что переменная Var_for_bit3 должна начинаться с 0x20001008 адреса. Что не удивительно - это прямая обязанность нормального компилятора (может быть только по-другому ругаться будет в другой среде разработки).
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|