ARM NXP LPC2378: безопасно ли изменять состояние вывода вывода GPIO через доступ к регистру? - PullRequest
2 голосов
/ 24 ноября 2010

В настоящее время я использую ARM NXP LPC2378 для проекта с использованием компилятора IAR.Я модифицирую выходные выводы GPIO через несколько нестандартный метод.Вот мой код ниже:

void SetPinhigh(int port_number, int pin_number)
{
    volatile unsigned long* set_register = (volatile unsigned long *)(BASE_ADDR + (PIN_PORT_LENGTH_IN_BYTES*port_number) + PIN_SET_REGISTER_OFFSET);

    *set_register |= (1 << pin_number);
}

Это безопасный метод для использования?Если я перебираю код, IAR выдает мне предупреждения о записи в регионы, не связанные с ОЗУ, но я пишу в регистр, и контакты переключаются.Мне нравится этот метод, потому что он кажется более чистым в использовании, чем структуры, созданные IAR.Есть ли лучший метод, о котором знают другие?

Ответы [ 5 ]

2 голосов
/ 24 ноября 2010

IAR правильно, регистры не RAM.:) Возможно, лучше всего посмотреть, как подавить предупреждения, просматривая примеры, идущие с IAR (если есть).Это может быть пользовательское ключевое слово IAR или прагма, что говорит компилятору, как вы собираетесь это делать.

Это также может быть проблемой в карте памяти, поскольку может потребоваться как-то определить регистр.

Я работаю с GCC и ARM, и он не жалуется ни на какой метод доступа к регистрам.Я использовал:

  1. прямой и вычисленный адрес (*((volatile unsigned int *)0xNNNNNNNNU) |= 1<<pin);
  2. массивы, структуры, объединения и битовые поля по прямому адресу (через это опасно, но это делает код такимnice);
  3. символы, определенные в файле карты со всеми вышеперечисленными (это может быть в основном C-совместимым из-за работы с компоновщиком, а не с компилятором).

Предлагается новое расширение, претендующее набыть стандартом, который я недавно обнаружил и который называется TR 18037: Embedded C .В разделе «6 ОСНОВНОЕ АДРЕС ОБОРУДОВАНИЯ В / В» дается общий метод доступа к оборудованию (см. Pdf):

#include <iohw.h>
#include "iodriv_hw.h"  /* Platform-specific designator
                           definitions. */

// Wait until controller is no longer busy.
while (iord(dev_status) & STATUS_BUSY) /* do nothing */;

// Write value to controller.
iowr(dev_out, ch);

Есть также функции ioand, ioor [например, макрос] и многие другие..

Пример реализации для iohw.h также есть, поэтому вы можете добавить поддержку для этого в IAR самостоятельно.

1 голос
/ 25 ноября 2010

Я предлагаю вам заглянуть в файл заголовка, специфичный для устройства, чтобы увидеть, как объявляются SFR. Вы также можете прочитать рекомендации на стр. 142 Руководство по разработке IAR C / C ++ , а также руководство по написанию файлов заголовков устройств IAR .

В частности, вы можете использовать макросы __IO_REGxx или по крайней мере посмотреть, как они определены в io_macros.h

0 голосов
/ 28 ноября 2010

Доступ к памяти и к отображенным в памяти регистрам в основном одинаков. Однако могут быть ограничения на доступ к регистрам с отображением в памяти. На LPC2378 разрешен только 32-битный доступ:

Все адреса периферийных регистров выровнены по словам (до 32-битных границ) независимо от их размера. Это устраняет необходимость в оборудовании для отображения байтовых дорожек, которое требуется для обеспечения доступа к байту (8 бит) или полуслову (16 бит) на меньших границах. Следствием этого является то, что регистры слов и полуслов должны быть доступны одновременно. Например, невозможно прочитать или записать верхний байт регистра слова отдельно.

(Руководство по LPC2378 http://www.keil.com/dd/docs/datashts/philips/lpc23xx_um.pdf)

Поскольку вы используете unsigned long для доступа к реестру, все должно быть в порядке. В качестве стиля вы также можете объявить struct с регистрами GPIO и получить доступ к регистру следующим образом:

gpio_port_registers_t *port = (gpio_port_registers_t *)BASE_ADDR;
port[port_number]->set_register |= (1 << pin_number);
0 голосов
/ 25 ноября 2010

Отлично выглядит для меня.Я делаю это таким же образом на других процессорах / инструментальных цепочках, регистры отображения памяти ведут себя так же, как RAM.Я не знаю, как работает ваш процессор и компилятор, и если могут возникнуть проблемы, но я не могу понять, как это может быть проблемой, если компилятор не попытается быть умнымЯ бы нашел способ подавить предупреждение.

0 голосов
/ 24 ноября 2010

Это компилятор или отладчик, который выдает вам предупреждения о записи в не-RAM места?

Я был бы удивлен, если бы компилятор выдал предупреждение о записи в не-RAM для кода, который вы разместили - кажется, что компилятор не может определить, каким будет адрес в конечном итоге, поскольку он зависит от port_number параметр.

Возможно, вам потребуется настроить отладчик для вашего устройства. В IAR есть файл описания устройства для LPC2378 в "C:\Program Files\IAR Systems\Embedded Workbench 5.0\ARM\config\debugger\NXP\iolpc2378.ddf", который позволяет отладчику узнать, какие регистры по каким адресам. Этот файл конфигурации позволяет отладчику показывать регистры, разбитые по битовым полям с именами, совпадающими (или близко совпадающими) с именами, используемыми в документах устройства, когда вы используете окно представления «Регистрация» в отладчике.

Если вы выберете правильное устройство на вкладке свойств проекта "General Options/Target", правильный файл .ddf должен быть настроен автоматически. Если по какой-то причине это не работает или вам нужен собственный файл, вы можете указать нужный файл в записи свойства проекта «Файл отладчика / Настройка / Файл описания устройства».

Использование правильного .ddf-файла (или исправление его, если оно неправильное) также может предотвратить появление предупреждений, которые приходят от отладчика.

...