2016-10-19 1 views
0

Я следил за вики xilinx о драйверах Linux (Linux-GPIO-Driver), чтобы управлять GPIO, подключенным к PS через контакты MIO и EMIO.Управление пользовательскими IP-устройствами, подключенными к AXI в Zybo под Linux OS

Затем я добавил некоторые базовые периферийные устройства к PL, подключенным к PS автобусами AXI. Это мой дизайн:

enter image description here

Этот файл, который содержит информацию периферийное PL, автоматически генерируется в источниках дерево устройств:

/ { 
amba_pl: amba_pl { 
    #address-cells = <1>; 
    #size-cells = <1>; 
    compatible = "simple-bus"; 
    ranges ; 
    axi_gpio_0: [email protected] { 
     #gpio-cells = <2>; 
     compatible = "xlnx,xps-gpio-1.00.a"; 
     gpio-controller ; 
     reg = <0x41200000 0x10000>; 
     xlnx,all-inputs = <0x0>; 
     xlnx,all-inputs-2 = <0x0>; 
     xlnx,all-outputs = <0x0>; 
     xlnx,all-outputs-2 = <0x0>; 
     xlnx,dout-default = <0x00000000>; 
     xlnx,dout-default-2 = <0x00000000>; 
     xlnx,gpio-width = <0x4>; 
     xlnx,gpio2-width = <0x20>; 
     xlnx,interrupt-present = <0x0>; 
     xlnx,is-dual = <0x0>; 
     xlnx,tri-default = <0xFFFFFFFF>; 
     xlnx,tri-default-2 = <0xFFFFFFFF>; 
    }; 
    axi_gpio_1: [email protected] { 
     #gpio-cells = <2>; 
     compatible = "xlnx,xps-gpio-1.00.a"; 
     gpio-controller ; 
     reg = <0x41210000 0x10000>; 
     xlnx,all-inputs = <0x1>; 
     xlnx,all-inputs-2 = <0x0>; 
     xlnx,all-outputs = <0x0>; 
     xlnx,all-outputs-2 = <0x0>; 
     xlnx,dout-default = <0x00000000>; 
     xlnx,dout-default-2 = <0x00000000>; 
     xlnx,gpio-width = <0x4>; 
     xlnx,gpio2-width = <0x20>; 
     xlnx,interrupt-present = <0x0>; 
     xlnx,is-dual = <0x0>; 
     xlnx,tri-default = <0xFFFFFFFF>; 
     xlnx,tri-default-2 = <0xFFFFFFFF>; 
    }; 
    axi_gpio_2: [email protected] { 
     #gpio-cells = <2>; 
     compatible = "xlnx,xps-gpio-1.00.a"; 
     gpio-controller ; 
     reg = <0x41220000 0x10000>; 
     xlnx,all-inputs = <0x1>; 
     xlnx,all-inputs-2 = <0x0>; 
     xlnx,all-outputs = <0x0>; 
     xlnx,all-outputs-2 = <0x0>; 
     xlnx,dout-default = <0x00000000>; 
     xlnx,dout-default-2 = <0x00000000>; 
     xlnx,gpio-width = <0x4>; 
     xlnx,gpio2-width = <0x20>; 
     xlnx,interrupt-present = <0x0>; 
     xlnx,is-dual = <0x0>; 
     xlnx,tri-default = <0xFFFFFFFF>; 
     xlnx,tri-default-2 = <0xFFFFFFFF>; 
    }; 
}; 
}; 

Все параметры, описанные выше, появляются в Linux так devicetree в папке:/SYS/прошивки/devicetree/базе/amba_pl

Например, в:/SYS/прошивке/devicetree/база/amba_pl/GPIO @ 41200000

я могу найти эти файлы

#gpio-cells 
compatible 
gpio-controller 
linux,phandle 
name 
phandle 
reg 
xlnx,all-inputs 
xlnx,all-inputs-2 
xlnx,all-outputs 
xlnx,all-outputs-2 
xlnx,dout-default 
xlnx,dout-default-2 
xlnx,gpio-width 
xlnx,gpio2-width 
xlnx,interrupt-present 
xlnx,is-dual 
xlnx,tri-default 
xlnx,tri-default-2 

Я также нашел (в:/SYS/автобус/платформы/водителей) водителей, связанных с GPIO, соответствующей опции, которые я включил в ядро ​​конфигурационного меню. Документацию об этих драйверах можно найти здесь: drivers-on-gpio

Но я до сих пор не знаю, как управлять и как связываться с общим IP-адресом на стороне PL zynq (как в этом примере, где я хочу играть со светодиодами и кнопками подключаются через интерфейс axi к PS)

