Плата с ARM CPU и Линух (Решено)

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Плата с ARM CPU и Линух (Решено)

Сообщение mig-31 » 08.09.2013 14:34:36

Добрый день.
Никак не могу найти ошибку из-за которой процессор зависает при записи в регистры PIOC.
Плата Portux G20 http://www.taskit.de/en/products/portuxg20/index.htm с Atmel AT91SAM9G20 с Angstrom Linux.
У этого процессора есть три линии конфигурируемых input/output линий по 32 на каждой линии PIOA, PIOB и PIOC.
Сдвиг на PIOB =$FFFFF600, PIOC=$FFFFF800. Сдвиг на регистры конфигурации
PER= $0000 //enable registr
OER=$0010 //enable output registr
IFDR=$0024 //enable filtr registr
SODR=$0030 //set ouput register - set high on output
CODR=$0034 //clear output registr - set low on output
IDR=$0044 //disable interrupt registr
Все регистры 32-х битные.

При записи в регистры линии PIOC процессор зависает.
Пример кода на С работает без проблем.

Мой код на Паскале
Код: Выделить всё
program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils,BaseUnix,crt,errors
  { you can add units after this };
const
  //map consts
  MAP_SIZE=4096;
  MAP_MASK=(MAP_SIZE-1);
  //BASE ADDRESS OF PIOB and PIOC
  //calculating address due of page size 4096 = $1000 PIOB_BASE= $FFFFF600 div $1000 =$FFFFF
  //calculating address due of page size 4096 = $1000 PIOB_BASE= $FFFFF800 div $1000 =$FFFFF
  //page number offset
  PIO_BASE=$FFFFF;
  //OFFSET TO CONTROL REGISTERS REGISTERS address  PIOB
  PIOB_OFFSET=$600;
  PIOB_PER=(PIOB_OFFSET+$0000);
  PIOB_OER=(PIOB_OFFSET+$0010);
  PIOB_IFDR=(PIOB_OFFSET+$0024);
  PIOB_SODR=(PIOB_OFFSET+$0030);
  PIOB_CODR=(PIOB_OFFSET+$0034);
  PIOB_IDR=(PIOB_OFFSET+$0044);

  //OFFSET TO CONTROL REGISTERS REGISTERS address  PIOB
  PIOC_OFFSET=$600;
  PIOC_PER=(PIOC_OFFSET+$0000);
  PIOC_OER=(PIOC_OFFSET+$0010);
  PIOC_IFDR=(PIOC_OFFSET+$0024);
  PIOC_SODR=(PIOC_OFFSET+$0030);
  PIOC_CODR=(PIOC_OFFSET+$0034);
  PIOC_IDR=(PIOC_OFFSET+$0044);
  //set 1 on 27 pin on PIOB controller registers
  PIOB_B27=(1 shl 27);
  //set 1 on pin 0 on PIOC controller registers
  PIOC_C00=(1 shl 0);
  blink_count=5;

var
  fd:cint;
  mem_base:^Longword;
  reg_addr:^Longword;
  i:byte;
begin
  //get file descriptor
  fd:=fpOpen('/dev/mem',O_RdWr or O_SYNC);
  if fd<0 then begin
    writeln('Cant get file description');
    Halt(1);
  end;
  writeln('/dev/mem has opened');
  //map 1 page memory 4kB
  //fpmmap is used page OFFSET not byte
  mem_base:=fpmmap(Nil,MAP_SIZE,PROT_READ or PROT_WRITE,MAP_SHARED ,fd, PIO_BASE);
  if ptrint(mem_base)=-1 then begin
    writeln('Memory map error. Error: ',strerror(fpGeterrno));
    Halt(2);
  end;
  writeln('Memory mapped on address $',hexstr(mem_base));
 
  //работает
  // setting registers to blink on pin B29
  //enable registr
  reg_addr:=Pointer(Longword(mem_base)+PIOB_PER);
  reg_addr^:=PIOB_B27;
  //disable input filtr
  reg_addr:=Pointer(Longword(mem_base)+PIOB_IFDR);
  reg_addr^:=PIOB_B27;
  //disable interrupt
  reg_addr:=Pointer(Longword(mem_base)+PIOB_IDR);
  reg_addr^:=PIOB_B27;
  //enable output
  reg_addr:=Pointer(Longword(mem_base)+PIOB_OER);
  reg_addr^:=PIOB_B27;
  //blinking
  for i:=0 to blink_count do begin
    //set output data register
    reg_addr:=Pointer(Longword(mem_base)+PIOB_SODR);
    reg_addr^:=PIOB_B27;
    sleep(1000);
    //clear output data register
    reg_addr:=Pointer(Longword(mem_base)+PIOB_CODR);
    reg_addr^:=PIOB_B27;
    sleep(1000);
  end;

  //вешает процессор
  // setting registers to blink on pin C00
  //enable registr
  reg_addr:=Pointer(Longword(mem_base)+PIOC_PER);
  reg_addr^:=PIOC_C00;
  //disable input filtr
  reg_addr:=Pointer(Longword(mem_base)+PIOC_IFDR);
  reg_addr^:=PIOC_C00;
  //disable interrupt
  reg_addr:=Pointer(Longword(mem_base)+PIOC_IDR);
  reg_addr^:=PIOC_C00;
  //enable output
  reg_addr:=Pointer(Longword(mem_base)+PIOC_OER);
  reg_addr^:=PIOC_C00;
  //blinking
  for i:=0 to blink_count do begin
    //set output data register
    reg_addr:=Pointer(Longword(mem_base)+PIOC_SODR);
    reg_addr^:=PIOC_C00;
    sleep(1000);
    //clear output data register
    reg_addr:=Pointer(Longword(mem_base)+PIOC_CODR);
    reg_addr^:=PIOC_C00;
    sleep(1000);
  end;
