Свечение светодиода с помощью GPIO в крановой плате

Я хотел бы использовать GPIO для включения светодиода на крановой панели (процессор ARM). Я очень новичок во встроенном программировании. Но я неплохо разбираюсь в C. Я обращался к некоторым веб-сайтам и узнал о командах, связанных с GPIO. Я написал код, но не совсем уверен, как его интегрировать в кодировку u-boot кранборда. Я не знаю, с чего начать. Пожалуйста, направь меня.

#define LED1    (1 << 6)

int getPinState(int pinNumber);

int main(void)
{

  GPIO0_IODIR |= LED1;

  GPIO0_IOSET |= LED1;

  while (1)
  {

      GPIO0_IOCLR |= LED1;

  }
}

int getPinState(int pinNumber)
{

  int pinBlockState = GPIO0_IOPIN;

  int pinState = (pinBlockState & (1 << pinNumber)) ? 1 : 0;

  return pinState;
}

person Gomu    schedule 11.02.2013    source источник


Ответы (3)


Прежде всего, изучите общие битовые (в вашем случае также контактные) выражения манипуляции, которые вы МНОГО будете использовать во встраиваемом программировании:

/* Set bit to 1 */
GPIO0_IODIR |= LED1; //output

/* Clear bit (set to 0) */
GPIO0_IOSET &= ~LED1; //low

/* Toggle bit */
GPIO0_IOSET ^= LED1;

Ваш цикл while() на самом деле ничего не делает, кроме первой итерации, потому что те же логические операции ИЛИ не изменяют битовое состояние (см. логическую таблицу этой операции). Также вы должны добавить задержку, потому что, если контакт переключается слишком быстро, светодиод может выглядеть как выключенный все время. Простое решение будет выглядеть так:

while(1)
{
   GPIO0_IOSET ^= LED1;
   sleep(1); //or replace with any other available delay command
}

У меня нет исходных файлов U-Boot для Craneboard, поэтому я не могу сказать вам точное место, куда положить ваш код, но в принципе есть несколько вариантов: 1) добавить его в main(), где стартует U-Boot, таким образом повесить его (но светодиод все еще мигает!). 2) реализовать отдельную команду для включения/выключения светодиода (см. примеры файлов command.c и cmd_ с префиксом) 3) интегрировать ее в последовательный цикл, чтобы контакт мог быть переключается во время ожидания ввода пользователем 4) создайте его как приложение поверх U-Boot.

Привыкайте к большому количеству чтения и документации, TRM здесь ваш друг (иногда единственный). Также есть несколько отличных руководств для начинающих, просто погуглите. Немного упомянуть:

http://www.microbuilder.eu/Tutorials/LPC2148/GPIO.aspx (основы с примерами)

http://beagleboard.org/ (отличный ресурс для BeagleBoard, но многое относится и к CraneBoard, поскольку они используют один и тот же SoC, включает большое сообщество).

http://free-electrons.com/ (больше для встраиваемых систем Linux и других продвинутых тем, но некоторые основы могут тоже можно найти)

http://processors.wiki.ti.com/index.php/CraneBoard (официальная вики CraneBoard, наверное это знают, но на всякий случай)

P.S. Удачи и не сдавайтесь!

person KBart    schedule 11.02.2013
comment
Большое спасибо. Я бы обязательно проверил эти сайты. Кстати, исходный код находится здесь, если вы могли бы мне немного помочь. - person Gomu; 11.02.2013
comment
Рад, что смог помочь. У вас есть доска и работает? Если да, то можете ли вы получить доступ к консоли U-Boot? Самым простым (и самым быстрым) решением будет изменение пример hello_world, созданный в U-Boot. Просто добавьте свой цикл в hello_world.c, перекомпилируйте, перепрошейте и следуйте инструкциям, как заставить его работать. Если у вас есть еще вопросы - дайте мне знать, может быть, я мог бы помочь снова. - person KBart; 11.02.2013
comment
Спасибо. Я попробовал процедуру, указанную здесь. Я не менял адрес загрузки. Он уже установлен на 0x82000000. Итак, я только что загрузился. Но когда 'go', он просто зависает. Какие-либо предложения? - person Gomu; 11.02.2013
comment
Вместо автономного, есть ли способ заставить светодиод, подключенный к GPIO, светиться во время загрузки u-boot? - person Gomu; 11.02.2013
comment
Недостаточно информации, чтобы сказать, почему ваша доска зависает. Что касается второго вопроса, конечно, есть способ, на самом деле много способов - вы можете инициализировать таймер, который переключает светодиод, мигать им вручную во время какого-либо действия и т. д., это зависит от вашей цели. Но этот сайт не для долгих дискуссий, свяжитесь со мной по почте, желательно с некоторыми логами и описанием, что вы сделали и что хотите сделать. - person KBart; 11.02.2013

Если вы хотите сделать это в u-boot (а не в линуксе), то вам придется написать приложение для u-boot.

5.12$ руководства по u-boot объясняет, как это сделать.

Источник u-boot содержит несколько примеров, которые вы можете использовать.

person Ottavio Campana    schedule 11.02.2013

Я хотел бы добавить свой ответ. Кодирование, которое я делал ранее, было обобщенным. В Craneboard есть определенные функции, которые выполняют операцию. Итак, я переписал его соответственно. Я включил файл cmd_toggle.c в каталог 'common' каталога u-boot. И добавил его в Makefile. Следующий код заставит светодиод мигать.

int glow_led(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret,i=0,num=0,ctr=0;
int lpin;
lpin=(int)strtoul(argv[1]);
ret=set_mmc_mux();
if(ret<0)
    printf("\n\nLED failed to glow!\n\n");
else{
        if(!omap_request_gpio(lpin))
        {
        omap_set_gpio_direction(lpin,0);

        for(i=1;i<21;i++)
        {
            ctr=0;
            if((i%2)==0)
            {
                num=num-1;
                omap_set_gpio_dataout(lpin,num);
            }
            else
            {
                num=num+1;
                omap_set_gpio_dataout(lpin,num);
            }

                    udelay(3000000);
        }

    }
}
return 0;
}

U_BOOT_CMD(toggle,2,1,glow_led,"Glow an LED","pin_number");

Я мог бы сделать это немного проще, просто используя цикл while, чтобы многократно устанавливать его как 1 и 0.

Это можно выполнить из консоли u-boot как toggle 142, так как я подключил светодиод к контакту 142.

P.S. Спасибо за все ваши советы. Отдельное спасибо KBart

person Gomu    schedule 27.02.2013