реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Компиляция ПО под embedded. Непонятно как поступить., Как компилироваться - если используются функции ядра
Atridies
сообщение Jul 31 2015, 06:20
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 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 - все получается, но работает только на чтение. Записать не получается.

Заранее спасибо.
Go to the top of the page
 
+Quote Post
krux
сообщение Jul 31 2015, 06:28
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596



капитан очевидность какбы подсказывает:
функции ядра можно использовать только в ядре. (в kernel-space)
если вам надо работать с железом напрямую - то в линукс это возможно только в ядерном модуле, т.е. в драйвере.
из простого ПО (user-space) прямой доступ к железу не предусматривался, и противоречит философии linux.


--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
Go to the top of the page
 
+Quote Post
Atridies
сообщение Jul 31 2015, 07:44
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Ясно.

А как писать и компилировать драйверы ? Как писАть сами драйверы - я читал несколько статей, думаю разберусь.
А вот как компилить (Cross Compilatioin)? Надо использовать tools для сборки ядра ?
Go to the top of the page
 
+Quote Post
Jury093
сообщение Jul 31 2015, 08:58
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(Atridies @ Jul 31 2015, 09:20) *
P.S. Пробовал сделать это через /dev/mem и mmap - все получается, но работает только на чтение. Записать не получается.

покажите кусок кода - как вы инициализуете доступ и как обращаетесь..
с правами рута все прекрасно ммапится, читается и пишется (по крайней мере на архитектурах freescale, ti, pxa, atmel)
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Jul 31 2015, 11:30
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Atridies
сообщение Jul 31 2015, 15:44
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 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". Это от рута - или что-то другое ?
Go to the top of the page
 
+Quote Post
Jury093
сообщение Jul 31 2015, 18:05
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 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);
Go to the top of the page
 
+Quote Post
Atridies
сообщение Jul 31 2015, 19:44
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 445
Регистрация: 7-02-05
Из: Зеленоград
Пользователь №: 2 468



Днем у меня доступа к сорцам не было sm.gif.

Ваш код - только читает из памяти. Это у меня тоже получается. У меня писАть не получается.
Go to the top of the page
 
+Quote Post
Jury093
сообщение Jul 31 2015, 20:43
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 959
Регистрация: 11-01-06
Из: Санкт-Петербург
Пользователь №: 13 050



Цитата(Atridies @ Jul 31 2015, 22:44) *
Днем у меня доступа к сорцам не было sm.gif.
Ваш код - только читает из памяти. Это у меня тоже получается. У меня писАть не получается.

вот так пишу
Код
    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
Go to the top of the page
 
+Quote Post
Atridies
сообщение Aug 1 2015, 06:50
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 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-платформу ?
Go to the top of the page
 
+Quote Post
_3m
сообщение Aug 1 2015, 06:58
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 745
Регистрация: 28-12-06
Пользователь №: 23 960



Цитата(Atridies @ Aug 1 2015, 09:50) *
Каким компилятором - компилировать модули ядра? Тем, которым собирается ядро под target-платформу ?

Да, тем которым собирали ядро под target.
Еще понадобятся заголовки ядра.
Go to the top of the page
 
+Quote Post
Jury093
сообщение Aug 3 2015, 20:21
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 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/
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 06:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.0147 секунд с 7
ELECTRONIX ©2004-2016