//close file descriptor
fpClose(fd);
//unmap memory
if fpMUnMap(mem_base, map_size)<>0 then Halt(fpgeterrno);
end.


Код на С
Код: Выделить всё
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
 
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

#define PIOB_BASE 0xfffff600UL
#define PIOC_BASE 0xfffff800UL

#define PIO_C00 ((unsigned long) 1 << 0)
#define PIO_C01   ((unsigned long) 1 << 1)
#define PIO_B27   ((unsigned long) 1 << 27)

#define PIOB_PER PIOB_BASE + 0x0000
#define PIOB_OER PIOB_BASE + 0x0010
#define PIOB_IFDR PIOB_BASE + 0x0024
#define PIOB_SODR PIOB_BASE + 0x0030
#define PIOB_CODR PIOB_BASE + 0x0034
#define PIOB_IDR PIOB_BASE + 0x0044


#define PIOC_PER PIOC_BASE + 0x0000
#define PIOC_OER PIOC_BASE + 0x0010
#define PIOC_IFDR PIOC_BASE + 0x0024
#define PIOC_SODR PIOC_BASE + 0x0030
#define PIOC_CODR PIOC_BASE + 0x0034
#define PIOC_IDR PIOC_BASE + 0x0044

int main(int argc, char **argv) {
    int fd, i, repetitions;
    void *map_base;
    if (argc > 1)
    {
       repetitions =(atoi(argv[1]));
    }
    else
    {
       printf("\nMissing argument\n");
         printf("Usage: led REPETITIONS\n");
    printf("REPETITIONS: int, that specifies number of repetitions of blinking led cycles\n\n\n");
         exit(1);
    }   


    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1)
    {
       printf("Couldn't open /dev/mem.\n");
   exit(1);
    }
    printf("/dev/mem opened.\n");
    fflush(stdout);
   
    /* Map one page */
    map_base = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, PIOB_BASE  & ~MAP_MASK);
    if(map_base == (void *) -1)
    {
       printf("Couldn't get Map-Address.\n");
      exit(1);
   }
    printf("Memory mapped shift %p.\n", PIOB_BASE  & ~MAP_MASK);
    printf("Memory mapped at address %p.\n", map_base);
    fflush(stdout);
   
    // Configure the registers

    *((unsigned long *) (map_base + (PIOB_PER & MAP_MASK))) = PIO_B27; //enable io
    printf("Memory shift to PER %p.\n", PIOB_PER & MAP_MASK);
    *((unsigned long *) (map_base + (PIOB_IFDR & MAP_MASK))) = PIO_B27; //disable input filter
     printf("Memory shift to IFDR %p.\n", PIOB_IFDR & MAP_MASK);
    *((unsigned long *) (map_base + (PIOB_IDR & MAP_MASK))) = PIO_B27;  // disable interrupt
    *((unsigned long *) (map_base + (PIOB_OER & MAP_MASK))) = PIO_B27;  // Enable output

    *((unsigned long *) (map_base + (PIOC_PER & MAP_MASK))) = PIO_C00 | PIO_C01;
    *((unsigned long *) (map_base + (PIOC_IFDR & MAP_MASK))) = PIO_C00 | PIO_C01;
    *((unsigned long *) (map_base + (PIOC_IDR & MAP_MASK))) = PIO_C00 | PIO_C01;
    *((unsigned long *) (map_base + (PIOC_OER & MAP_MASK))) = PIO_C00 | PIO_C01;

    i = 0;
    while(i < repetitions)
    {         
      *((unsigned long *) (map_base + (PIOC_CODR & MAP_MASK))) = PIO_C00;
      *((unsigned long *) (map_base + (PIOB_SODR & MAP_MASK))) = PIO_B27;
      sleep(1);
      *((unsigned long *) (map_base + (PIOB_CODR & MAP_MASK))) = PIO_B27; 
      *((unsigned long *) (map_base + (PIOC_SODR & MAP_MASK))) = PIO_C01;
      sleep(1);
      *((unsigned long *) (map_base + (PIOC_CODR & MAP_MASK))) = PIO_C01;
      *((unsigned long *) (map_base + (PIOC_SODR & MAP_MASK))) = PIO_C00;      
      sleep(1);
      i++;
    }
    *((unsigned long *) (map_base + (PIOB_CODR & MAP_MASK))) = PIO_B27; 
    *((unsigned long *) (map_base + (PIOC_CODR & MAP_MASK))) = PIO_C00 | PIO_C01;      
    if(munmap(map_base, MAP_SIZE) == -1) exit(1);
    close(fd);
    return 0;
}


