Jump to content
    

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

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

Пишу тут описание регистров периферии для одного МК (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. Но сейчас ищу способ не захламлять список регистров при всплывающей подсказке.

Edited by Arlleex

Share this post


Link to post
Share on other sites

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 прямого ответа не дает.

Edited by Arlleex

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

Цитата

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

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

:smile:

Share this post


Link to post
Share on other sites

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

По поводу первого вопроса. Сделал через нижние подчеркивания, как бы намекая, что область системная и прямого манипулирования с этой областью не предусматривается. Поставил модификатор 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)

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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;

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...