Программирую Си на встраиваемой системе. Архитектура процессора 32 бита (sizeof(int)
- 32 бита, sizeof(short)
- 16 бит). Существует 32-битная переменная, представляющая собой управляющий регистр, отображенный на карте памяти (CTRL_REG
), который указан как используемые только нижние 16 бит, и они содержат подписанное 16-битное целое значение (запись в верхние бит не влияет на результат). Доступы к памяти должны быть выровнены по 32 битам, поэтому я не могу просто перекинуть указатель через пару байт, а также не могу предположить эндианность. Меня беспокоит то, что автоматическое продвижение типа будет портить все, что я храню, расширяя знаковый бит до бита 31, вместо того, чтобы оставлять его на бит 15, где я хочу. Как лучше всего хранить что-то в этом месте?
Вот мой оригинальный код, который, я почти уверен, неправильный:
#define CTRL_REG *((volatile unsigned int *)0x4000D008u)
short calibrationValue;
CTRL_REG = -2 * calibrationValue;
Тогда я попробовал это, но я думаю, что он все еще может быть подвержен целочисленному продвижению в точке назначения:
CTRL_REG = (short)(-2 * calibrationValue);
Тогда, наконец, я подумал об этом:
CTRL_REG = (unsigned short)(short)(-2 * calibrationValue);
Я не могу оценить эти опции очень хорошо, потому что все они работают в моих тестах, потому что калибровочное значение
бывает отрицательным (это калибровочный параметр, специфичный для каждого устройства, и поэтому может быть положительным на некоторых устройствах), поэтому после умножения на -2, я в конечном итоге сохраняю положительное значение и, таким образом, я на самом деле не сталкиваюсь с проблемой, которую я ожидаю в своих тестах.
Ваша помощь очень ценится, даже если это просто сказать "вы слишком много думаете".