|
C+ASM - помогите, Не понимаю, чего ему не нравится |
|
|
|
Mar 5 2008, 05:45
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Всем приветы! Ткскзть двое суток без сна, не могу победить простую вещь. Имеется IAR 4.41, пытаюсь сделать ассемблерную вставку, не выходит: Код static inline portDISABLE_INTERRUPTS(void) { asm (" STMDB SP!, {R0}"); asm (" MRS R0, CPSR"); asm (" ORR R0,R0,#0x80"); asm (" MSR CPSR,R0"); asm (" LDMIA SP!, {R0}"); } В ответ получаю Код Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 93 Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 94 Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" c:\PTJoy\new\firmware\ptjoy\FreeRTOS\Source\portable\IAR\SAM7S256\portmacro.h 95 По-хорошему, нужно делать #define'ом, но там то-же самое, только без номеров строк Ткните пожалуйста, что я делаю не так. Процессор - ARM7. Спасибо!
|
|
|
|
|
Mar 5 2008, 06:31
|
Частый гость
 
Группа: Свой
Сообщений: 151
Регистрация: 21-02-06
Пользователь №: 14 561

|
Код asm (" MRS R0, CPSR"); asm (" ORR R0,R0,#0x80"); asm (" MSR CPSR,R0"); В этих командах у Вас ошибка синтаксиса, посмотрите manual.
|
|
|
|
|
Mar 5 2008, 06:46
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(tag @ Mar 5 2008, 09:31)  В этих командах у Вас ошибка синтаксиса, посмотрите manual. Смотрю ассемблерный листинг, сгенерированный этим-же компилятором: Код vPortEnterCritical: MRS R0,CPSR ORR R0,R0,#0xC0 MSR CPSR_c,R0 и не вижу разницы...
|
|
|
|
|
Mar 5 2008, 07:05
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Ассемблерную строку надо заканчивать символом \n См. в описании компилятора главу INLINE ASSEMBLER. Пример из описания: Код bool flag; void foo() { while (!flag) { asm(" ldr r2,[pc,#0] \n" /* r2 = address of flag */ " b .+8 \n" /* jump over constant */ " DCD flag \n" /* address of flag */ " ldr r3,[pc,#0] \n" /* r3 = address of PIND */ " b .+8 \n" /* jump over constant */ " DCD PIND \n" /* address of PIND */ " ldr r0,[r3] \n" /* r0 = PIND */ " str r0,[r2]"); /* flag = r0 */ } } Хотя может и не в этом дело.
|
|
|
|
|
Mar 5 2008, 07:08
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(IgorKossak @ Mar 5 2008, 10:05)  Ассемблерную строку надо заканчивать символом \n См. в описании компилятора главу INLINE ASSEMBLER. Да пробовал и с \n: Код static inline portDISABLE_INTERRUPTS(void) { asm (" STMDB SP!, {R0}\n"); asm (" MRS R0, CPSR\n"); asm (" ORR R0,R0,#0x80\n"); asm (" MSR CPSR,R0\n"); asm (" LDMIA SP!, {R0}\n"); } Ошибки те-же в тех-же местах. ЗЫ большие-маленькие мнемоники я тоже пробовал, и названия регистров тоже
|
|
|
|
|
Mar 5 2008, 07:15
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
Цитата(Kitsok @ Mar 5 2008, 12:08)  Ошибки те-же в тех-же местах. а у меня ваш код без проблем откомпилировался: Код # IAR ARM ANSI C/C++ Compiler V4.41A/W32 EVALUATION 05/Mar/2008 12:09:03 # \ In segment CODE, align 4, keep-with-next 266 void portDISABLE_INTERRUPTS(void) 267 { 268 asm (" STMDB SP!, {R0}"); \ ??portDISABLE_INTERRUPTS: \ 00000000 01002DE9 STMDB SP!, {R0} 269 asm (" MRS R0, CPSR"); \ 00000004 00000FE1 MRS R0, CPSR 270 asm (" ORR R0,R0,#0x80"); \ 00000008 800080E3 ORR R0,R0,#0x80 271 asm (" MSR CPSR,R0"); \ 0000000C 00F029E1 MSR CPSR,R0 272 asm (" LDMIA SP!, {R0}"); \ 00000010 0100BDE8 LDMIA SP!, {R0} 273 } \ 00000014 0EF0A0E1 MOV PC,LR ;; return А почему вы не хотите: Код void portDISABLE_INTERRUPTS_1(void) { __set_CPSR(__get_CPSR() | 0x80); } ?
--------------------
Пасу котов...
|
|
|
|
|
Mar 5 2008, 07:31
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(IgorKossak @ Mar 5 2008, 10:21)  Взял Вашу функцию один к одному, скомпилировал, ни одной ошибки. Правда у меня версия 5.11, но не думаю, чтобы так сильно всё отличалось.
Нашел в чём дело. Если в настройках компилятора устанавливаю Code->Processor mode->Thumb, то возникает ошибка 401. С ARM всё нормально. Вот похоже, что в этом и дело. В итоге вот так скомпилялось, а работает или нет - буду проверять Код __arm __interwork static inline __disable_IRQ( void );
__arm __interwork static inline __disable_IRQ(void) { asm (" stmdb SP!, {r0}\n"); asm (" mrs r0, CPSR\n"); asm (" orr r0,r0,#0x80\n"); asm (" msr CPSR,r0\n"); asm (" ldmia SP!, {r0}\n"); }
#define portDISABLE_INTERRUPTS() __disable_IRQ()
|
|
|
|
|
Mar 5 2008, 07:35
|

