Я не могу найти, в чем проблема ..
Проблема в том, что вы неправильно используете адрес, возвращаемый mmap () , который, кстати, вы не смогли проверить.
Возвращенный указатель присваивается указателю типа целое без знака.
static volatile unsigned int ... *UART;
...
UART = (unsigned int*)mmap(...);
Затем вы пытаетесь получить доступ к содержимому регистров UART, используя (неправильную) арифметику указателей, например:
IO = UART + 0x40;
Предположительно, 0x40 (и другие смещения, которые вы используете) - это смещение в байтах.
В выражении C <pointer> + <scaler>
, <scaler>
берется для представления количества с таким же размером, что и тип указателя (например, sizeof(unsigned int)
).
Только когда указатель является байтовым указателем, <scaler>
будет представлять количество байтов.
Так как UART
объявлен как указатель на 4-байтовое слово, ваш расчет указателя в
IO = UART + 0x40;
действительно эквивалентно
IO = (unsigned int *)((unsigned char *)UART + (sizeof(unsigned int) * 0x40));
, где sizeof(unsigned int)
равно 4 (байтам), а примененное смещение в четыре раза больше, чем вы предполагали.
Таким образом, вместо доступа к аппаратным регистрам UART, вы читаете случайные (возможно, несуществующие) области памяти. Такая ошибка кодирования может привести к ошибке шины, когда местоположение фактически недействительно.
Вы можете подтвердить эти операторы (или отладить свой код), используя printf () , чтобы сообщить значения UART
, IO
и другие переменные-указатели.
Обратите внимание, что большинство настроек termios влияют только на программные состояния, а не на регистры UART, причем заметными исключениями являются скорость передачи данных, кадрирование и CRTSCTS (управление потоком HW)