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

VladislavS

Свой
  • Постов

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

  • Посещение

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

    9

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


  1. 18 минут назад, KnightIgor сказал:

    Синтаксисы ассемблеров gcc и KEIL сильно отличаются

    Для Cortex-M легко и непринуждённо без ассемблера всё происходит. Не из репозитория, конечно, но с минимальными усилиями.

  2. Попрошу не тыкать! 

    Файлы те написаны людьми мало понимающими как работает стандартная библиотека в Keil. К делу, впрочем, это не относится. Скорее что-то с путями к системным файлам и файлам проекта.

    Конечно не смогу, у меня проекты из одних исходников тремя разными компиляторами собираются, куда уж мне пустой проект в Keil сделать....

     

  3. Пофиксили. Должно заработать. Но что-то я не уверен в оптимальности того что получается.

    Вот, например, на "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: Я правда циклы и загрузки в память из памяти в листинге почикал.

  4. 1 час назад, MrBearManul сказал:

    она не очень сложная

    Там есть кусок кода инициализации из стандартной библиотеки без исходников. Из общих представлений, кончено, можно догадаться что там происходит, но для новичка это сложно.

  5. Припоминаю, что 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();
    

     

  6. Что значит нравится, не нравится? Был КОНКРЕТНЫЙ вопрос, дан КОНКРЕТНЫЙ ответ. 

    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;
    }

    Но вы же не об этом спрашивали.

  7. 27 минут назад, adnega сказал:

    В общем случае может не сработать (конкретные примеры привести?).

    Примеров я и сам могу привести. В том числе и из Errata. Только ни о каком общем случае речи не было. Вопрос стоял конкретный:

    Цитата

    Как проще всего закинуть в порт GPIOA->ODR char данные

    в первые 8 бит но не трогать все остальные ?

     

  8. 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] 

     

     

    Мне кажется, это не бага, а компилятор что-то с выравниванием команд мутит.

  9. 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

     

  10. 14 часов назад, backa сказал:

    Вроде есть нечто платное VisualGDB

    На рутрекере есть. Работает хорошо. Создание проектов, редактирование, компиляция, прошивка, отладка. Достаточно просто сделать, чтобы из одних исходников собрать в VS, Keil, IAR или просто makefile.

  11. 4 минуты назад, MrBearManul сказал:

    Но вот действительно вопрос: как жи никто не напоролся на этот баг?

    Каков процент пользователей IAR из общего количества эмбеддеров? Сколько из них пользуется float? Как  часто те кто пользуется умножают на 2^n и усекают до 16 бит?

    Лично я последний раз в 2006 году использовал плавучку и то в double.

  12. //    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

     

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