Знающий
   
Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206

|
более правильный код для запрещения прерываний на АРМ такой: Код do { __set_CPSR(StatusReg | (1<<7)); } while (!(__get_CPSR() & (1<<7)));
--------------------
Пасу котов...
|
|
|
|
|
Mar 5 2008, 07:54
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Цитата(Andy Mozzhevilov @ Mar 5 2008, 10:35)  более правильный код для запрещения прерываний на АРМ такой: Код do { __set_CPSR(StatusReg | (1<<7)); } while (!(__get_CPSR() & (1<<7))); Дык у меня thumb, а __?et_CPSR - intrinsic, поэтому, видимо, все функции, вызывающие такой запрет нужно компилять с __intrinsic. А в чем разница с моим-то?  Вон, родной __disable_interrupt вообще даже R0 в стеке не сохраняет.
|
|
|
|
|
Mar 5 2008, 10:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Andy Mozzhevilov @ Mar 5 2008, 09:35)  более правильный код для запрещения прерываний на АРМ такой: Еще более оптимальный такой (исправлен): Код while (!(__get_CPSR() & (1<<7))) { __set_CPSR(StatusReg | (1<<7)); } Цитата(Andy Mozzhevilov @ Mar 5 2008, 10:15)  Не могу сейчас быстро найти соответсвующий раздел документации. Atmel Application Note Rev. 1156A-08/98Цитата(Kitsok @ Mar 5 2008, 09:54)  Дык у меня thumb, а __?et_CPSR - intrinsic, поэтому, видимо, все функции, вызывающие такой запрет нужно компилять с __intrinsic. Доступ к CPSR имеют только команды ARM-режима (MSR, MRS). Из THUMB режима могут быть вызваны ARM-функции, скомпилированные с атрибутом __interwork. __intrinsic - ключевое слово для функций, реализованных внутри компилятора (для которых компилятор генерит код сам в процессе компиляции) и не должно использоваться для пользовательских функций. Генерируемый для __intrinsic - функций код может отличаться в зависимости от аргументов, режима компиляции и кучи других параметров. Для той же __disable_interrupt() в ARM-режиме генерится непосредственно MSR, MCR, а в THUMB-режиме - вызов соответствующей ARM-функции.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 5 2008, 11:33
|
Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 9-11-06
Пользователь №: 22 136

|
Вот на этом while'е оно и встанет  Точка с запятой там явно лишняя. Да, __intrinsic перепутал естественно с __interwork. Вроде работает, спасибо! Начинаем битву с FIQ, но это уже тема совсем другого топика
|
|
|
|
|
Mar 5 2008, 12:41
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Kitsok @ Mar 5 2008, 13:33)  Вот на этом while'е оно и встанет  Точка с запятой там явно лишняя. Угу. Делал быстро из кода Andy, упустил. Цитата(repairDV @ Mar 5 2008, 14:35)  А этот ассемблер, который внутри процедуры Си, полнофункциональный? Условные - безусловные переходы на метки поддерживает? Нет. Это даже не ассемблер, а так, некий костыль чтобы вставить NOP. Даже в документации написано что-то вроде "ну есть нечто похожее на ассемблер, но лучше и не пытайтесь его использовать  ". В этом смысле инлайн-ассемблер GCC - просто произведение искусства.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|