Избегайте битовых полей, они, как известно, являются проблемой с языком C, ненадежными, непереносимыми и могут быть изменены в любое время.И в любом случае я не помогу вам с этой проблемой.
Союзы тоже приходят на ум, но я исправлял достаточно много раз, чтобы вы не могли использовать союзы для изменения типов в соответствии со стандартами C.Хотя, как я предполагаю с другим автором, я еще не видел случая, когда использование объединения для изменения типов не работало.Разбитые битовые поля, постоянно нарушенное совместное использование памяти, пока что безболезненно.И профсоюзы не спасут вас ни одного оперативного плеера, поэтому он здесь не работает.
Почему вы пытаетесь заставить компилятор работать?Во время компиляции вам понадобится какой-нибудь сценарий типа компоновщика, который инструктирует компилятору делать 32-битные обращения с масками, сдвигами, чтением-изменением-записью, для некоторых адресных пространств, а для других - более естественным словом, полусловом идоступ к байту.Я не слышал ни о gcc, ни о языке C, имеющем такие элементы управления, будь то в синтаксисе, скрипте компилятора или каком-либо файле определения.И если он существует, он не используется достаточно широко, чтобы быть надежным, я бы ожидал ошибок компилятора и избегал этого.Я просто не вижу, чтобы компилятор делал это, конечно, не в структурной манере.
Для чтения вам может повезти, он сильно зависит от аппаратного обеспечения.Где этот интерфейс памяти nvram, внутри чипа, изготовленного вашей компанией, другой компанией, на краю чипа и т. Д.?Ограничение, подобное тому, которое вы описываете частично, может означать, что управляющие сигналы, которые различают размер доступа или байтовые дорожки, могут игнорироваться.Таким образом, ldrb может выглядеть как nvram как 32-битное чтение, и рука будет захватывать правильную байтовую дорожку, потому что думает, что это 8-битное чтение.Я хотел бы провести несколько экспериментов, чтобы убедиться в этом, так как имеется более одной шины памяти, каждая из которых имеет много разных типов передач.Возможно, поговорите с аппаратными специалистами или проведите некоторые hdl-симуляции, если у вас есть такая возможность, чтобы увидеть, что на самом деле делает рука.Если вы не можете использовать этот ярлык, чтение будет ldr с возможной маской и сдвигом, независимо от того, как вы заставите компилятор это сделать.
Запись, отличная от размера слова, должна выполняться для чтения, изменения и записи.ldr, bic, shift или or, str.Неважно, кто это делает, вы или компилятор.
Просто сделайте это сами, я не могу понять, как компилятор сделает это за вас.Компиляторам, в том числе gcc, довольно трудно выполнять определенный доступ, который, как вам кажется, говорят:
*(volatile unsigned int *)(SOME_ALIGNED_ADDRESS)=some_value;
Мой синтаксис, вероятно, неверен, потому что я отказался от него несколько лет назад, но он не всегда выдает неподписанныйint size store, и когда компилятор не хочет, он не будет.если он не может сделать это надежно, как вы можете ожидать, что он создаст один набор загрузок и хранилищ для этой переменной или структуры и другой вариант для этой переменной или структуры?
Итак, если у вас есть конкретные инструкции, вам нужен компилятор дляпроизводить, у вас не получится, вы должны использовать ассемблер, точка.В частности, ldm, ldrd, ldr, ldrh, ldrb, strd, str, strh, strb и stm.
Я не знаю, сколько у вас nvram, но мне кажется, что решение вашей проблемы состоит в том, чтобы сделать всев нврам размером 32 бита.Вы выполняете несколько дополнительных циклов, выполняя контрольную сумму, но ваше пространство кода и (энергозависимое) использование оперативной памяти минимально.Требуется очень мало сборки (или нет, если вам это удобно).
Я также рекомендую попробовать другие компиляторы, если вас беспокоит такая большая оптимизация.Как минимум попробуйте gcc 3.x, gcc 4.x, llvm и rvct, которые, я думаю, есть версия, которая поставляется с Keil (но не знаю, как она сравнивается с реальным компилятором rvct).
Я не чувствую, насколько маленьким должен быть ваш двоичный файл.Если вам нужно упаковать вещи в nvram и вы не можете создать все 32-битные записи, я бы порекомендовал несколько вспомогательных функций ассемблера, один вариант get32 и put32, два варианта get16 и put16 и четыре варианта get8 и put8.Вы будете знать, как пишете код, в который упакованы вещи, так что вы можете писать код напрямую или с помощью макросов / определяет, какой вариант get16 или put8.Эти функции должны иметь только один параметр, так что при их использовании не требуется затрат места на коде, производительность в виде сброса канала в ветви, в зависимости от вашего вида ядра.Что я не знаю, так это то, что эти 50 или 100 инструкций функций put и get нарушают ваш бюджет размера кода?Если так, то мне интересно, стоит ли вам вообще использовать C?В частности, gcc.
И вы, вероятно, захотите использовать thumb вместо arm, если размер очень важен, thumb2, если он у вас есть.
Я не понимаю, как заставить компилятор это делать.для вас может потребоваться какая-то прагма, специфичная для компилятора, которая, вероятно, будет редко использоваться и содержать ошибки, если она существует.
Какое ядро вы используете?Я недавно работал с кем-то из семейства arm 11 с шиной Axi, и рука действительно хорошо справляется с преобразованием последовательностей ldrs, ldrbs, ldrhs и т. Д. В отдельные 32- или 64-битные чтения (да, несколько отдельных инструкций могут превратиться водин цикл памяти).Возможно, вам просто придется адаптировать свой код к функциям ядра, в зависимости от ядра и того, где находится этот интерфейс для поддержки памяти nvram.Для этого пришлось бы сделать много симов, я знаю это только по тому, что смотрел на автобус, а не из документации по руке.