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

Реализация безымянного пространства в структуре

Приветствую!

Пишу тут описание регистров периферии для одного МК (STM8, STVD/Cosmic).

Бывает так, что между двумя регистрами одной и той же периферии или блока находится пустое пространство (резерв). Так вот, в местах, где такие "дыры" по пару байт, я пользуюсь безымянными битовыми полями:

typedef volatile struct
{
	      u8 CR1;
	      u8 CR2;
	      u8 NCR2;
	const u8 FPR;
	const u8 NFPR;
	      u8 IAPSR;
	      u16 : 16;
	      u8 PUKR;
	      u8 : 8;
	      u8 DUKR;
}TNVM;

 

Но есть периферия, между регистрами которой очень много пространства (больше килобайта).

Пытался сделать так:

u8 : 95856;

 

Однако, даже если писать более короткие размеры

u8 : 16;

компилятор кричит на невозможность создания такого битового поля:

Цитата

#error cpstm8 STM8S003.h:46(14) invalid bitfield size

 

При этом открываю Dev-C++, копирую туда тот же самый код и компиляция проходит успешно (без ошибок, но с предупреждениями).

 

Кто-нибудь знает наиболее красивый способ объявить безымянную пустышку в структуре в произвольное количество байт, чтобы при доступе к элементам с включенной функцией автозавершения кода это пустое место не светилось никакими "Reserved1" и т.д.? Либо что-то типа безымянного массива (правда, я о таких не слышал). Решение нужно кроссплатформенное стандартное:blush:

P.S. Раньше так и делал - в нужном месте объявлял массив нужной размерности и давал ему имя Reservedx, x = 1, 2...N. Но сейчас ищу способ не захламлять список регистров при всплывающей подсказке.

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

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


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

ИМХО, лучше уж назвать их как-нибудь вроде "zReserved", чтобы сваливались в конец списка.

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


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

16 минут назад, aaarrr сказал:

ИМХО, лучше уж назвать их как-нибудь вроде "zReserved", чтобы сваливались в конец списка.

Печально:cray:

Не плодя тем, еще хотел бы осветить один момент.

Пишу файл startup.c с константным массивом, определяющим таблицу векторов прерываний:

typedef struct
{
	#define INT_OPERATION_CODE 0x82
	u8     INTOperationCode;
	
	void (*Handler)(void);
}TISRVector;


extern void ISR_ResetHandler(void);
extern void ISR_TrapHandler(void);
extern void ISR_TLIHandler(void);
...
extern void ISR_NVMHandler(void);

static const TISRVector ISRVectorTable[] =
{
	{INT_OPERATION_CODE, ISR_ResetHandler},
	{INT_OPERATION_CODE, ISR_TrapHandler},
	{INT_OPERATION_CODE, ISR_TLIHandler},
	{INT_OPERATION_CODE, ISR_AWUHandler},
	{INT_OPERATION_CODE, ISR_ClockHandler},
	{INT_OPERATION_CODE, ISR_EXTI0Handler},
	{INT_OPERATION_CODE, ISR_EXTI1Handler},
	{INT_OPERATION_CODE, ISR_EXTI2Handler},
	{INT_OPERATION_CODE, ISR_EXTI3Handler},
	{INT_OPERATION_CODE, ISR_EXTI4Handler},
	{0, 0},
	{0, 0},
	{INT_OPERATION_CODE, ISR_SPIHandler},
	{INT_OPERATION_CODE, ISR_TIM1FirstHandler},
	{INT_OPERATION_CODE, ISR_TIM1SecondHandler},
	{INT_OPERATION_CODE, ISR_TIM2FirstHandler},
	{INT_OPERATION_CODE, ISR_TIM2SecondHandler},
	{0, 0},
	{0, 0},
	{INT_OPERATION_CODE, ISR_USARTTxHandler},
	{INT_OPERATION_CODE, ISR_USARTRxHandler},
	{INT_OPERATION_CODE, ISR_I2CHandler},
	{0, 0},
	{0, 0},
	{INT_OPERATION_CODE, ISR_ADCHandler},
	{INT_OPERATION_CODE, ISR_TIM4Handler},
	{INT_OPERATION_CODE, ISR_NVMHandler},
	{0, 0},
	{0, 0},
	{0, 0},
	{0, 0},
	{0, 0},
};

 

Хочу теперь сделать хитрость. Чтобы в разных проектах заново не добавлять/удалять только нужные обработчики, я (как видно выше) определил для линкера все символы (имена обработчиков). Однако, как и следовало ожидать, при сборке проекта и отсутствии определенных обработчиков (их нет в таблице символов линкера), вылезли ошибки типа

Цитата

#error clnk debug\stm8s_fancontrol.lkf:1 symbol _ISR_TrapHandler not defined (Debug\start.o Debug\start.o )

 

Что бы я хотел: при отсутствии обработчика в проекте, считать, что он для текущего проекта и не используется, и подставить вместо этого имени значение 0 (хотя это и не так важно). В Keil для этого существовала опция [weak], которая, будучи определенной рядом с именем, указывала, что, если этот символ будет определен в проекте, то использоваться будет именно он. Если нет - то символ со спецификатором [weak].

Является ли стандартной фишкой компоновщика наличие команды, заставляющей обратить ненайденные символы в 0 или другое известное значение, или это бородатый вымысел и такого в принципе не предусматривается? Беглый взгляд на описание компоновщика под Cosmic прямого ответа не дает.

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

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


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

weak в том или ином виде должен быть у всех. Ну а если хотите переносимо - делайте обертку.

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


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

А зачем битовые поля? Задавайте байты, я называю Reserved_ и номер или адрес добавляю. А если нужно много байтов, тогда - массив. 

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


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

4 часа назад, ViKo сказал:

А зачем битовые поля? Задавайте байты, я называю Reserved_ и номер или адрес добавляю. А если нужно много байтов, тогда - массив. 

Мой первый пост:

Цитата

Кто-нибудь знает наиболее красивый способ объявить безымянную пустышку в структуре в произвольное количество байт, чтобы при доступе к элементам с включенной функцией автозавершения кода это пустое место не светилось никакими "Reserved1" и т.д.? Либо что-то типа безымянного массива (правда, я о таких не слышал). Решение нужно кроссплатформенное стандартное:blush:

P.S. Раньше так и делал - в нужном месте объявлял массив нужной размерности и давал ему имя Reservedx, x = 1, 2...N. Но сейчас ищу способ не захламлять список регистров при всплывающей подсказке.

:smile:

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


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

Итак, что в итоге.

По поводу первого вопроса. Сделал через нижние подчеркивания, как бы намекая, что область системная и прямого манипулирования с этой областью не предусматривается. Поставил модификатор const, чтобы нельзя было туда записать в явном виде (как жаль, что нет модификатора запрета и чтения в Си):

...

typedef volatile struct
{
	      u8 CR1;
	      u8 CR2;
	      u8 FREQR;
	      u8 OARL;
	      u8 OARH;
	const u8 __RESERVE__[1];
	      u8 DR;
	const u8 SR1;
	      u8 SR2;
	const u8 SR3;
	      u8 ITR;
	      u8 CCRL;
	      u8 CCRH;
	      u8 TRISER;
}TI2C;

...

 

По поводу weak-символов. Получил официальный ответ от Cosmic.

Оказывается, weak-символы поддерживаются в компиляторах Cosmic только в версиях, начиная с 4.4.7.

Синтаксис следующий:

void @weak function(void)
{...}

 

Текст официального ответа от Cosmic:

Цитата

Hello,
The weak feature is experimentally supported in the STM8 compiler from version V4.4.7 and not currently described in the manual. The syntax uses the @weak modifier placed before a function name:

void @weak func(void)

 

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


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

Вряд ли вы сами в здравом уме будете записывать в переменную RESERVED, так что можно быть проще.

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


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

3 часа назад, Arlleex сказал:

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

Вроде как имена окаймлённые двойным подчёркиванием обычно зарезервированы для нужд компилятора или идущих с ним стандартных хидеров. Поэтому такие имена лучше не использовать, во избежание конфликтов и недоразумений.

Я такие поля обычно обзываю unuseXX. Визуально оно чётко отличается от действительных полей, так как те написаны большими буквами.

Спойлер

//GPIO
typedef struct {
  u32 OUT;
  union {
    u32 OM;
    struct {
      u16 OMS;
      u16 OMR;
    };
  };
  u32 unuse0[2];
  union {
    u32 IOCR[4];
    u8 IOCR8[16];
  };
  u32 unuse1[1];
  u32 IN;
  u32 unuse2[6];
  u32 PDR[2];
  u32 unuse3[6];
  u32 PDISC;
  u32 unuse4[3];
  u32 PPS;
  u32 HWSEL;
  u32 unuse5[34];
} HwRegsGPIO;

 

 

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


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

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

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

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

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

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

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

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

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

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