Я полагаю, что мне нужно играть с операциями чтения/записи в памяти. Не могли бы вы дать мне информацию о том, как мне нужно следовать? Вы знаете о каком-либо источнике информации, связанной с этой задачей? Есть ли примеры того, как управлять и где найти правильный драйвер, автоматически созданный с помощью xilinx-tools? Я буду благодарен за любую поддержку!

Целью этого является изучение основ для управления любым общим IP-соединением, связанным с AXI.

+0

Я предлагаю вам подтянуть тему вопроса, а именно о том, как получить доступ к Xilinx AXI GPIO-устройствам из пользовательского пространства. У вас есть драйвер, скомпилированный в ваше ядро? –

+0

Кроме того, когда вы говорите «изучите основы», вы хотите узнать, как использовать IP-адрес, который уже имеет драйверы устройств Linux, или вы хотите узнать, как написать драйвер для вашего собственного AXI-IP, или вы хотите узнать, как разработать AXI IP, который не требует собственного драйвера устройства? –

+0

То, что я хотел сделать, это каким-то образом контролировать эту периферию. Когда я писал это, я пытался использовать драйверы gpio, но поскольку эти периферийные устройства подключены через AXI, который является интерфейсом карты памяти, я не мог этого сделать. Я достиг своей цели, используя функцию mmap() и сопоставляя управляющие регистры периферийных устройств в пользовательском пространстве для прямой записи. Я думаю, что еще одно возможное решение - изменить совместимое поле для использования драйверов UIO, но мне нужно изменить ядро, как это показано на форуме xilinx. Моя следующая цель - написать собственные драйверы для пространства ядра. – Arturete

ответ

1

Как я публиковал в комментарии, мне удалось управлять периферийными устройствами AXI GPIO из приложения пользовательского пространства, но без использования драйверов GPIO. Я читал много вещей, пока не понял, что, поскольку эти периферийные устройства используют интерфейс карты памяти, я не мог использовать драйверы GPIO. Я только смог использовать драйверы GPIO для управления выводами MIO и EMIO. Тот факт, что когда pl.dtsi создается инструментами Xilinx, периферийные устройства выглядят как xps-gpio-1.00.a меня сбивает с толку. Мы можем видеть, что в коде, который я опубликовал в вопросе в строках: compatible = "xlnx,xps-gpio-1.00.a";

Решение, с которым я столкнулся, состояло в использовании функции mmap() (man mmap) для сопоставления регистров управления периферийными устройствами, которые находятся в физической памяти в память пользовательского пространства, которую будет использовать мое приложение, и что он знает это во время выполнения, но не раньше. Мы можем знать, которым являются периферическими физическими адресами, глядя на адрес смещение поля Адресной редактор вкладки дизайна диаграммы блока программы Vivado, как мы можем видеть здесь: enter image description here
Также рекомендую для просмотра таблицы периферийных устройств (link).
И, наконец, это код, который я использовал:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/mman.h> 

#define IN 0 
#define OUT 1 

#define GPIO_0_BASE_ADDR 0x41200000 
#define GPIO_1_BASE_ADDR 0x41210000 
#define GPIO_ADDR_RANGE  0x10000 

int main(void) 
{ 

    int fd; 
    int value = 0; 

    void *gpio0_virtual_add, *gpio1_virtual_add; //pointers to the virtual memory 

    /* Open /dev/mem file */ 
    fd = open ("/dev/mem", O_RDWR); 
    if (fd < 1) { 
     printf("***error opening dev file"); 
     return -1; 
    } 

    /* mmap the devices into memory */ 
    gpio0_virtual_add = mmap(NULL, GPIO_ADDR_RANGE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_0_BASE_ADDR); 
    if (&gpio0_virtual_add==MAP_FAILED){ 
     printf("map failed\n"); 
    } else { 
     printf("device mapped to user space, %d\n", gpio0_virtual_add); 
    } 

    gpio1_virtual_add = mmap(NULL, GPIO_ADDR_RANGE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_1_BASE_ADDR); 

    if (&gpio1_virtual_add==MAP_FAILED){ 
     printf("map 2 failed\n"); 
    } else { 
     printf("2 device mapped to user space, %d\n", gpio0_virtual_add); 
    } 

    /* Read/Write value from/to the device register */ 
    while (value!=5){ 
     value = *((unsigned *)(gpio1_virtual_add));  //read value from the buttons 
     *((unsigned *)(gpio0_virtual_add)) = value;  //turn on the leds 
    } 

    /*free virtual memory*/ 
    munmap(gpio0_virtual_add, GPIO_ADDR_RANGE);   
    munmap(gpio1_virtual_add, GPIO_ADDR_RANGE); 

    return 0; 
} 

Пожалуйста, если что-то либо, что я объяснил или неверный код или запутанный спросить мне знать, и не стесняйтесь, чтобы исправить это.

Смежные вопросы