Код на Паскале компилировал на Магея Линух 3 64-бит с crossarm и fpc юнитами 2.5.1 для ARM и прямо на плате fpc 2.6.2. Результат один и тот же при записи в регистры PIOC процессор зависает. Чтение регистра возвращающего состояние (OFFSET= $0008) outputa выполняется без проблем.
Уже не зная, где искать ошибку. Может баг функции fpmmap - выделяет 512 байт вместо 4 килобайт (хотя наверно это невозможно)?

Спасибо за любую идею.
Последний раз редактировалось mig-31 10.09.2013 14:54:36, всего редактировалось 1 раз.
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Плата с ARM CPU и Линух

Сообщение mig-31 » 10.09.2013 14:54:02

Решено. Ошибка была в записи используемого бита.
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Плата с ARM CPU и Линух (Решено)

Сообщение vada » 10.09.2013 15:16:33

Стесняюсь спросить, сколько девайс стоит? А то вот тут http://www.zao-zeo.ru/ наши продают похожие устройства за какие-то нереальные деньги.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Плата с ARM CPU и Линух (Решено)

Сообщение debi12345 » 10.09.2013 15:58:01

за какие-то нереальные деньги

Ну, для начала - чипы от MARWELL (распаиваемые на этих платах) всегда были недешевые.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Плата с ARM CPU и Линух (Решено)

Сообщение vada » 10.09.2013 16:17:45

чипы от MARWELL (распаиваемые на этих платах) всегда были недешевые.

И что? Старушка у метро говорила что она выкопала 8 ведер картошки.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Плата с ARM CPU и Линух (Решено)

Сообщение Sergei I. Gorelkin » 10.09.2013 16:32:53

Дык, на taskit.de есть магазин с ценами... и я бы не сказал, что у наших цены по сравнению с ними прямо-таки нереальные.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Плата с ARM CPU и Линух (Решено)

Сообщение debi12345 » 10.09.2013 16:41:57

и я бы не сказал, что у наших цены по сравнению с ними прямо-таки нереальные.

Цены на промэлектронику всегда завышены (если гос-во это не берет на конроль) - фирмачи считают, что у целого предприятия на несчатную плату несколько сотен басов всегда найдутся :) Подход конечно идиотский и недальновидный - затруднящий техническое творчество индивидуалов на дому, в кружкАх,.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Плата с ARM CPU и Линух (Решено)

Сообщение mig-31 » 11.09.2013 09:34:30

На сайте есть ценник PriceList
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Плата с ARM CPU и Линух (Решено)

Сообщение vada » 11.09.2013 10:39:00

Дауж. Ценник кусается. Проще купить PocketBook какой-нибудь.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 691
Зарегистрирован: 14.02.2006 13:43:17

Re: Плата с ARM CPU и Линух (Решено)

Сообщение mig-31 » 11.09.2013 13:44:51

Не сказал бы. Главное применение, наверно автоматизация, вместо PLC (некоторые PLC выполняют только один Task ). Цена ниже, цены PLC с подобным количеством входов/выходов. Но PLC проще программировать.
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Плата с ARM CPU и Линух (Решено)

Сообщение debi12345 » 11.09.2013 15:08:49

Данные девайсы вообще не расчитаны на их програмирование. Их плюс - на их можно использовать море уже имеющегося линуксового софта - например ZoneMinder для систем видеонаблюдения. И даже выневого софта :)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Плата с ARM CPU и Линух (Решено)

Сообщение mig-31 » 11.09.2013 17:37:53

Подобная плата

http://www.acmesystems.it/FOXG20
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Плата с ARM CPU и Линух (Решено)

Сообщение debi12345 » 11.09.2013 17:43:49

http://www.acmesystems.it/FOXG20

Оно умеет писАть на внешний USB-HDD ? (чтобы не убивать загрузочную MicroSD)
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5759
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: Плата с ARM CPU и Линух (Решено)

Сообщение mig-31 » 11.09.2013 21:14:59

debi12345 писал(а):Оно умеет писАть на внешний USB-HDD ?


Обе платы работают с USB-HDD, но наверно потребуется внешнее питание.
mig-31
постоялец
 
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17

Рейтинг@Mail.ru