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

esaulenka

Свой
  • Постов

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

  • Посещение

  • Победитель дней

    2

Сообщения, опубликованные esaulenka


  1. ругаться тут можно на

    а) FIOxSET, FIOxCLR перед записью читать не нужно!!

    б) нестандартные имена

    в) некрасивый, на мой взгляд, вызов макроса

    предпочёл бы P0.0_IN(); вместо P0.0_IN;

    г) супер-мега-монстр типа дефайн-внутри-дефайна у меня не удался :)

    но такой объем copy-paste... некрасиво...

     

    я делал вот такую штуку

     

    // регистры Fast GPIO для LPC23xx
    #define PORT0    0x3FFFC000
    #define PORT1    0x3FFFC020
    #define PORT2    0x3FFFC040
    #define PORT3    0x3FFFC060
    #define PORT4    0x3FFFC080
    #define FIODIR(port)    (*(volatile unsigned long *)(port + 0x00))
    #define FIOMASK(port)    (*(volatile unsigned long *)(port + 0x10))
    #define FIOPIN(port)    (*(volatile unsigned long *)(port + 0x14))
    #define FIOSET(port)    (*(volatile unsigned long *)(port + 0x18))
    #define FIOCLR(port)    (*(volatile unsigned long *)(port + 0x1C))

     

    а потом определял кучу однотипных функций (надо было обращаться "поштучно" к 40 пинам, хаотично разбросанным по всем портам)

    #define DefPin(PinName,Port,BitNo)            \
        void Set##PinName (int val)                    \
        {                                            \
            FIODIR(Port) |= BIT(BitNo);                \
            if (val) FIOSET(Port) = BIT(BitNo);        \
            else FIOCLR(Port) = BIT(BitNo);            \
        }                                            \
        int Get##PinName (void)                        \
        {                                            \
            FIODIR(Port) &= ~BIT(BitNo);            \
            return (FIOPIN(Port) & BIT(BitNo));        \
        }
    
    DefPin (RST2, PORT1, 29);

     

    можно расширить, скажем, так:

    #define PORT_IN(port,pin)    FIODIR(port) &= ~(1UL<<(pin))
    #define PORT_SET(port,pin)    FIOSET(port) = (1UL<<(pin))

    впрочем, эти макросы тоже заслуживают эпитетов "нестандартно" и "некрасиво" ;)

  2. предлагаю воспользоваться гуглем вообще и

    http://www.keil.com/forum/docs/thread14304.asp

    в частности :)

     

    Кстати говоря, на сайте кейла весьма толковые книжки.

    http://www.keil.com/support/man_arm.htm

     

    И в форуме там тоже советы дельные. Разве что мне языка не хватает, чтобы грамотно задавать вопросы...

  3. Нарисовать в автокаде (это на порядок удобнее), перенести DXF в пикад, обвести получившийся набор линий.

     

    У нас так конструктор логотип нарисовал компании. Забавная штука получилась :)

    Вот только конструктор - бывший, посему подробности не расскажу...

  4. Угу, портится R0 и STRB вполне законно вылетает.

     

    Только вот всё остальное-то работает!

     

    В частности, в том же самом месте эта memcpy нормально вызывается 0x3890 раз (собственно, считываем прошивку целиком кусочками по 16 байт в один и тот же буфер). И дальше нормально выполняется, если указатель руками переставить...

     

    Прерывания выключать не пробовал, т.к. всё развалится. Хотя вот Test() вызывал до разрешения прерываний, оно работает.

     

    Освобожусь чуток, постараюсь разобраться...

  5. Наткнулся на непонятную проблему...

     

    Исходные данные:

    Keil, компилятор - древний кейловский CARM, оптимизаций нет.

    процессор LPC2138

     

     

    Есть такой код (вопросы по оптимальности использования LDRB/STRB, перебрасывания регистров туда-сюда - к авторам библиотек к CARM)

    0x000388F4  E59FC000  LDR       R12,[PC]
    0x000388F8  E12FFF1C  BX        R12
    0x000388FC  00038901  DD        0x00038901
                    strlen:
    0x00038900  2100      MOV       R1,#0x00
    0x00038902  E000      B         0x00038906
    0x00038904  3101      ADD       R1,#0x01
    0x00038906  1C02      ADD       R2,R0,#0
    0x00038908  3001      ADD       R0,#0x01
    0x0003890A  7812      LDRB      R2,[R2,#0x00]
    0x0003890C  2A00      CMP       R2,#0x00
    0x0003890E  D1F9      BNE       0x00038904
    0x00038910  1C08      ADD       R0,R1,#0
    0x00038912  4770      BX        LR
    
    0x00038914  E59FC000  LDR       R12,[PC]
    0x00038918  E12FFF1C  BX        R12
    0x0003891C  00038921  DD        0x00038921
                    memcpy:
    0x00038920  B430      PUSH      {R4-R5}
    0x00038922  1C03      ADD       R3,R0,#0
    0x00038924  1C18      ADD       R0,R3,#0
    0x00038926  E005      B         0x00038934
    0x00038928  1C0C      ADD       R4,R1,#0
    0x0003892A  7825      LDRB      R5,[R4,#0x00]
    0x0003892C  1C04      ADD       R4,R0,#0
    0x0003892E  7025      STRB      R5,[R4,#0x00]
    0x00038930  3101      ADD       R1,#0x01
    0x00038932  3001      ADD       R0,#0x01
    0x00038934  1C14      ADD       R4,R2,#0
    0x00038936  3A01      SUB       R2,#0x01
    0x00038938  2C00      CMP       R4,#0x00
    0x0003893A  D1F5      BNE       0x00038928
    0x0003893C  1C18      ADD       R0,R3,#0
    0x0003893E  BC30      POP       {R4-R5}
    0x00038940  4770      BX        LR
    

     

     

    вызываем

    memcpy (0x40002390, 0x00038910, 0x10)

     

    ... и попадаем в DataAbort.

     

    Содержимое регистров:

    R0 = 0x0000008A

    R1 = 0x00038911

    R2 = 0x0000000D

    R3 = 0x40002390

    R4 = 0x0000008A

    R5 = 0x0000001C

    R13 (SP) = 0x40002524

    R14 (LR) = 0x00038936

    R15 (PC) = 0x00000010

    SPSR = 0x00000030

     

     

    Какая-то мистика.

    memcpy (0x40002390, 0x00038920, 0x10)

    memcpy (0x40002390, 0x00038900, 0x10)

    - всё проходит нормально.

    Если выполнять этот код по шагам, всё также проходит нормально.

    Запускаем в обычном режиме - получите переход на 0x10...

     

    Экспериментально установлено, что если дошагать до

    0x00038926 E005 B 0x00038934

    дальше всё работает. Если запустить на выполнение до этой строки, получаем ошибку.

     

     

    Сделал тестовую функцию - она тоже работает нормально!

    Да, она действительно работает, оптимизатор до неё не добрался.

    Адреса менял - пофигу...

    void Test (void)
    {
    char buff[128];
    int ptr = 0x038910; // этот адрес менял уже из-под отладчика
    
    while (1)
    {
    	memcpy (buff, ptr, 16);
    }
    
    }
    

     

    Собственно, вопрос. Что это было?!

     

    Нарисовал CopyMem, которая копирует по 4 байта за раз - она работает хорошо. Но хочется разобраться...

  6. Забавно :)

    Как раз этим вопросом озадачился час назад.

     

    Итог - защита победила, пришлось делать отладочные спец-прошивки.

     

    Дано: LPC2138, Mt-Link, Segger RDI, Keil.

     

    Моё видение процесса:

    Мт-линк перезагружает контроллер.

    Бут видит magic, отключает джитаг.

    Основная программа пишет 0x04 в PINSEL2 - включает джитаг обратно.

    Однако процесс этот идёт неспешно, и мт-линк успевает убедиться, что джитаг отключен.

     

    Хм... Мысль: в настройках RDI есть некий macro file. Надо будет на досуге посмотреть...

     

     

    PS

    Ничего не изменится, если 0xFF во флэш писать. Задумайтесь.

    Для LPC'шек это верно? Там ведь только блоками можно писать, и никто не говорит, не пишутся ли там какие-нибудь контрольные суммы.

  7. поставить галку Project -> Manage -> Components,Environment,... -> Folders -> Use RealView Compiler (путь у меня сразу прописан правильный. если надо, уточнить)

     

    скопировать C:\Keil\ARM\Startup\Philips\Startup.s вместо используемого. В принципе, там только синтаксис макросов поменялся и символ комментария, можно и старый поправить

     

    А этот компилятор, которым пытаетесь собрать, помер...

    AARM MACRO ASSEMBLER V2.50 COPYRIGHT KEIL ELEKTRONIK GmbH 2003 - 2006

    ARM COMPILER V2.54a - SN: Eval Version COPYRIGHT KEIL ELEKTRONIK GmbH 2003 - 2006

    LARM LINKER/LOCATER V2.54a - SN: Eval Version COPYRIGHT KEIL ELEKTRONIK GmbH 2001 - 2006

  8. Небольшое уточнение.

    Вчера одним глазом посмотрел даташит на ATXL210.

    Для них нужны не два канала АЦП, а ещё пара таймеров с input capture - на выходе у него ШИМ.

     

    Требования к этому датчику Вы не озвучивали. Наверное, также надо опрашивать с частотой 100..200 Гц

     

     

    Примечание номер раз. Память, с которой могут работать одновременно два контроллера, штука редкая. О существовании такой флеш-памяти я вообще ни разу не слышал (правда, и не интересовался специально). О том, что запись во флеш мгновенно не осуществляется, молчу :)

    Примечание номер два. Программа на дельфи в реальном времени? Ой, не верю :)

  9. Какая-то неправильная задача :)

     

    Зачем вашей программе знать, что 499 тысяч раз в секунду НИЧЕГО НЕ МЕНЯЛОСЬ?

     

    Кроме того, такой объем данных уже достаточно сложно передавать - UART уже не успеет, а эмулятор COM-порта на USB при работе с отдельными байтами работает даже медленнее (во всяком случае, в моей реализации :)

     

     

    Предлагаю два варианта:

    - с компьютера приходит запрос, контроллер отвечает "двигатель 1 повернулся на 125 импульсов вправо, двигатель 2 повернулся на 13 импульсов влево, акселерометр показывает 43 попугая"

    - контроллер самостоятельно отправляет посылки "двигатель 1 повернулся влево", "двигатель 2 повернулся вправо" и т.д. на каждое изменение

  10. Критики? Да сколько угодно :)

     

    Предлагаю воспользоваться кнопочкой "поиск".

    Например, заслуживает тщательного изучения следующая тема:

    http://electronix.ru/forum/index.php?showtopic=55392

     

    Мне кажется, что

    - контроллер должен быть один. С отладкой взаимодействия нескольких контроллеров пока лучше не сталкиваться :)

    - АВРки тут вполне достаточно. Особенно если не заморачиваться с USB (опять таки, для начинающих могут быть проблемы), а воспользоваться RS232.

    - основная проблема - правильно передать данные из контроллера в этот Ваш LabView.

  11. собственный девайс на LPC2388 работает с флешкой

     

    О! Скажите, а стек вы готовый использовали?

     

    Посмотрел, что есть готового... Грустно как-то - какой-то маловразумительный код, практически без комментариев...

     

    Собственно, у меня задача попроще. Мне надо просто собрать USB-дескрипторы с внешних устройств, никакой поддержки mass storage и прочих HID'ов не требуется.

  12. Жили бы в пещерах и не знали бы горя.

    Во-во! :)

     

    Не занимайтесь ерундой: ресурс флеша не закончится!

    Раньше закончится проект или помрут ноги от коротких замыканий :)

     

    Надо написать такой scatter-файл, чтобы кейл прошивку располагал в ОЗУ (см. хелп кейла).

    Также надо как-то передавать туда управление. Думаю, соответствующая команда бутлоадера (см. даташит, ISP Commands) должна помочь :)

     

     

    Такой задачей никогда не занимался, делал чуть попроще - две прошивки во флеши, одна из которых располагалась по ненулевому адресу.

  13. Почитал доки на SRecord, спасибо.

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

     

    Подскажите, как написать красивее, без exclude ?

    rem вставим контрольную сумму
    srec_cat ^
        firmware.bin -binary ^
        -exclude 0x1000 0x1004 ^
        -little_endian_checksum_negative 0x1000 4 4 ^
        -o firmware.bin -binary

     

     

    И ещё. У нас для вставки билда в файл прошивки используется самописная утилитка, которая берёт результаты svn info <url>, вытаскивает оттуда revision, добавляет единицу и записывает в бинарник. svn info выдаёт что-то вроде

    Path: ***
    URL: ***
    Repository Root: ***
    Repository UUID: ***
    Revision: 681
    Node Kind: directory
    Last Changed Author: esaulenko
    Last Changed Rev: 680
    Last Changed Date: 2009-06-18 14:41:49 +0400 (Чт, 18 июн 2009)

    Нет желающих попинать автора SRecord, чтобы он реализовал нужный формат? :)

    Или все как-то по-другому контрольную сумму вставляют?

  14. В очередной раз сработала примета "напиши о проблеме, она сама решится" :)

     

    Банально вынес объявление векторов в отдельную процедурку, сказал "положить в ОЗУ" и кейл сделал всё самостоятельно. Чудеса :)

    AREA VECTORS_TBL,    CODE,    AT 0x40000000
    VECTORS_TABLE        PROC    ARM
    
    Vectors:        LDR     PC,Reset_Addr         
                    LDR     PC,Undef_Addr
                    LDR     PC,SWI_Addr
                    LDR     PC,PAbt_Addr
                    LDR     PC,DAbt_Addr
                    NOP                            /* Reserved Vector */
                    LDR     PC,[PC, #-0x0FF0]      /* Vector from VicVectAddr */
                    LDR     PC,FIQ_Addr
                                 
    
    Reset_Addr:     DD      Reset_Handler
    Undef_Addr:     DD      Undef_Handler?A
    SWI_Addr:       DD      SWI_Handler?A
    PAbt_Addr:      DD      PAbt_Handler?A
    DAbt_Addr:      DD      DAbt_Handler?A
    FIQ_Addr:       DD      FIQ_Handler?A
    
                        ENDP
    
    
    AREA   STARTUPCODE, CODE, AT 0x00002000
    
           PUBLIC  __startup
    __startup       PROC    ARM
    
    
    Reset_Handler:  
    
    // дальше совсем неинтересно :)

  15. Подниму тему.

     

    Скажите, а как красиво расположить вектор IRQ в ОЗУ?

    Вот эту конструкцию надо как-то отвязать от PC:

    LDR PC, [PC, #-0x0FF0] ; Vector from VicVectAddr

     

     

    Хотя и остальные вектора сделал как-то коряво...

    В стартапе вместо LDR PC, Addr сделал

    LDR        R0, =0x40000000
    LDR        R1, Reset_Addr
    STR        R1, [R0, #0x00]

     

    Надо бы какие-нибудь асмовые исходники почитать на досуге...

    Компилятор кейл, камень - 2138 (впрочем, это влияет только на расположение VicVectAddr).

  16. А в каком стандарте появились безымянные члены структур?

     

    Древний кейловский CARM нормально кушает объявление

    typedef struct
    {
        union
        {
            unsigned long long num;
            unsigned char ddb[8];
            struct 
            {
                unsigned long nlo;    
                unsigned long nhi;    
            };
        };
        char cnt;      
    } Numb_t;

     

    не ругается на

    Numb_t numb;

    numb.cnt = 1;

     

    зато на

    numb.num = 2;

    говорит, что undefined member

     

     

    Хм. Keil RealView (этот довольно свежий) пишет варнинги "expected an identifier" уже при объявлении структуры

    и ошибку struct "<unnamed>" has no field "num"

     

     

    IAR для АВРов кушает этот код без проблем.

×
×
  • Создать...