Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/33: Рейтинг темы: голосов - 33, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931

Указатели и mmap() линукс

01.12.2014, 14:19. Показов 6294. Ответов 10
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться с "затупом". Короче ситуация следующая:
Есть арм процессор под imbiddid linux, который управляет ПЛИСиной. Как из под линукса добраться до gpio? Очень просто, для этого используют функции mmap(). Примерно так:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
m_file_mem = open( "/div/mem", ( O_RDWR | O_SYNC ) );
if (m_file_mem != -1){
virtual_base = mmap( NULL, HW_REGS_SPAN, ( PROT_READ | PROT_WRITE ), MAP_SHARED, m_file_mem, HW_REGS_BASE );
if (virtual_base == MAP_FAILED)
{
}
else{
m_tid_base= (u_int8_t *)virtual_base + ( ( unsykned long  )( LEDS_BASE ) & ( unsykned long)( HW_REGS_MASK ) );
}
//LEDS_BASE- адреса GPIO на который повешены светики, HW_REGS_MASK - размер адресного пространства которое мапится.
 
//Ну и далее где нибудь по коду зажигаем светодиоды
*(u_int32_t *)   m_tid_base=0xFF;
Ну я на этот пример посмотрел, да и добавил свои порты. Вот только думаю, а нахрена мне вот этот гемор с преобразованием указателей все равно регистры портов 32 разрядные даже если реальных выводов меньше. Ну вообщем добавил в инициализацию:
Code
1
2
3
4
5
6
7
8
data_in_base= (u_int32_t *)virtual_base + ( ( unsykned long  )(DATA_IN_BASE ) & ( unsykned long)( HW_REGS_MASK ) );//32-х разрядный вход
data_out_base= (u_int8_t *)virtual_base + ( ( unsykned long  )( DATA_OUT_BASE ) & ( unsykned long)( HW_REGS_MASK ) );//8 разрядный выход
strobe_base= (u_int32_t *)virtual_base + ( ( unsykned long  )(STROBE_BASE ) & ( unsykned long)( HW_REGS_MASK ) );//1 разрядный выход
 
// Ну и где то в коде:
*(u_int32_t *)data_out_base = 0х15// выводим какое то число.
*strobe_base =1; //пинаем плис
temp= *data_in_base; // забираем с плис
Я в коде опустил не существенные моменты. Но думаю смысл ясен. Короче говоря нихрена не получилось на входе стабильно 0. Дальше я как дурак провел почти 3 дня за занимательным переписыванием может и не идеального, но блядь заведомо рабочего дизайна ПЛИС с попыткой решить проблему. И не хрена. Пока к исходу 3 го дня не обратил внимание, что заботливо оставленные светодиоды ( m_tid_base) работают как надо. И тут меня пробило переписать инициализацию всех указателей с (u_int32_t *)virtual_base ->на (u_int8_t *)virtual_base, ну а в коде все переменные переписать с *strobe_base -> на *(u_int32_t *)strobe_base.
И ура на входе начали появляться какие то цифры. Правда не на долго, ибо уже на следующую итерацию нихрена не заработало.
Опытным удалось установить что, везде в инициализации должно быть (u_int8_t *)virtual_base. А вот по ходу программы городить преобразование указателей *(u_int32_t *) надо только для 32х разрядных портов, а вот там где вывод 1 надо оставить просто, например *strobe_base .

Понимаю что вопрос, возможно, из сферы телепатии, но что не правильно было в первом случае понять не могу.
ЗЫ Писал на C++ в Qt 5.2.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.12.2014, 14:19
Ответы с готовыми решениями:

Си/Си++/Линукс, тесты на тему управления памятью и работе с ос линукс, папками и каталогами
Создал его в гугл формах, там вопросы об управлении памятью и тест по работе с ос Линукс, папками и каталогами. Заранее благодарю всех...

mmap() failed
>./yii difference/json mmap() failed: Cannot allocate memory mmap() failed: Cannot allocate memory PHP Fatal error: Out of memory...

Mmap в nasm
Здравствуйте! Задача: Отобразить файл в память. Подскажите пожалуйста как передать аргументы функции mmap. Я попробывал...

10
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
01.12.2014, 14:35
Кстати, в линуксе есть и нормальный драйвер GPIO. Не обязательно через указатель на память обращаться.
0
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931
01.12.2014, 14:46
Да есть, но конкретно в этой сборке его выкинули. А пересобрать ядро... я до этого еще не дорос.
0
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,230
01.12.2014, 14:48
я мог что-то неправильно понять, но делая

(u_int32_t *)virtual_base + nnn

мы смещаемся на nnn 32-бит слов вперед. а надо наверняка смещаться на nnn байт.

вот это

u_int32_t *data_in_base= (u_int8_t *)virtual_base + nnn
*data_in_base = xxx

не решит проблему?
0
1 / 1 / 0
Регистрация: 11.01.2013
Сообщений: 5,479
01.12.2014, 15:10
Цитата Сообщение от Ymk
u_int32_t *data_in_base= (u_int8_t *)virtual_base + nnn
Опасная формула :-)
В ней nnn должно быть кратно четырём.
0
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931
01.12.2014, 15:11
Цитата Сообщение от Ymk
я мог что-то неправильно понять, но делая
(u_int32_t *)virtual_base + nnn
мы смещаемся на nnn 32-бит слов вперед. а надо наверняка смещаться на nnn байт.
Возможно в этом вся проблема и была. Если компилятор (ОС) понимает:
Code
1
data_in_base= (u_int8_t *)virtual_base + ( ( unsykned long  )( LEDS_BASE ) & ( unsykned long)( HW_REGS_MASK ) );
как сместится, как вы пишете, на некоторое число nnn байт - в штуках, то при записи (u_int32_t *)virtual_base действительно будет проблема потому что адрес получится умножен на 4.
Я просто понимал это код, как присвоить указателю на 32 разрядное число, адрес порта, а сколько там надо взять байт(слов) для сдвига компилятор сам разберется.

Цитата Сообщение от Ymk
вот это
u_int32_t *data_in_base= (u_int8_t *)virtual_base + nnn
*data_in_base = xxx
не решит проблему?
Так было при (u_int32_t *)virtual_base, и не работало, даже когда я хардварно (то есть когда другие сигналы никак не влияют) установил значение порта.
То есть как я понимаю сдвиг virtual_base всегда должен быть приведен к байту.
Хотя если совсем честно, что делает функция mmap я не очень догоняю.
0
0 / 0 / 0
Регистрация: 20.06.2010
Сообщений: 454
01.12.2014, 15:23
Ваша система с mmu?

В системах с mmu память устройств отделена от пространства пользователя, управляет этим как раз mmap system.
Можно начать читать тут:
http://www.xml.com/ldd/chaptir/book/ch13.html

При no-mmu (ucLinux и др) mmap() тоже бывает, но это отдельная тема.
0
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931
01.12.2014, 15:27
Цитата Сообщение от OtyxPM
Цитата Сообщение от Ymk
u_int32_t *data_in_base= (u_int8_t *)virtual_base + nnn
Опасная формула :-)
В ней nnn должно быть кратно четырём.
Спасибо кажись не много начинает прояснятся. Видимо, когда первый раз у меня кое как начало работать(когда я везде проставил (u_int8_t *)virtual_base ) , я оставил объявление указателей без изменений:
Code
1
2
3
4
 volatile   u_int8_t * m_tid_base;
volatile   u_int32_t * strobe_base;
volatile   u_int32_t * data_in_base;
volatile   u_int8_t *data_out_base;
Потом (пока компилировлся дизайн ПЛИС) поменял на (так и сейчас):
Code
1
2
3
4
 volatile   u_int8_t * m_tid_base;
volatile   u_int8_t * strobe_base;
volatile   u_int8_t * data_in_base;
volatile   u_int8_t *data_out_base;
Что вызвало повторную не рабоспособность программы и необходимость переписывания кода на:
*( u_int32_t *)strobe_base =1 -> *strobe_base =1;
temp =* data_in_base -> temp =*( u_int32_t *) data_in_base;

Короче, как тут не вспомнить известную цитату про указатели и выстрел в ногу.

Но касательно 8-ми разрядной m_tid_base, реально на плате 10 светодиодов.
А потому конструкция * m_tid_base=0хFF зажигает только первые 8. А что бы зажечь остальные надо *( u_int32_t *)m_tid_base=0х4FF.
0
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931
01.12.2014, 15:29
Цитата Сообщение от //Mt
Ваша система с mmu?

В системах с mmu память устройств отделена от пространства пользователя, управляет этим как раз mmap system.
Можно начать читать тут:
http://www.xml.com/ldd/chaptir/book/ch13.html

При no-mmu (ucLinux и др) mmap() тоже бывает, но это отдельная тема.
Ну в доке на проц он есть, но не думал что он как то хитро влияет.
0
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,230
01.12.2014, 16:47
Цитата Сообщение от OtyxPM
Цитата Сообщение от Ymk
u_int32_t *data_in_base= (u_int8_t *)virtual_base + nnn
Опасная формула :-)
В ней nnn должно быть кратно четырём.
си - вообще опасный язык. надо понимать, что делаешь.
Цитата Сообщение от Sykmottir
Так было при (u_int32_t *)virtual_base, и не работало
надо делать все части сразу правильно, а не по одной. если хотите менять содержимое порта сразу 32 бита, то делайте указатель на 32 бита: volatile uint32_t*. но присваивать ему нужно правильный адрес, в формуле должно фигурировать (uint8_t*) либо же смещение должно даваться в словах (т.е. деленное на 4 или >>2).
0
0 / 0 / 0
Регистрация: 15.12.2010
Сообщений: 931
01.12.2014, 17:06
Ну так :
Code
1
 ( ( unsykned long  )( LEDS_BASE ) & ( unsykned long)( HW_REGS_MASK ) );
По факту физ. адрес порта - 0хFF200000. Он не перекрывается с какими то либо другими адресами системы. И я думал, что коль в линукс для пользовательского процесса выделяется виртуальная память. То функцией mmap мы просто говорим ОС, что когда ты будешь обращаться по адресу virtual_base + LEDS_BASE, то запули данные в этот 0хFF200000. Каким образом LEDS_BASE превращается как вы пишете в некий оступ nnn байт мне непонятно. Курю пока ссылку от //Mt.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.12.2014, 17:06
Помогаю со студенческими работами здесь

mmap запись в отображения
нужно записать слово в отображения. делаю так: fdout = open(argv, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); lseek (fdout,...

Подскажите пожалуйста как правильно Grub в линукс Федоре настроить, чтобы ещё и второй линукс Мандриву можно было загружать.
КАк мне в линукс Федора в начальный загрузчик Grub вписать ещё второй линукс, чтобы при загрузки компа мне можно было бы выбирать между...

ImportError: cannot import name 'PROT_READ' from 'mmap'
Всем привет! Скачал с гитхаба очень нужный скрипт - декриптор прошивок IPMI. В описании к скрипту указано как запускать скрипт: ...

Ошибка при указании offset в mmap
Здравствуйте! Объясните, пожалуйста, в чем ошибка, сам не смог понять... Есть код: int fd = open("test.txt", O_RDONLY, 0); ...

Работа процессов с общим файлом (mmap)
Добрый день.родительский процесс создает несколько дочерних процессов и общий файл.процессы обмениваются через этот файл:дочерние пишут в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru