реклама на сайте
подробности

 
 
> описание регистров
grau
сообщение Mar 19 2007, 14:34
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 3-02-05
Пользователь №: 2 390



Salute!

А существует ли компиляторонезависимая возможность в C/Cpp осуществлять доступ к ячейкам памяти, и к их битовым полям? К примеру Reg.Bits = 1 устанавливает бит по адресу 0x0014.

Да, и без использования #define.

Что-то мне пока только нечто монстроидальное придумывается..

Best regards
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 6)
SM
сообщение Mar 19 2007, 14:49
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(grau @ Mar 19 2007, 14:34) *
Да, и без использования #define.


А чем #define не по душе - с ним все удобно и не монстроидально.
Go to the top of the page
 
+Quote Post
Pathfinder
сообщение Mar 19 2007, 15:55
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 275
Регистрация: 29-06-05
Пользователь №: 6 400



Компиляторонезависимая - только через маски.
Если нужно компактно хранить несколько мало-битных полей, можно объявлять примерно так:
Код
struct MyStruct
{
  int field1 : 2;
  int field2 : 5;
  bool field3 : 1;
}

Для поля field1 будет использовано 2 бита, для field2 - 5, для field3 соотв. - 1. В целом структура будет длиной 8 байт без учета выравнивания.


--------------------
ADC / DAC LC Filter Designer — Удобный инструмент проектирования LC-фильтров для ЦАП и АЦП
Go to the top of the page
 
+Quote Post
Doka
сообщение Mar 19 2007, 16:34
Сообщение #4


Electrical Engineer
******

Группа: СуперМодераторы
Сообщений: 2 163
Регистрация: 4-10-04
Пользователь №: 778



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


--------------------
Блог iDoka.ru
CV linkedin.com/in/iDoka
Sources github.com/iDoka


Never stop thinking...........................
Go to the top of the page
 
+Quote Post
grau
сообщение Mar 20 2007, 12:01
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 3-02-05
Пользователь №: 2 390



Salute!

Посидел, подумал..

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

Основная идея которая придумалась - это использование конструкции вида

Код
//-----------------------------------------------------------------------------
template <unsigned A, unsigned P, unsigned L>
class CBitsRW{
public:    
    void operator = (unsigned Val){
        *((volatile unsigned*) A) &= ~(((1<<L)-1)<<P);
        *((volatile unsigned*) A) |= ((Val&((1<<L)-1))<<P);
    };
    operator unsigned(){
        return ((*((volatile unsigned*) A))>>P)&((1<<L)-1);
    }
};
//-----------------------------------------------------------------------------
template <unsigned A>
class CMixReg {
public:
    CBitsRW<A, 0, 2> First;
    CBitsRW<A, 2, 6> Second;
    
    void operator = (unsigned Val)  {    
         *((volatile unsigned*) A) = Val;     
    };
    operator unsigned() {                    
         return *((volatile unsigned*) A);    
    }
};
//-----------------------------------------------------------------------------
// example
CMixReg MixReg;

MixReg.First = 1;



В качестве примера - описал так регистры USB в LPC2148 (в прикрепленном файле). Громоздко это все очень.

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

Best regards
Go to the top of the page
 
+Quote Post
SasaTheProgramme...
сообщение Mar 25 2007, 00:25
Сообщение #6


Частый гость
**

Группа: Новичок
Сообщений: 129
Регистрация: 4-08-06
Пользователь №: 19 327



Цитата(Pathfinder @ Mar 19 2007, 14:55) *
Компиляторонезависимая - только через маски.
Если нужно компактно хранить несколько мало-битных полей, можно объявлять примерно так:
Код
struct MyStruct
{
  int field1 : 2;
  int field2 : 5;
  bool field3 : 1;
}

Для поля field1 будет использовано 2 бита, для field2 - 5, для field3 соотв. - 1. В целом структура будет длиной 8 байт без учета выравнивания.

У какого-то компилятора (увы, уже не помню у какого) был "прикол" - для каждого поля выделялся отдельный int, если они перечислялись через ';'. Эти же поля упаковывались при перечислении через запятую. А байтовые поля вообще, кажется, никаким компилятором не понимаются, только int'ы в той разрядности, в которой это понимает компилятор (ну так K&R заложили).
Т.е. самое коректное, безопасное и переносимое - действительно через маски.
Go to the top of the page
 
+Quote Post
grau
сообщение Mar 26 2007, 13:42
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 49
Регистрация: 3-02-05
Пользователь №: 2 390



Цитата(SasaTheProgrammer @ Mar 25 2007, 01:25) *
У какого-то компилятора (увы, уже не помню у какого) был "прикол" -


Сейчас ради интереса заглянул в стандарт. Там по поводу переносимости битовых сказано достаточно четко:

//-----------------------------------------------------------------------------
Allocation of bit-fields within a class object is implementation-defined.
Alignment of bit-fields is implementation-defined.
//-----------------------------------------------------------------------------
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 06:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016