Крайне маловероятно, что для этого есть какое-либо портативное решение, не в последнюю очередь потому, что множество C -only платформ на самом деле C -только и используют одноразовые компиляторы, то есть ничего массового и современного-стандарта- податливый вроде g cc или лязг. Так что, если вы действительно нацеливаетесь на укоренившуюся C, тогда все это полностью зависит от платформы c и не переносимо - до такой степени, что поддержка «C99» становится безнадежной. Лучшее, что вы можете ожидать от переносимого кода C, - это поддержка ANSI C, относящаяся к самому первому не-черновому стандарту C, опубликованному ANSI. К сожалению, это до сих пор является общим знаменателем - крупные производители избегают неприятностей. Я имею в виду: Zilog каким-то образом сходит с рук, даже если сейчас они всего лишь подразделение Littelfuse, бывшего подразделения IXYS Semiconductor, которое приобрел Littelfuse.
Например, вот некоторые компиляторы, в которых есть только платформа. -specifi c способ сделать это:
Zilog eZ8 с использованием «недавнего» компилятора Zilog C (все, что старше 20 лет, в порядке): чтение 8-битного значения -modify-write - это atomi c. 16-битные операции, в которых компилятор генерирует словарные инструкции с выравниванием по словам, такие как LDWX
, INCW
, DECW
, также являются atomi c. Если чтение-изменение-запись в противном случае умещается в 3 инструкции или меньше, вы должны добавить операцию с помощью asm("\tATM");
. В противном случае вам нужно будет отключить прерывания: asm("\tPUSHF\n\tDI");
, а затем снова включить их: asm("\tPOPF");
.
Zilog ZNEO - это 16-битная платформа с 32-битными регистрами. , а доступ для чтения-изменения-записи к регистрам - это atomi c, но операции чтения-изменения-записи в памяти обычно выполняются через регистр и требуют 3 инструкции - таким образом, к операции RMW добавляется asm("\tATM")
.
Zilog Z80 и eZ80 требуют заключения кода в asm("\tDI")
и asm("\tEI")
, хотя это действительно только тогда, когда известно, что прерывания всегда разрешены при запуске вашего кода. Если они не могут быть включены, тогда возникает проблема, поскольку Z80 не позволяет считывать состояние IFF1
- триггер разрешения прерывания. Таким образом, вам нужно будет где-то сохранить «тень» его состояния и использовать это значение для условного включения прерываний. К сожалению, eZ80 не предоставляет регистр контроллера прерываний, который позволял бы получить доступ к IEF1
(eZ80 использует номенклатуру IEFn
вместо IFFn
), поэтому этот архитектурный упущение перенесено с почтенного Z80 на «современный». .
Это не обязательно самые популярные платформы, и многие люди не беспокоятся о компиляторах Zilog из-за их довольно низкого качества (достаточно низкого, чтобы вам действительно пришлось писать компилятор, ориентированный на eZ8 *). Тем не менее, такие странные углы являются основой кодовых баз, содержащих только C, и у библиотечного кода нет другого выбора, кроме как учесть это, если не напрямую, то, по крайней мере, путем предоставления макросов, которые можно переопределить с помощью специфичных для платформы c magi c.
Например, вы можете предоставить пустые по умолчанию макросы MYLIB_BEGIN_ATOMIC(vector)
и MYLIB_END_ATOMIC(vector)
, которые будут использоваться для обертывания кода, требующего доступа atomi c по отношению к данному вектору прерывания (или, например, -1
если по всем векторам прерываний). Естественно, замените MYLIB_
на префикс «пространства имен» c в вашей библиотеке.
Чтобы включить оптимизацию c для конкретной платформы, например ATM
vs DI
на «современных» платформах Zilog макросу может быть предоставлен дополнительный аргумент для разделения предполагаемых «коротких» последовательностей, для которых компилятор склонен генерировать последовательности из трех инструкций по сравнению с более длинными. Такая микрооптимизация обычно требует аудита вывода сборки (легко автоматизируемого) для проверки предположения о длине последовательности команд, но, по крайней мере, данные для принятия решения будут доступны, и у пользователя будет выбор: использовать их или игнорировать. .
* Если какая-то заблудшая душа хочет знать что-нибудь, граничащее с тайной рекой. eZ8 - спроси. Я слишком много знаю об этой платформе, в деталях настолько кровавых, что даже современной голливудской компьютерной графике и спецэффектам было бы сложно воспроизвести истинную глубину происходящего на экране. Я также, возможно, единственный, кто запускает части eZ8 с частотой 20 МГц время от времени на частоте 48 МГц - это верный признак одержимости демонами, насколько позволяет мультивселенная. Если вы считаете возмутительным, что такая развратность воплощается в производственном оборудовании - я с вами. Увы, бизнес-кейс есть бизнес-кейс, к черту l aws физики.