Arlleex 131 11 декабря, 2018 Опубликовано 11 декабря, 2018 (изменено) · Жалоба Приветствую! Пишу тут описание регистров периферии для одного МК (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" и т.д.? Либо что-то типа безымянного массива (правда, я о таких не слышал). Решение нужно кроссплатформенное стандартное P.S. Раньше так и делал - в нужном месте объявлял массив нужной размерности и давал ему имя Reservedx, x = 1, 2...N. Но сейчас ищу способ не захламлять список регистров при всплывающей подсказке. Изменено 11 декабря, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 11 декабря, 2018 Опубликовано 11 декабря, 2018 · Жалоба ИМХО, лучше уж назвать их как-нибудь вроде "zReserved", чтобы сваливались в конец списка. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 11 декабря, 2018 Опубликовано 11 декабря, 2018 (изменено) · Жалоба 16 минут назад, aaarrr сказал: ИМХО, лучше уж назвать их как-нибудь вроде "zReserved", чтобы сваливались в конец списка. Печально Не плодя тем, еще хотел бы осветить один момент. Пишу файл 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 прямого ответа не дает. Изменено 11 декабря, 2018 пользователем Arlleex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 11 декабря, 2018 Опубликовано 11 декабря, 2018 · Жалоба weak в том или ином виде должен быть у всех. Ну а если хотите переносимо - делайте обертку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 11 декабря, 2018 Опубликовано 11 декабря, 2018 · Жалоба Понял, благодарю! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба А зачем битовые поля? Задавайте байты, я называю Reserved_ и номер или адрес добавляю. А если нужно много байтов, тогда - массив. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба 4 часа назад, ViKo сказал: А зачем битовые поля? Задавайте байты, я называю Reserved_ и номер или адрес добавляю. А если нужно много байтов, тогда - массив. Мой первый пост: Цитата Кто-нибудь знает наиболее красивый способ объявить безымянную пустышку в структуре в произвольное количество байт, чтобы при доступе к элементам с включенной функцией автозавершения кода это пустое место не светилось никакими "Reserved1" и т.д.? Либо что-то типа безымянного массива (правда, я о таких не слышал). Решение нужно кроссплатформенное стандартное P.S. Раньше так и делал - в нужном месте объявлял массив нужной размерности и давал ему имя Reservedx, x = 1, 2...N. Но сейчас ищу способ не захламлять список регистров при всплывающей подсказке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 декабря, 2018 Опубликовано 12 декабря, 2018 · Жалоба Вот так и делайте. Как все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 131 14 декабря, 2018 Опубликовано 14 декабря, 2018 · Жалоба Итак, что в итоге. По поводу первого вопроса. Сделал через нижние подчеркивания, как бы намекая, что область системная и прямого манипулирования с этой областью не предусматривается. Поставил модификатор 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) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 14 декабря, 2018 Опубликовано 14 декабря, 2018 · Жалоба Вряд ли вы сами в здравом уме будете записывать в переменную RESERVED, так что можно быть проще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 14 декабря, 2018 Опубликовано 14 декабря, 2018 · Жалоба 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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться