|
|
  |
Компиляция ПО под embedded. Непонятно как поступить., Как компилироваться - если используются функции ядра |
|
|
|
Jul 31 2015, 06:20
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Под плату SBC8600 (AM3359, Angstrom Linux) делаю программу. Есть Toolchain, и есть tools: для сборки ядра, u-boot и пр. под эту плату. Пока используются стандартные функции Си - то все нормально: ПО компилится Toolchain-ом, нормально запускается и работает. Но сейчас понадобился прямой доступ к регистрам микроконтроллера. Хочу сделать это так: Код base = ioremap(ADDR, SIZE); __raw_writel(base+0x08F0, DATA); x = __raw_readl(base+0x08F0); Но этот код не хочет компилироваться. Эти функции - принадлежат ядру и находятся в файлах: /arch/arm/include/asm/io.h. В самой Toolchain - нету такого файла и нету таких функций. Оно наверное и понятно - Toolchain вряд ли поддерживает функции ядра. Подключил к своему проекту h-файл из tools для сборки ядра - все равно не компилится: у меня ведь проект ядра не компилируется вместе с программой. Что делать - не знаю. Как вообще компилироваться - если используются функции ядра ? P.S. Пробовал сделать это через /dev/mem и mmap - все получается, но работает только на чтение. Записать не получается. Заранее спасибо.
|
|
|
|
|
Jul 31 2015, 08:58
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(Atridies @ Jul 31 2015, 09:20)  P.S. Пробовал сделать это через /dev/mem и mmap - все получается, но работает только на чтение. Записать не получается. покажите кусок кода - как вы инициализуете доступ и как обращаетесь.. с правами рута все прекрасно ммапится, читается и пишется (по крайней мере на архитектурах freescale, ti, pxa, atmel)
|
|
|
|
|
Jul 31 2015, 11:30
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(Atridies @ Jul 31 2015, 11:44)  Ясно.
А как писать и компилировать драйверы ? Как писАть сами драйверы - я читал несколько статей, думаю разберусь. А вот как компилить (Cross Compilatioin)? Надо использовать tools для сборки ядра ? Кросс компиляцию уже обсуждали: Сделайте поиск в форуме по ключевуму слову "eabi" Будут вопросы спрашивайте. В частности: http://electronix.ru/forum/index.php?showt...=eabi&st=45Одно из лучших руководств по напиасанию драйверов: http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf
Сообщение отредактировал Tarbal - Jul 31 2015, 11:30
|
|
|
|
|
Jul 31 2015, 15:44
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Вот попытка записать данные напрямую в память - через /dev/mem. Код int mfd; void * base; int regData; char str[100];
mfd = open("/dev/mem", O_RDWR);
if( mfd < 0 ) { printf("Cannot open /dev/mem.\n"); return 0; }
printf("/dev/mem opened.\n");
base = mmap(0, 0x00001000, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0x44E10000);
if (base == MAP_FAILED) { printf("Memory mapping error.\n"); return 0; //exit(EXIT_FAILURE); }
printf("Memory block mapped at address %p.\n", base);
regData = *((unsigned int*)(base + 0x0)); sprintf(str, "Revision = 0x%X", regData); puts(str);
regData = *((unsigned int*)(base + 0x600)); sprintf(str, "Device ID = 0x%X", regData); puts(str);
regData = *((unsigned int*)(base + 0x604)); sprintf(str, "Dev. feature = 0x%X", regData); puts(str);
regData = *((unsigned int*)(base + 0x8F0)); sprintf(str, "Pin MMC0_DAT3 = 0x%X", regData); puts(str);
*((unsigned int*)(base + 0x8F0)) = 0x34; sprintf(str, "Set pin MMC0_DAT3 = uart1_dcdn"); puts(str);
regData = *((unsigned int*)(base + 0x8F0)); sprintf(str, "Pin MMC0_DAT3 = 0x%X", regData); puts(str);
munmap(0, 0x00001000);
return 0; Проц: AM3359. В доке на него - указано, что запись в эти регистры может быть только в "privileged mode". Это от рута - или что-то другое ?
|
|
|
|
|
Jul 31 2015, 18:05
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(Atridies @ Jul 31 2015, 18:44)  Вот попытка записать данные напрямую в память - через /dev/mem. Проц: AM3359. В доке на него - указано, что запись в эти регистры может быть только в "privileged mode". Это от рута - или что-то другое ? если бы днем выложили сорц, то прямо на ам3359 и посмотрел бы что не так.. да, все действия от рута, иначе любой юзер завалит систему одним движением.. вот куски из рабочего кода (запускал на nuc950), с коррекцией адресов пойдет на другой АРМ-архитектуре Код #define XZ_BA 0xB0000000 #define MAP_BASE1 (XZ_BA)
#define MAP_SIZE 4096Ul #define MAP_MASK (MAP_SIZE - 1)
int fd; void *mapped_base1;
if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) { printf("Cannot open /dev/mem.\n"); exit(EXIT_FAILURE); } printf("/dev/mem opened.\n"); mapped_base1 = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, MAP_BASE1 & ~MAP_MASK);
if (mapped_base1 == (void *) -1) { printf("Memory mapping error.\n"); exit(EXIT_FAILURE); } printf("Check register MFSEL\n"); mapped_base1+=(MAP_BASE1 & MAP_MASK); printf("Target address mapped 0x%08x-->0x%08x\n",(int) MAP_BASE1,(int)mapped_base1); data = *(int*)(mapped_base1+0x00); printf("PDID =%08X\n",data);
|
|
|
|
|
Jul 31 2015, 19:44
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Днем у меня доступа к сорцам не было  . Ваш код - только читает из памяти. Это у меня тоже получается. У меня писАть не получается.
|
|
|
|
|
Jul 31 2015, 20:43
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(Atridies @ Jul 31 2015, 22:44)  Днем у меня доступа к сорцам не было  . Ваш код - только читает из памяти. Это у меня тоже получается. У меня писАть не получается. вот так пишу Код data = *(int*)(mapped_base1+0x0c); data = data & 0xffffdbff; *(int*)(mapped_base1+0x0c) = data; printf("MFSEL =%08X\n",data); это отладочный код, я его таскаю по всем платформам, всегда работает.. Цитата(Atridies @ Jul 31 2015, 10:44)  А как писать и компилировать драйверы ? Как писАть сами драйверы - я читал несколько статей, думаю разберусь. А вот как компилить (Cross Compilatioin)? Надо использовать tools для сборки ядра ? я с нуля драйверы не писал, но знаю пару вариантов: - в дереве исходников своего ядра находится близкоподходящий драйвер под свои нужды, клонируется под другим именем и прописывается в конфигурацию, потом меняется функционал под свое железо или алгоритм - многие компании-производители, в частности сетевых железяк, практикуют выкладывать пакет с исходниками драйверов под свои адаптеры/сетевые чипы - архив разворачивается, внутри правятся пути до исходников текущего ядра, далее сборка кросскомпилятором и получается модуль драйвера *.ko, который можно подгрузить в ядро для написания с нуля, вместо клонирования, создаете свой сишный файл в подходящем разделе дерева драйверов, прописываете в конфигурацию, потом долго и нудно изобретаете свои код, для обмена данными между железом и юзерспейсом, *.ko - профит.. в общем случае сетапиться линукс система (реальная или в виртуалке), на нее разворачивается дерево исходников ядра и архив с кросскомпилятором (aka тулчейн). в частности, для ам3359 можно раздобыть все в одном флаконе на ti.com или профильных форумах/комьюнити.. если накопитель на таргете (ам3359) большой и шустрый, то ядро можно собрать прямо в системе, не заморачиваясь х86 хостом и КК.. Цитата А вот как компилить (Cross Compilatioin)? не вижу смысла пересказывать 100 раз описанное, почитайте на том же ti.com местную twiki для am3359
|
|
|
|
|
Aug 1 2015, 06:50
|
Местный
  
Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468

