Перейти к содержанию
    

Antokha

Участник
  • Постов

    31
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Antokha

  • Звание
    Участник
    Участник
  • День рождения 14.09.1985

Контакты

  • ICQ
    Array

Информация

  • Город
    Array
  1. Народ, у меня composite cdc + MSC заработал из ASF с небольшими танцами с бубном на conf_usb.h, НО по безопасному извлечению устройства отображаемый диск не размонтируется (в Windows)... что очень странно, могут быть проблемы с потерей данных. Так, ну ладно, нашел обработчик команды безопасное извлечение устройства (команда SCSI START STOP UNIT) udi_msc_sbc_start_stop и вписал после него udd_detach() - типа по обработчику все сделали можно демонтировать. Так в этом случае винда говорит на размонтирование устройства что оно с ошибкой произошло, то есть что-то не доработало до логического конца. Кто-нибудь если сталкивался подскажите куда копать. Вторая проблема при удалении файла с этого раздела он не сразу удаляется, поэтому функция сохраняющая данные в него при проверке говорит что файл не могу открыть и пытается создать новый.
  2. LCP2939

    С какой скоростью работают на LPC2939 выводы? В PDF-нике написано что на частоте ядра, которая равна 125 МГц. Но судя по AT91RM9200, с которым я работал, возможны ограничения. Поэтому привожу описание программы время выполнения каждого тела цикла хотелось бы узнать. Надеюсь у кого-нибудь завалялась плата с LPC2939. Необходим следующий режим работы: - формируем единичку на одном выводе (назовем его Pin_1); - считываем состояние соседнего вывода (к нему присоединен выход другого устройства); - формируем ноль на Pin_1. Эта последовательность повторяется в цикле 20 раз. Формирование единицы и нуля необходимо для проверки правильности установки длительности выполнения тела цикла и отметки времени считывания порта. Интересует следующее время выполнения (T): _ _ _ _ начало______| считали состояние вывода |________ . . .______| считали состояние вывода |________ -->|---------------------------|<--- T
  3. Нда, нашел в чём проблема была - в файле compile переменную LDFLAGS="-T elf32-littlearm.lds -Ttext 0" надо заменить на LDFLAGS="-T elf32-littlearm.lds". Всего ничего, но неделю убил.
  4. Собственно задача: имеется ubuntu, кросскомпилятор arm-linux-gcc 2.95.3 (ну я думаю это не столь важно), нормально компилирующийся этим кросскомпилятором проект romboot (запускается первым на плате, копирует секции из SPI-флеш в SDRAM, предварительно их инициализировав). Скрипты для сборки: compile: #!/bin/sh OUTPUT1=romboot1 CROSS=/usr/local/arm/2.95.3/bin/arm-linux- #/usr/local/arm/<version>/bin #CROSS=/opt/cross/bin/arm-linux- #GCC="$CROSS"gcc GCC="$CROSS"gcc LD="$CROSS"ld OBJCOPY="$CROSS"objcopy SIZE="$CROSS"size OBJDUMP="$CROSS"objdump LDFLAGS="-T elf32-littlearm.lds -Ttext 0" $GCC asm_isr.S -c -Iinclude $GCC cstartup_ram.S -c -Iinclude $GCC jump.S -c -Iinclude $GCC at45.cpp -c -Iinclude -Os $GCC com.cpp -c -Iinclude -Os $GCC dataflash.cpp -c -Iinclude -Os $GCC init.cpp -c -Iinclude -Os $GCC main.cpp -c -Iinclude -Os $GCC -c stdio.cpp -Os $GCC -c _udivsi3.S $GCC -c _umodsi3.S $GCC -c div0.c -Os $LD cstartup_ram.o asm_isr.o jump.o at45.o com.o dataflash.o init.o main.o stdio.o _udivsi3.o _umodsi3.o div0.o -o $OUTPUT1.out $LDFLAGS -n $OBJCOPY $OUTPUT1.out -O binary $OUTPUT1.bin $OBJDUMP -h -s $OUTPUT1.out > $OUTPUT1.lss $SIZE $OUTPUT1.out elf32-littlearm.lds OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { *(.text) } . = ALIGN(4); .rodata : { *(.rodata) } . = ALIGN(4); .data : { *(.data) } . = ALIGN(4); .bss : { *(.bss) } } Необходимо запустить этот (хотя бы) проект (для определённости назовём его romboot2) после небольшого увеличения функционала этим же romboot-ом (соответственно romboot1), но по адресу 0x20000000 (План: 1. Пуск romboot1 (он копирует romboot2 в SDRAM и запускает его на выполнение. 2. Работа romboot2). Как я написал romboot1 нормально собирается. Для сборки romboot2 правлю elf32-littlearm.lds: /* link.ld - GNU ld script */ OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /* */ OUTPUT_ARCH(arm); ENTRY(_start); /* точка входа программы */ MEMORY { ram : ORIGIN = 0x20000000, LENGTH = 0x8000 } SECTIONS /* куда какую информацию размещать */ { . = ALIGN(4); .text : /* размещение самой программы (исполняемый код) */ { . = ALIGN(4); /* оператор точка определяет текущий адрес, оператор ALIGN(4) – предписываем компоновщику выравнивать адреса по 4 байта */ KEEP(*(.RESET)) /* таблица векторов прерывания в начале памяти, KEEP */ *(.text*) /* исполняемый код */ *(.rodata*) /* константы */ *(.glue_7) *(.glue_7t) } > ram _etext = .; . = ALIGN(4); .data : /* размещение ненулевых данных */ { _data = .; *(.data*) _edata = .; } > ram . = ALIGN(4); .bss : { _bss = .; *(.bss*) _ebss = .; } > ram _stack_size = 500; _stack_top = 0x20000000 + 0x8000; _stack_begin = _stack_top - _stack_size; . = ALIGN(4); . = _stack_begin; ._stack : { . = . + _stack_size; } > ram } В ИАРе всё просто изменяется (в файле *.icf): define symbol __ICFEDIT_intvec_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_start__ = 0x20000080; define symbol __ICFEDIT_region_RAM_end__ = 0x20008000; Здесь же получаю: anton@ANTON:~/Рабочий стол/3_new_Xmodem_on_USART1/3$ sh compile_except /usr/local/arm/2.95.3/bin/arm-linux-ld: address 0xa0 of romboot1.out section .text is not within region ram /usr/local/arm/2.95.3/bin/arm-linux-objcopy: romboot1.out: ??? ?????? ????? ??? ???????? /usr/local/arm/2.95.3/bin/arm-linux-objdump: romboot1.out: ??? ?????? ????? ??? ???????? /usr/local/arm/2.95.3/bin/arm-linux-objdump: romboot1.out: ??? ?????? ????? ??? ???????? /usr/local/arm/2.95.3/bin/arm-linux-size: romboot1.out: ??? ?????? ????? ??? ???????? Пробовал разными способами указать, что адрес начала программы на целевой платформе будет не 0x0, а любой другой. В лучшем случае получался файл размером 512 Мб, в худшем описанная выше ошибка (хотя она похожа на то, что программа не убирается, но я-то её ещё вообще не трогал. как работала нормально в случае romboo1 на 16кБ внутренней SRAM, также и должна работать в SDRAM(её-то 16 Мб)). Видимо я как-то неправильно в принципе делаю. Пять дней бьюсь-->результат нулевой. Голова уже не работает. Возможно ошибка во флагах для сборки проекта romboot2, но как-то в это не вериться: как правильно указать линкеру адреса VMA не найду никак.
  5. Попробовал изменить последовательность запуска этих сервисов: pAT91 = AT91C_ROM_BOOT_ADDRESS; // Tempo Initialisation pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); //if (!pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC))) \ AT91F_DBGU_Printk("\n\rOpenCtlTempo(): OpenCtlTempo initialized\n\r"); //OK ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); //if ((ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)))== 2 ) \ AT91F_DBGU_Printk("\n\rCtlTempoStart returns 2\n\r"); //OK // Attach the tempo to a tempo controler //ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // <<<<<<<<------------здесь в окне гипертерминала пишет the software tempo wasn't created // svcUbootTempo.Start(&svcUbootTempo,100,0,NULL,NULL); // Xmodem Initialisation pXmBuffer = pAT91->OpenSBuffer(&sXmBuffer); pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, (AT91PS_USART)AT91C_BASE_DBGU, &ctlTempo); //--- //pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, (AT91PS_USART)AT91C_BASE_US1, &ctlTempo); pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer); // System Timer initialization AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, // AIC base address AT91C_ID_SYS, // System peripheral ID AT91C_AIC_PRIOR_HIGHEST, // Max priority AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive AT91F_ST_ASM_Handler ); // Enable ST interrupt AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS); // DataFlash on SPI Configuration AT91F_DataflashInit (); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // <<<<<<<<------------здесь в окне гипертерминала пишет the software tempo was created // start tempo to start Uboot in a delay of 1 sec if no key pressed svcUbootTempo.Start(&svcUbootTempo, 1000, 0, AT91F_StartUboot, (void *)0); Результат: при втором запуске всё добавляется. Убираю первый запуск (оставляя второй, т.е. тот что после AT91F_DataflashInit ()) получаю опять сообщение "the software tempo wasn't created".
  6. Решил прикрутить к своей программе протокол x-modem и управление программой через hyperterminal. Взял за основу romboot от Atmel-a, который я уже сам компилировал с помощью gcc под линуксом (ubuntu). Программа к которой хочу прикрутить x-modem делалась в ИАР-е, поэтому создал проект в ИАР 5.11, добавил файлы romboot-а, поправил c_startup.s, asm-обработчик прерывания. Проект компилируется, но смущают восемь warning-ов на файл embedded_services.h на структуры в самом конце этого файла где написаны const. Ладно - под линуксом работало и здесь вроде бы тоже должно. Заливаю по X-modem-у в контроллер AT91RM9200. Не определяется флеш. Начинаю копать покомандно с выводом ошибок через printf: int main(void) { AT91PS_Buffer pXmBuffer; AT91PS_SvcComm pSvcXmodem; AT91S_SvcTempo svcUbootTempo; // Link to a AT91S_Tempo object unsigned int AddressToDownload, SizeToDownload; unsigned int DeviceAddress = 0; volatile int i = 0; char command = 0; unsigned int crc1 = 0, crc2 = 0; volatile int device; int NbPage; stdin = fopen(0, at91_dbgu_getc); stdout = fopen(at91_dbgu_putc, 0); pAT91 = AT91C_ROM_BOOT_ADDRESS; // Tempo Initialisation pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); //if (!pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC))) \ AT91F_DBGU_Printk("\n\rOpenCtlTempo(): OpenCtlTempo initialized\n\r"); //OK ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); //if ((ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)))== 2 ) \ AT91F_DBGU_Printk("\n\rCtlTempoStart returns 2\n\r"); //OK // Attach the tempo to a tempo controler //ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo); if ((ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo)) == 1) AT91F_DBGU_Printk("\n\rthe software tempo wasn't created\n\r");\ else AT91F_DBGU_Printk("\n\rthe software tempo was created\n\r"); // svcUbootTempo.Start(&svcUbootTempo,100,0,NULL,NULL); На ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo) выводит ошибку. Прошу поделиться опытом применения встроенного ПО контроллера. Чего не правильно уже понять не могу. В приложении мой проект для ИАРа. Так же не работает кроме SPI-флешки X-modem (имеется ввиду его реализация в бинарнике romboot-a: его функции: он не принимает бинарник). Romboot.rar
  7. Это моя отсебятина, начитался pdf-ника. Там сказано регистр считать, а cstartup.s не доглядел. Про ошибку: При использовании функции AT91F_AIC_ConfigureIt объявляя функцию static __arm __irq void PIOA_Handler( void ), получаю ошибку: Error[Pe167]: argument of type "void (__arm __irq *)()" is incompatible with parameter of type "void (*)()" На данный момент сделал так: Инит: AT91C_BASE_PIOA->PIO_PPUDR |= ( DataInput ); AT91C_BASE_PIOA->PIO_ODR = ( DataInput ); AT91C_BASE_PIOA->PIO_BSR = ( DataInput ); AT91C_BASE_AIC->AIC_IDCR = ( 1UL<<AT91C_ID_IRQ2 );//disable interrupt IRQ2 AT91C_BASE_AIC->AIC_SVR[AT91C_ID_IRQ2] |= ( AT91_REG )PIOA_Handler; // set isr AT91C_BASE_AIC->AIC_SMR[AT91C_ID_IRQ2] |= ( AT91C_AIC_SRCTYPE_EXT_HIGH_LEVEL ) | ( 7 ); // prio 7 AT91C_BASE_AIC->AIC_ICCR = ( 1UL<<AT91C_ID_IRQ2 );//clear interrupt AT91C_BASE_AIC->AIC_IECR = ( 1UL<<AT91C_ID_IRQ2 );//enable interrupt Обработка: static __irq __arm void PIOA_Handler( void ) {AT91C_BASE_PIOB->PIO_SODR = ( DDS_P2_MODULATION ); /* PB7 - выв 87 AT91RM9200 */ AT91C_BASE_PIOB->PIO_CODR = ( DDS_P2_MODULATION ); /* PB7 are output */ AT91C_BASE_AIC->AIC_EOICR = 0; } виснет после команды __enable_interrupt(); P.S. Имя обработчика прерывания осталось от нужного когда-то прерывания, извините уж. А книжка - Это Редькин П.П. "32/16-битные микроконтроллеры ARM7 семейства AT91SAM7 Руководство пользователя"
  8. Про ошибку завтра днём. Компилятор (от IAR 5.11) дома не пашет.
  9. Книжка может быть и Редькина, точно скажу завтра днем. При использовании функции AT91F_AIC_ConfigureIt объявляя функцию static __arm __irq void PIOA_Handler( void ), получаю ошибку. Пробовал ещё так: - настройка: AT91C_BASE_PIOA->PIO_ODR |= ( DataInput ); /* PB27 are input */ AT91C_BASE_PIOA->PIO_ASR |= ( DataInput ); AT91C_BASE_AIC->AIC_IDCR |= ( 1UL<<AT91C_ID_IRQ2 );//disable interrupt IRQ2 AT91C_BASE_AIC->AIC_SVR[AT91C_ID_IRQ2] |= ( AT91_REG )PIOA_Handler; // set isr AT91C_BASE_AIC->AIC_SMR[AT91C_ID_IRQ2] |= ( AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED ) | ( 7 )); // prio 7 AT91C_BASE_AIC->AIC_ICCR |= ( 1UL<<AT91C_ID_IRQ2 );//clear interrupt AT91C_BASE_AIC->AIC_IECR |= ( 1UL<<AT91C_ID_IRQ2 );//enable interrupt функцию PIOA_Handler объявляю как: static __arm __irq void PIOA_Handler( void ); без ошибок компилируется, но работает также.
  10. Функция (обработчик прерывания) должна выплюнуть последовательный код на ножку PB7. Восстановление контекста - какое именно, в pdf написано что возврат в прерванную функцию производится самостоятельно, ничего дописывать не надо, или я что-то не так понял. У меня поганится один из массивов - такое ощущение, что нормального выхода из прерывания нет и контроллер дальше выполняет инструкции, следующие за кодом прерывания (неизвестно какие -:( ). Код static void PIOA_Handler( void ) В void IntInit(void): ... AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_IRQ2, 7, AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, PIOA_Handler); ... Вообще void IntInit(void) брал из книги по ARM7, там AIC такой-же. Вырезка из lib_AT91RM9200.h: __inline unsigned int AT91F_AIC_ConfigureIt ( AT91PS_AIC pAic, // \arg pointer to the AIC registers unsigned int irq_id, // \arg interrupt number to initialize unsigned int priority, // \arg priority to give to the interrupt unsigned int src_type, // \arg activation and sense of activation void (*newHandler) (void) ) // \arg address of the interrupt handler { unsigned int oldHandler; unsigned int mask; oldHandler = pAic->AIC_SVR[irq_id]; mask = 0x1 << irq_id; //* Disable the interrupt on the interrupt controller pAic->AIC_IDCR = mask; //* Save the interrupt handler routine pointer and the interrupt priority pAic->AIC_SVR[irq_id] = (unsigned int) newHandler; //* Store the Source Mode Register pAic->AIC_SMR[irq_id] = src_type | priority; //* Clear the interrupt on the interrupt controller pAic->AIC_ICCR = mask; return oldHandler; }
  11. AT91C_BASE_PIOB->PIO_SODR |= ( DDS_P2_MODULATION ); - установить вывод PB7 в 1. AT91C_BASE_PIOB->PIO_CODR |= ( DDS_P2_MODULATION ); - установить вывод PB7 в 0. AIC_ICCR - это на самом деле лишнее. Прерывание - внешнее - IRQ2, соответствует выводу PA25. Мне лучше, чтобы по фронтуили спаду прерывание обрабатывалось, чем по уровню. Я думаю будет точнее работать (время от появления какого либо фронта до установления PB7 в единичку)
  12. Если это про AIC_IVR, то это я наверно на автомате набрал, читая pdf на контроллер. Вообще-то этот регистр уже наверно считался до входа в эту процедуру обработки: cstartup.s: ... __irq_handler: ldr PC,[PC,#-0xF20] ;; IRQ .... AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED в файле AT91RM9200.h описан как: #define AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED ((unsigned int) 0x1 << 5) // (AIC) Internal Sources Code Label Edge triggered, т.е. в соответствии с pdf на контроллер это и прерывание по фронту для внутреннего источника так и прерывание по спаду для внешнего прерывания.
  13. У меня почти такая же проблема: второй раз не обрабатывает прерывание и докучи перезаписывает один из существующих массивов (программа не зависает, если это важно). Камень AT91RM9200 Инициализация (сделана отдельной функцией): void IntInit(void) {AT91F_PIO_CfgInput(AT91C_BASE_PIOA, DataInput); AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, DataInput, 0); AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_IRQ2, 7, AT91C_AIC_SRCTYPE_INT_EDGE_TRIGGERED, PIOA_Handler); // prio AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_IRQ2); } Обработчик: extern int p[33]; static void PIOA_Handler( void ) { AT91C_BASE_AIC->AIC_IVR; AT91C_BASE_PIOB->PIO_SODR |= ( DDS_P2_MODULATION ); /* PB7 - выв 87 AT91RM9200 */ AT91C_BASE_PIOB->PIO_CODR |= ( DDS_P2_MODULATION ); /* PB7 are output */ AT91C_BASE_AIC->AIC_ICCR |= ( 1UL<<AT91C_ID_IRQ2 );//clear interrupt AT91C_BASE_AIC->AIC_EOICR = 0; } Строки, касающиеся прерывания из main(): ... IntInit(); AT91C_BASE_PIOB->PIO_SODR |= ( DDS_P2_MODULATION ); /* PB7 - выв 87 AT91RM9200 */ __enable_interrupt(); delay(5000); AT91C_BASE_PIOB->PIO_CODR |= ( DDS_P2_MODULATION ); /* PB7 are output */ ...
  14. Другими словами, описания начала и конца сегментов, содержащих весь код программы и лежащих до маркера, недостаточно?
  15. Я уже тоже думаю сделать примерно также. Но вариант с кэшем надо проработать до логического завершенния.
×
×
  • Создать...