-
Постов
1 241 -
Зарегистрирован
-
Посещение
-
Победитель дней
9
Сообщения, опубликованные VladislavS
-
-
18 минут назад, KnightIgor сказал:
Синтаксисы ассемблеров gcc и KEIL сильно отличаются
Для Cortex-M легко и непринуждённо без ассемблера всё происходит. Не из репозитория, конечно, но с минимальными усилиями.
-
Чтобы не было таких накладок, заголовочный файл контроллера и стартап должны лежать в проекте, а не подключаться "откуда-то оттуда". И стартап можно сделать универсальный на разные тулчейны.
-
8 минут назад, forummailandlogin сказал:
Кейлу всё равно есть в пути кириллица или её нет.
Судя по ошибке это не так. И это не обязательно пути. Читайте внимательно текст ошибки.
-
Попрошу не тыкать!
Файлы те написаны людьми мало понимающими как работает стандартная библиотека в Keil. К делу, впрочем, это не относится. Скорее что-то с путями к системным файлам и файлам проекта.
Конечно не смогу, у меня проекты из одних исходников тремя разными компиляторами собираются, куда уж мне пустой проект в Keil сделать....
-
Можно подумать, что это я не могу пустой проект скомпилировать.
-
Потому что ошибка ещё до компиляции main.c возникает.
-
Я бы внутрь startup_stm32f407xx.s заглянул.
-
Неужели так трудно без ошибок скомпилировать
int main() { }
и затем добавлять код и смотреть где ошибка?
-
Пофиксили. Должно заработать. Но что-то я не уверен в оптимальности того что получается.
Вот, например, на "size"
VMOV.F32 S0,#8.0 //res16 = (int)(x * 8) + 0x00008000ul; VLDR S1,[R1, #0] VMUL.F32 S1,S1,S0 VCVT.S32.F32 S1,S1 VMOV R3,S1 SUB R3,R3,#+32768 //res32 = (int)(x * 16) + 0x00008000ul; VLDR S0,[R1, #0] VCVT.S32.F32 S0,S0,#+4 VMOV R4,S0 ADD R4,R4,#+32768
А это на "speed"
//res16 = (int)(x * 8) + 0x00008000ul; VLDR S0,[R2, #0] VCVT.S32.F32 S0,S0,#+3 VMOV R3,S0 SUB R3,R3,#+32768 //res32 = (int)(x * 16) + 0x00008000ul; VMOV.F32 S0,#16.0 VLDR S1,[R2, #0] VMUL.F32 S1,S1,S0 VCVT.S32.F32 S1,S1 VMOV R3,S1 ADD R3,R3,#+32768
PS: Я правда циклы и загрузки в память из памяти в листинге почикал.
-
На вкладке Debugger в свойствах проекта.
-
1 час назад, MrBearManul сказал:
она не очень сложная
Там есть кусок кода инициализации из стандартной библиотеки без исходников. Из общих представлений, кончено, можно догадаться что там происходит, но для новичка это сложно.
-
Припоминаю, что Keil-овская стандартная библиотека на ядре M4F при инициализации использует FPU. Если его не включить в SystemInit, то будет Hardfault-иться и до main() не дойдёт. Проверьте что эта строка не заифдефлена.
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
А оптимальнее вот так
SCB->CPACR = ((3UL << 10*2)|(3UL << 11*2)); // set CP10 and CP11 Full Access.
И послушайте совет MrBearManul - в пошаговом режиме в окне дизассемблера пройдитесь до ошибки. Это не так уж сложно.
PS: Переходите уже на 6-й компилятор.
PPS:
//__asm volatile ("cpsie i"); __enable_irq();
-
Я бы начал с
volatile unsigned char *from;
Затем листинг смотрел. И неплохо бы название контроллера и компилятора узнать.
-
Что значит нравится, не нравится? Был КОНКРЕТНЫЙ вопрос, дан КОНКРЕТНЫЙ ответ.
42 минуты назад, whale сказал:а если нужно не 8 бит а 5 или 3
Это уже другая задача. Которая в общем виде решается так
using pVU8 = volatile uint8_t*; using pVU16 = volatile uint16_t*; using pVU32 = volatile uint32_t*; template<uint32_t PM> static inline void write(uint32_t data) { if constexpr (PM==0) return; if constexpr (PM == 0xFFFF) base()->ODR = data; else if constexpr (PM == 0x00FF) *pVU8(&base()->ODR) = data; else if constexpr (PM == 0xFF00) *(pVU8(&base()->ODR) + 1) = data >> 8; else base()->BSRR = (PM << 16) | (data & PM); } //Оптимизация записи по маске 32-битного регистра с возможностью 8 и 16-битного доступа template<uint32_t mask> static inline void writeReg32(pVU32 reg, uint32_t value) { if constexpr (mask==0) return; if constexpr (mask == 0xFFFF'FFFF) *reg = value; else if constexpr (mask == 0x0000'FFFF) *pVU16(reg) = value; else if constexpr (mask == 0xFFFF'0000) *(pVU16(reg) + 1) = value >> 16; else if constexpr (mask == 0x0000'00FF) *pVU8(reg) = value; else if constexpr (mask == 0x0000'FF00) *(pVU8(reg) + 1) = value >> 8; else if constexpr (mask == 0x00FF'0000) *(pVU8(reg) + 2) = value >> 16; else if constexpr (mask == 0xFF00'0000) *(pVU8(reg) + 3) = value >> 24; else if constexpr ((mask & 0xFFFF'FF00)==0) *pVU8(reg) = (*pVU8(reg) & ~mask) | value; else if constexpr (!(mask & 0xFFFF'00FF)) *(pVU8(reg) + 1) = (*(pVU8(reg) + 1) & ~(mask >> 8)) | (value >> 8); else if constexpr (!(mask & 0xFF00'FFFF)) *(pVU8(reg) + 2) = (*(pVU8(reg) + 2) & ~(mask >> 16)) | (value >> 16); else if constexpr (!(mask & 0x00FF'FFFF)) *(pVU8(reg) + 3) = (*(pVU8(reg) + 3) & ~(mask >> 24)) | (value >> 24); else if constexpr (!(mask & 0xFFFF'0000)) *pVU16(reg) = (*pVU16(reg) & ~mask) | value; else if constexpr (!(mask & 0x0000'FFFF)) *(pVU16(reg) + 1) = (*(pVU16(reg) + 1) & ~(mask >> 16)) | (value >> 16); else *reg = (*reg & ~mask) | value; }
Но вы же не об этом спрашивали.
-
27 минут назад, adnega сказал:
В общем случае может не сработать (конкретные примеры привести?).
Примеров я и сам могу привести. В том числе и из Errata. Только ни о каком общем случае речи не было. Вопрос стоял конкретный:
ЦитатаКак проще всего закинуть в порт GPIOA->ODR char данные
в первые 8 бит но не трогать все остальные ?
-
1 час назад, Darth Vader сказал:
Может не сработать
Как это? Порт указан, контроллер угадан. Что там может не сработать? Не сработает на F1, но речь не про него.
-
37 минут назад, jcxz сказал:
Для ядер >= M3 генерится LDRSB, для <M3 - LDRB
На крайней версии компилятора всё так же.
-----------------------------------------
ARM Compiler 6.15, Cortex-M4F
0x20001B00 B081 SUB sp,sp,#0x04 10: i0 += 25 << moFault; 0x20001B02 F2422030 MOVW r0,#0x2230 0x20001B06 F2C20000 MOVT r0,#0x2000 0x20001B0A F2422240 MOVW r2,#0x2240 0x20001B0E 7800 LDRB r0,[r0,#0x00] 0x20001B10 F2C20200 MOVT r2,#0x2000 0x20001B14 2119 MOVS r1,#0x19 0x20001B16 6813 LDR r3,[r2,#0x00] 0x20001B18 FA01F000 LSL r0,r1,r0 0x20001B1C 4418 ADD r0,r0,r3 0x20001B1E 6010 STR r0,[r2,#0x00] 11: volatile int x = i0; 0x20001B20 9000 STR r0,[sp,#0x00] 0x20001B22 BF00 NOP 0x20001B24 E7FE B 0x20001B24
------------------------------------------
GCC 10.1 , Cortex-M4F, -03
10: i0 += 25 << moFault; 0x200002c4 05 4B ldr r3, [pc, #20] ; (0x200002dc <main()+24>) 0x200002c6 06 4A ldr r2, [pc, #24] ; (0x200002e0 <main()+28>) 0x200002c8 18 78 ldrb r0, [r3, #0] 0x200002ca 11 68 ldr r1, [r2, #0] 0x200002cc 19 23 movs r3, #25 9: { 0x200002ce 82 B0 sub sp, #8 0x200002d0 83 40 lsls r3, r0 0x200002d2 0B 44 add r3, r1 0x200002d4 13 60 str r3, [r2, #0]
Мне кажется, это не бага, а компилятор что-то с выравниванием команд мутит.
-
Причём тут GCC? Первая "I" не скопипастилась.
-
AR C/C++ Compiler for ARM 8.50.9.278 (8.50.9.278), Cortex-M0, оптимизация High Speed.
//static uint8_t volatile moFault; moFault: DS8 1 DS8 3 //int i0; i0: DS8 4 //int main() //{ main: SUB SP,SP,#+4 // i0 += 25 << moFault; LDR R0,??DataTable0 LDR R1,[R0, #+4] MOVS R2,#+25 LDRB R0,[R0, #+0] LSLS R2,R2,R0 ADDS R0,R1,R2 // volatile int x = i0; STR R0,[SP, #+0] //for(;;); ??main_0: B ??main_0 //} ??DataTable0: DC32 moFault
-
14 часов назад, backa сказал:
Вроде есть нечто платное VisualGDB
На рутрекере есть. Работает хорошо. Создание проектов, редактирование, компиляция, прошивка, отладка. Достаточно просто сделать, чтобы из одних исходников собрать в VS, Keil, IAR или просто makefile.
-
4 минуты назад, MrBearManul сказал:
Но вот действительно вопрос: как жи никто не напоролся на этот баг?
Каков процент пользователей IAR из общего количества эмбеддеров? Сколько из них пользуется float? Как часто те кто пользуется умножают на 2^n и усекают до 16 бит?
Лично я последний раз в 2006 году использовал плавучку и то в double.
-
32 минуты назад, jcxz сказал:
Это на какой версии IAR?
8.50.9. Оптимизация High->Size.
Для 32 бит вот так стабильно лечится. (int32_t)(eeg*16) + (int32_t)B15;
-
// 9 constexpr float eeg[] = { eeg: DATA32 DC32 0x4174'a79a, 0xbc22'79e6, 0xc1ab'ab56, 0xc236'1238, 0xc286'8ffa DC32 0xc2a0'1c4a, 0xc29b'8275, 0xc26e'936b, 0xc1f6'ddfd, 0x4015'5349 DC32 0x420d'872f, 0x4281'849d, 0x42ad'6fea, 0x42c1'34d8, 0x42b5'c24a DC32 0x428b'bd67, 0x4214'c9a3, 0xbf9d'179e, 0xc212'7e61 // 10 1.5290918e+01, // 11 -9.9167579e-03, // 12 -2.1458661e+01, // 13 -4.5517792e+01, // 14 -6.7281206e+01, // 15 -8.0055255e+01, // 16 -7.7754796e+01, // 17 -5.9643962e+01, // 18 -3.0858393e+01, // 19 2.3332083e+00, // 20 3.5382015e+01, // 21 6.4759012e+01, // 22 8.6718579e+01, // 23 9.6603208e+01, // 24 9.0879472e+01, // 25 6.9869923e+01, // 26 3.7196912e+01, // 27 -1.2272832e+00, // 28 -3.6623416e+01 // 29 }; // 44 inline constexpr TEST test; test: DATA32 DC32 33'012, 32'768, 32'425, 32'040, 31'692, 31'488, 31'524, 31'814 DC32 32'275, 32'805, 33'334, 33'804, 34'155, 34'313, 34'222, 33'885 DC32 33'363, 32'749, 32'183 // 46 int main() // 47 { main: PUSH {R3-R7,LR} // 48 for(uint32_t i=0; i<ncell(eeg); i++) MOVS R4,#+0 ADR.N R5,?_0 LDR.N R6,??DataTable3 LDR.N R7,??DataTable3_1 // 49 { // 50 uint32_t tmp = (int32_t)(eeg[i]*16) + 0x00008000ul; // 51 DEBUG_Print("%10d %10d\r\n",tmp,test(i)); ??main_0: ADD R0,R6,R4, LSL #+2 LDR R3,[R7, R4, LSL #+2] MOV R1,R5 ADDS R4,R4,#+1 VLDR S0,[R0, #0] MOVS R0,#+0 VCVT.U32.F32 S0,S0,#+4 VMOV R2,S0 ADD R2,R2,#+32768 BL SEGGER_RTT_printf CMP R4,#+19 BCC.N ??main_0
-
Поделюсь. Чуть позже, работа пришла :)
Если отключить FPU, то колонки совпадают.
Прерывание от USB в STM32F: косяк KEIL vs. GCC
в STM
Опубликовано · Пожаловаться
И вам не хворать.