2016-04-15 3 views
1

У меня есть программный проект, который должен использовать A20-OLinuXino-MICRO-4GB board. Я не могу контролировать, какой совет использовать, поэтому предложения об альтернативах не помогают.Включить контроллер SPI для Cortex-A7 за пределами linux

У этого есть двухъядерный процессор Cortex-A7 Allwinner A7 (armv7a).

Я попытался выполнить работу с Linux, но даже с максимальным приоритетом, PTHREAD_EXPLICIT_SCHED и SCHED_FIFO, я не смог предотвратить прерывания временной критической секции управляющего кода (необходимо обработать каждые 10 микросекунд, но получил 40 микросекундных промежутков около 40 раз в секунду).

С вышеприведенным ограничением, предложения по доступу к SPI и UART из Linux также не помогают. Ограничения по времени во втором потоке (целая ядро ​​cpu, выделенная для него), означает, что обычный linux в настоящее время не является жизнеспособной альтернативой. Может быть, полный рабочий стол в режиме реального времени выполнит эту работу, но у меня нет ресурсов для создания этого, просто чтобы посмотреть, будет ли это может работать.

Текущая среда разработки:

Gentoo 4.3.3-hardened-r4 
crossdev --kernel =3.18 --libc =2.21-r2 --binutils =2.24-r3 --gcc =4.8.5 

Строительство u-boot в настоящее время не работает с 5.x версии GCC, так что не слишком много места, чтобы двигаться туда.

Итак, перешел к написанию как отдельный код, который должен быть запущен с u-boot. Никаких дополнительных задержек нет, но теперь мне не хватает чего-то, чтобы настроить другие модули ядра. Когда я пытаюсь инициализировать и настраивать устройства SPI или UART (кроме UART0, который используется для консоли u-boot), все регистры сообщают о нуле и остаются там даже после их установки. Он действует так, как будто ничего нет (нет аппаратного обеспечения). UART0 имеет разумные/ожидаемые значения, а настройка стандартных контактов GPIO (ввода и вывода) работает нормально. Настройка уплотненных GPIO булавки для использования SPI или UART также появляется работа, но модули упорно отказываются признать, что они существуют.

Образец кода, файл Makefile и вывод для попыток поговорить с модулями SPI можно найти in the olimex forum. Обратите внимание, что образец использует файлы include из сборки u-boot Основная документация, используемая для создания этого кода, - A20 User Manual.

Кто-нибудь работал с A20, Cortex-A7, armv7a или аналогичными чипами и выяснил, как получить доступ к возможностям за пределами Linux?

Кто-нибудь знает, где можно получить лучшую документацию о программировании на этом уровне?

Руководство пользователя У меня есть много информации о адресах регистра, смещениях, бит-масках, но ничего на пути примеров кода. Я ожидаю, что простой автономный пример C (или даже ассемблер), который настроил любой из (устройств) модулей и установил прерывание для его обработки, будет , поэтому поможет разобраться в остальном.

На самом деле я получил связь SPI, работая по битам ввода-вывода. Это не будет работать для UART, и SPI выглядит как более простой случай для работы в первую очередь.

Я программировал много лет на больших системах, а некоторые на очень маленьких (6502, 8085, arduinio) системах, но не имеют реального опыта разработки в этой среде. Я не программист ядра, или что-то близко.

EDIT: Я добавил настройку Clock SPI1 в код примера, но все регистры SPI по-прежнему отображаются как все нули до и после установки. Код меняется:

#include <asm/arch-sunxi/clock_sun4i.h> 
struct sunxi_ccm_reg * clockRegister; 
#define SPI_SCLK_GATING_CLKON 0x80000000 
#define SPI_CLK_SRC_OSC24M  0x00000000 
#define SPI_CLK_DIV_RATION_8 0x00030000 
// ... 
printf ("SPI1 clk cfg %08x\n", clockRegister->spi1_clk_cfg); 
clockRegister->spi1_clk_cfg = 
    SPI_SCLK_GATING_CLKON | SPI_CLK_SRC_OSC24M | SPI_CLK_DIV_RATION_8 | 15; 
printf ("SPI1 clk cfg %08x\n", clockRegister->spi1_clk_cfg); 

Это показывает, что конфигурация часы DID изменения от 0x00000000 до 0x8003000f

+1

я фактически ожидал такого устройства, чтобы иметь либо буфер FIFO или DMA, прикреплены к периферийным. – Olaf

+0

Он делает (оба). Тем не менее, по-прежнему необходимо включить, включить, настроить, инициализировать, ПОЛУЧИТЬ устройство/модуль. – mMerlin

+0

Поскольку вы преодолеваете препятствия для компиляции, загрузки и получения кода для чтения и записи MMIO, вы можете спокойно забыть о Cortex-A7, это все о периферийных устройствах на A20 SoC, а не о том, какой процессор подключен к ним - если вы сбросили ядро ​​MIPS там, вместо этого он не изменит характер проблемы один бит. Как правило, на мобильном устройстве вам нужно немного флиртовать с PLL и, возможно, регуляторами, чтобы получить синхронизацию и питание, не связанные с загрузкой, - что требует A20 в этом отношении? – Notlikethat

ответ

0

Я также отправил этот вопрос на Microcontroller Based Projects Google + сообществах, и Николай Кондрашов (spbnick) там замечен и правильно интерпретирован информация, содержащаяся в документации.

Чтобы получить доступ к регистрам SPI, необходимо установить как часы AHB Gating для SPI «n» бит в AHB_GATTING_REG0, так и бит SCLK_GATING в SPI «n» _CLK_REG. Как только они установлены, модуль SPI «n» регистрируется, становится доступным.

Потенциально запутанное примечание стороны: сначала установите бит стробирования AHB, а затем попытайтесь обратиться к регистру SPI, прежде чем устанавливать бит стробирования SCLK, вызывает полное замораживание. Поскольку в приложении , работающем, они обычно устанавливаются вместе, это обычно не является проблемой. Только появился с выходом отладки, проверяя, как только появятся записи SPI.

Я до сих пор считаю, что документации недостаточно. Несколько примеров кода могли бы улучшить его. Это открытие, вероятно, достаточно для доступа к большинству модулей/устройств SoC.

Довольно минимальный пример кода. Это работает с тем же Makefile, показанным для исходного вопроса. В который входит дополнительный файл загрузки u-boot.

#include <common.h> 

// Global memory pointers 
uint32_t 
    (*SPIarry1)[11], 
    *SPI1_Cfg, 
    *AHB_Gate0, 
    *SPI1_ClkCfg; 

int spi_test (void); 

int spi_test (void) 
{ 
    AHB_Gate0 = (uint32_t *)(SUNXI_CCM_BASE + 0x60); 
    SPI1_ClkCfg = (uint32_t *)(SUNXI_CCM_BASE + 0xa4); 
    SPIarry1 = (uint32_t (*)[11])SUNXI_SPI1_BASE; 

    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    *SPI1_ClkCfg = 0x80000000; 
    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    *AHB_Gate0 |= 0x00200000; 
    printf ("SPI1 Cfg Reg 0x%08x\n", (*SPIarry1)[2]); 
    return (0); 
} 

захватили пример вывода программы

## Starting application at 0x42000000 ... 
SPI1 Cfg Reg 0x00000000 
SPI1 Cfg Reg 0x00000000 
SPI1 Cfg Reg 0x0012001c 
## Application terminated, rc = 0x0 
Смежные вопросы