|
Я пишу так: Код *((unsigned int*)(base + 0x8F0)) = 0x34; Собственно в регистры, не защищенные privileged режимом - все пишется нормально. Но конкретно нужные мне: Цитата "For writing to the control module registers, the Cortex A8 MPU will need to be in privileged mode of operation and writes will not work from user mode." Поэтому и не пишется.... Цитата не вижу смысла пересказывать 100 раз описанное, почитайте на том же ti.com местную twiki для am3359 Я вероятно неправильно задал вопрос. Каким компилятором - компилировать модули ядра? Тем, которым собирается ядро под target-платформу ?
|
|
|
|
|
Aug 1 2015, 06:58
|
Знающий
   
Группа: Участник
Сообщений: 745
Регистрация: 28-12-06
Пользователь №: 23 960

|
Цитата(Atridies @ Aug 1 2015, 09:50)  Каким компилятором - компилировать модули ядра? Тем, которым собирается ядро под target-платформу ? Да, тем которым собирали ядро под target. Еще понадобятся заголовки ядра.
|
|
|
|
|
Aug 3 2015, 20:21
|
Знающий
   
Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050

|
Цитата(Atridies @ Aug 1 2015, 09:50)  Я пишу так: Код *((unsigned int*)(base + 0x8F0)) = 0x34; Собственно в регистры, не защищенные privileged режимом - все пишется нормально. Но конкретно нужные мне: Поэтому и не пишется.... да, вы правы, действительно не пишется.. впрочем, народ это бодро обходит, по крайней мере для gpio. (насколько я помню, если в борд-файле не прописать нужный пин в gpio mode, то потом фиг его настроишь..) но вот тут вроде как через debugfs крутят: http://graycat.io/tutorials/beaglebone-io-using-python-mmap/
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|