Autor Tema: Cálculos en punto flotante con un cortex M0  (Leído 2293 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Cálculos en punto flotante con un cortex M0
« en: 06 de Septiembre de 2017, 06:40:06 »
Hola a todos.
Para un experimento casero necesito leer la temperatura en 4 puntos diferentes. Para ello estoy utilizando 4 termistores de vishay NTC de 10k.
Empecé a hacerlo con un pic18F2550, y con él conseguí leer los 4 valores con el ADC, convertirlos a temperatura y enviarlos por el puerto serie junto con la fecha y hora leida de un DS1307 por I2C. Al compilar, el XC8 decía que estaba utilizando un 30% de la memoria del micro disponible aproximadamente (no me acuerdo ahora de la cifra exacta).

También estuve haciendo pruebas con un arduino uno, el del atmega, y también compilaba y funcionaba bien.

Por seguir experimentando, lo estoy intentando hacer ahora con un STM32F030, el de la placa que venden en ebay por 1,6€, y aquí es donde empiezan los problemas.

He configurado los periféricos con STM32CubeMX, los 4 canales de ADC y el puerto serie por ahora. He podido leer los 4 canales de ADC y enviar los valores enteros por el puerto serie, pero cuando meto la fórmula de cálculo de la temperatura de los termistores:

Código: [Seleccionar]
float CalculaTemp(uint32_t ValorADC){
  float fTemp;
  float fRes;

  fRes = log((_NUMPASOS/ValorADC)-1);

  fTemp = (1 / (_A1 + fRes*(_B1 + fRes*(_C1+_D1*fRes))))-273.15;
  return fTemp;
}

}

el linker da un error de que estoy sobrepasando la capacidad de la memoria flash del dispositivo, que son 32 kB.

Si comento las lineas en las que hago los cálculos, vuelve a compilar y enlazar sin problemas, por lo que supongo que será por los cálculos de punto flotante, pero también los estoy utilizando en el pic y en el arduino sin problemas.

¿Hay alguna librería de cálculos en punto flotante que sea algo más ligera? ¿Cómo se utilizaría?

Muchas gracias.

« Última modificación: 06 de Septiembre de 2017, 16:45:27 por fuente »

Desconectado MerLiNz

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2463
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #1 en: 06 de Septiembre de 2017, 06:47:55 »
Lo mas sencillo y eficiente seria que el micro enviase los datos ADC por uart y el software del puerto serie los convierta a valores ºC asi evitas saturar el micro.

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #2 en: 06 de Septiembre de 2017, 07:06:28 »
Sí, inicialmente lo iba  a hacer así, pero se me ocurrió la posibilidad de ver las temperaturas en alguna pantalla LCD.

De todas formas, si en el PIC y en arduino se puede, también debería poderse hacer en este.

Desconectado george.manson.69

  • PIC10
  • *
  • Mensajes: 33
    • Microcontroladores en General
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #3 en: 06 de Septiembre de 2017, 12:11:15 »
¿Puedes decir que plataforma estas usando para programar el STM32? para yo compilarlo y a ver si es un problema de linkeo o algun otro problema del compilador.

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #4 en: 06 de Septiembre de 2017, 13:02:33 »
Estoy utilizando en Ubuntu el compilador gcc (arm-none-eabi), creo que la última version, y con el makefile que genera el STM32CubeMX.

Ya le quité la opción de debug y le añadí la optimización para tamaño de código, pero no le basta.

Muchas gracias por la ayuda.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #5 en: 06 de Septiembre de 2017, 15:05:58 »
¿Se podria saber que tipo son los coeficientes?

Para probarlo, y ademas el codigo tiene un error, hay un parentesis de mas o de menos.
« Última modificación: 06 de Septiembre de 2017, 16:07:47 por KILLERJC »

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #6 en: 06 de Septiembre de 2017, 16:49:08 »
Perdonad, no tenía el codigo a mano y lo escribí de memoria. Lo he editado y ya está el que estoy compilando.

Los coeficientes son:

Código: [Seleccionar]
#define _A1 0.003354016
#define _B1 0.000256985
#define _C1 0.000002620131
#define _D1 0.00000006383091
#define _NUMPASOS 4096.0

Y el resultado de la compilación:

Código: [Seleccionar]
-------------- Build: Release in Prueba_UART (compiler: GNU GCC Compiler)---------------

Checking if target is up-to-date: make -q -f Makefile Release
Running command: make -f Makefile
/usr/bin/arm-none-eabi-gcc -c -mcpu=cortex-m0 -mthumb   -DUSE_HAL_DRIVER -DSTM32F030x6 -IInc -IDrivers/STM32F0xx_HAL_Driver/Inc -IDrivers/STM32F0xx_HAL_Driver/Inc/Legacy -IDrivers/CMSIS/Device/ST/STM32F0xx/Include -IDrivers/CMSIS/Include -Os -Wall -fdata-sections -ffunction-sections -MMD -MP -MF"build/main.d" -MT"build/main.d" -Wa,-a,-ad,-alms=build/main.lst Src/main.c -o build/main.o
Src/main.c: In function 'HAL_ADC_ConvCpltCallback':
Src/main.c:121:16: warning: unused variable 'i' [-Wunused-variable]
  unsigned char i;
                ^
Src/main.c: In function 'main':
Src/main.c:215:17: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
     len=sprintf(buffer,"Temperatura: %i ºC\r\n",temperature); //sprintf will return the length of 'buffer'
                 ^
In file included from /usr/include/newlib/stdio.h:29:0,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h:50,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h:45,
                 from Inc/stm32f0xx_hal_conf.h:193,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h:46,
                 from Src/main.c:40:
/usr/include/newlib/stdio.h:231:5: note: expected 'char * restrict' but argument is of type 'unsigned char *'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^
Src/main.c:215:24: warning: format '%i' expects argument of type 'int', but argument 3 has type 'int32_t {aka long int}' [-Wformat=]
     len=sprintf(buffer,"Temperatura: %i ºC\r\n",temperature); //sprintf will return the length of 'buffer'
                        ^
Src/main.c:215:24: warning: format '%i' expects argument of type 'int', but argument 3 has type 'int32_t {aka long int}' [-Wformat=]
Src/main.c:218:17: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
     len=sprintf(buffer,"Numero de ciclos: %i Numero de conversiones: %i.\r\n",numConv2, numConv1); //sprintf will return the length of 'buffer'
                 ^
In file included from /usr/include/newlib/stdio.h:29:0,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h:50,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h:45,
                 from Inc/stm32f0xx_hal_conf.h:193,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h:46,
                 from Src/main.c:40:
/usr/include/newlib/stdio.h:231:5: note: expected 'char * restrict' but argument is of type 'unsigned char *'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^
Src/main.c:218:24: warning: format '%i' expects argument of type 'int', but argument 3 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
     len=sprintf(buffer,"Numero de ciclos: %i Numero de conversiones: %i.\r\n",numConv2, numConv1); //sprintf will return the length of 'buffer'
                        ^
Src/main.c:218:24: warning: format '%i' expects argument of type 'int', but argument 4 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
Src/main.c:218:24: warning: format '%i' expects argument of type 'int', but argument 3 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
Src/main.c:218:24: warning: format '%i' expects argument of type 'int', but argument 4 has type 'uint32_t {aka long unsigned int}' [-Wformat=]
Src/main.c:225:21: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
         len=sprintf(buffer,"canal %i: %d,%d.\r\n",i, tempEnt[i],tempDec[i]); //sprintf will return the length of 'buffer'
                     ^
In file included from /usr/include/newlib/stdio.h:29:0,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h:50,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h:45,
                 from Inc/stm32f0xx_hal_conf.h:193,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h:46,
                 from Src/main.c:40:
/usr/include/newlib/stdio.h:231:5: note: expected 'char * restrict' but argument is of type 'unsigned char *'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^
Src/main.c:225:28: warning: format '%d' expects argument of type 'int', but argument 4 has type 'int32_t {aka long int}' [-Wformat=]
         len=sprintf(buffer,"canal %i: %d,%d.\r\n",i, tempEnt[i],tempDec[i]); //sprintf will return the length of 'buffer'
                            ^
Src/main.c:225:28: warning: format '%d' expects argument of type 'int', but argument 5 has type 'int32_t {aka long int}' [-Wformat=]
Src/main.c:225:28: warning: format '%d' expects argument of type 'int', but argument 4 has type 'int32_t {aka long int}' [-Wformat=]
Src/main.c:225:28: warning: format '%d' expects argument of type 'int', but argument 5 has type 'int32_t {aka long int}' [-Wformat=]
Src/main.c:228:17: warning: pointer targets in passing argument 1 of 'sprintf' differ in signedness [-Wpointer-sign]
     len=sprintf(buffer,"\r\n"); //sprintf will return the length of 'buffer'
                 ^
In file included from /usr/include/newlib/stdio.h:29:0,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_def.h:50,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_rcc.h:45,
                 from Inc/stm32f0xx_hal_conf.h:193,
                 from Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal.h:46,
                 from Src/main.c:40:
/usr/include/newlib/stdio.h:231:5: note: expected 'char * restrict' but argument is of type 'unsigned char *'
 int _EXFUN(sprintf, (char *__restrict, const char *__restrict, ...)
     ^
/usr/bin/arm-none-eabi-gcc build/stm32f0xx_hal_tim.o build/stm32f0xx_hal_gpio.o build/stm32f0xx_hal_tim_ex.o build/stm32f0xx_it.o build/stm32f0xx_hal.o build/stm32f0xx_hal_cortex.o build/system_stm32f0xx.o build/stm32f0xx_hal_pwr.o build/stm32f0xx_hal_uart.o build/stm32f0xx_hal_rcc.o build/stm32f0xx_hal_rcc_ex.o build/main.o build/stm32f0xx_hal_pwr_ex.o build/stm32f0xx_hal_msp.o build/stm32f0xx_hal_uart_ex.o build/stm32f0xx_hal_adc_ex.o build/stm32f0xx_hal_adc.o build/startup_stm32f030x6.o -mcpu=cortex-m0 -mthumb   -specs=nano.specs -TSTM32F030F4Px_FLASH.ld  -lc -lm -lnosys -Wl,-Map=build/Prueba_UART.map,--cref -Wl,--gc-sections -o build/Prueba_UART.elf
/usr/lib/gcc/arm-none-eabi/5.4.1/../../../arm-none-eabi/bin/ld: build/Prueba_UART.elf section `.text' will not fit in region `FLASH'
/usr/lib/gcc/arm-none-eabi/5.4.1/../../../arm-none-eabi/bin/ld: region `FLASH' overflowed by 5460 bytes
collect2: error: ld returned 1 exit status
make: *** [build/Prueba_UART.elf] Error 1
Makefile:176: fallo en las instrucciones para el objetivo 'build/Prueba_UART.elf'
Process terminated with status 2 (0 minute(s), 2 second(s))
2 error(s), 15 warning(s) (0 minute(s), 2 second(s))
 

En un rato puedo subir todos los fuentes para que probéis.

Muchísimas gracias.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #7 en: 06 de Septiembre de 2017, 17:22:46 »
Sacando de lado todos los warning por el mal uso del tipo en los printf, si el problema es ese.
Por lo que lei, es problema de GCC, y es que ocupan MUCHO al no tener un acelerador hardware.

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #8 en: 06 de Septiembre de 2017, 17:49:17 »
Sí, lo de los sprintf para sacar datos son pruebas y no le he prestado mucha atención.

De todas formas, el PIC tampoco tiene el acelerador hardware y el xc8 lo hace bien. Por eso preguntaba si hay alguna librería o se me ha pasado por alto algún parámetro del compilador.
Tendré que plantearme si sigo con el PIC o paso a un m3.

Desconectado tsk

  • PIC18
  • ****
  • Mensajes: 257
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #9 en: 06 de Septiembre de 2017, 18:08:53 »
Sí, lo de los sprintf para sacar datos son pruebas y no le he prestado mucha atención.

De todas formas, el PIC tampoco tiene el acelerador hardware y el xc8 lo hace bien. Por eso preguntaba si hay alguna librería o se me ha pasado por alto algún parámetro del compilador.
Tendré que plantearme si sigo con el PIC o paso a un m3.

No creo que sea cuestión de usar un M3, está más relacionado con el uso de las librerías. Usa las LL en lugar de las HAL, las HAL te van a consumir toda la memoria.

Eso lo modificas en Project->Settings->Advance Settings, por defecto estan con las HAL, sólo las cambias a LL.

Con eso es más que suficiente para contar con un binario por mucho más pequeño

Con las HAL, compilando únicamente con el código generado por cubeMX

Código: [Seleccionar]
/usr/bin/arm-none-eabi-size build/stm32f030Test.elf
   text    data     bss     dec     hex filename
   5708      12    1756    7476    1d34 build/stm32f030Test.elf

Con las LL

Código: [Seleccionar]
/usr/bin/arm-none-eabi-size build/stm32f030Test.elf
   text    data     bss     dec     hex filename
   2380      12    1564    3956     f74 build/stm32f030Test.elf

Como interpretas el resultado:

text + data es el tamaño del binario generado:

data + bss es la cantidad de RAM que se esta usando

Recuerda que sólo cuentas con 4K en RAM y 32K en FLASH, por lo que los tiene que manejar para evitar que te quedes sin memoria.

Con tan sólo agregar la librería math.h y string.h y haciendo un cálculo dentro del while principal

Código: C
  1. sprintf(buffer,"Hola Mundo\r\n");
  2. HAL_UART_Transmit(&huart1,(uint8_t*)&buffer[0],strlen(buffer),100);
  3. AL_Delay(1000);
  4. float t = CalculaTemp(2333);

Código: [Seleccionar]
text    data     bss     dec     hex filename
  15316     116    1756   17188    4324 build/stm32f030Test.elf

Eso representa ya la mitad de la memoria disponible

Si ahora lo cambiamos a:

Código: C
  1. float t = CalculaTemp(2333);
  2. sprintf(buffer,"Temperatura: %i %f\r\n",2333,t);
  3. HAL_UART_Transmit(&huart1,(uint8_t*)&buffer[0],strlen(buffer),100);
  4. HAL_Delay(1000);

Código: [Seleccionar]
text    data     bss     dec     hex filename
  17800     116    1772   19688    4ce8 build/stm32f030Test.elf

Si ahora generamos RCC, GPIO y ADC con LL y USART1 con HAL

Código: [Seleccionar]
text    data     bss     dec     hex filename
  15384     116    1700   17200    4330 build/stm32f030Test.elf

Ahora todo con LL

Código: C
  1. float t = CalculaTemp(2333);
  2.         uint32_t i,len;
  3.         len = sprintf(buffer,"Temperatura: %i %f\r\n",2333,t);
  4.         //HAL_UART_Transmit(,(uint8_t*)&buffer[0],len,100);
  5.         for(i=0;i<len;i++)
  6.         {
  7.                 LL_USART_TransmitData8(USART1,buffer[i]);
  8.         }
  9.         for(i=0;i<60000;i++){}

Código: [Seleccionar]
/usr/bin/arm-none-eabi-size build/stm32f030Test.elf
   text    data     bss     dec     hex filename
  13848     116    1580   15544    3cb8 build/stm32f030Test.elf

Es fácil quedarse sin espacio.

Cambiando en el Makefile -Og a -Os, el resultado de arriba queda:

Código: [Seleccionar]
/usr/bin/arm-none-eabi-size build/stm32f030Test.elf
   text    data     bss     dec     hex filename
  13736     116    1580   15432    3c48 build/stm32f030Test.elf
« Última modificación: 06 de Septiembre de 2017, 18:14:04 por tsk »

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #10 en: 06 de Septiembre de 2017, 19:59:57 »
tengo tirados un puñado de esos micros por acá, 32Kb de flash es muy poco, por lo menos para mis proyectos y por desconocimiento los compre solo mirando el precio. Lo que he hecho es seguir con el F030, pero otra version, con 64K de flash. Con ese sí estoy resolviendo todos mis proyectos.

Muy buen aporte el de tsk con las LL y las diversas compilaciones!  ((:-))

Saludos!
-
Leonardo Garberoglio

Desconectado Carl47D

  • PIC16
  • ***
  • Mensajes: 160
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #11 en: 06 de Septiembre de 2017, 22:57:27 »
Hola a todos.
Para un experimento casero necesito leer la temperatura en 4 puntos diferentes. Para ello estoy utilizando 4 termistores de vishay NTC de 10k.
Empecé a hacerlo con un pic18F2550, y con él conseguí leer los 4 valores con el ADC, convertirlos a temperatura y enviarlos por el puerto serie junto con la fecha y hora leida de un DS1307 por I2C. Al compilar, el XC8 decía que estaba utilizando un 30% de la memoria del micro disponible aproximadamente (no me acuerdo ahora de la cifra exacta).

También estuve haciendo pruebas con un arduino uno, el del atmega, y también compilaba y funcionaba bien.

Por seguir experimentando, lo estoy intentando hacer ahora con un STM32F030, el de la placa que venden en ebay por 1,6€, y aquí es donde empiezan los problemas.

He configurado los periféricos con STM32CubeMX, los 4 canales de ADC y el puerto serie por ahora. He podido leer los 4 canales de ADC y enviar los valores enteros por el puerto serie, pero cuando meto la fórmula de cálculo de la temperatura de los termistores:

Código: [Seleccionar]
float CalculaTemp(uint32_t ValorADC){
  float fTemp;
  float fRes;

  fRes = log((_NUMPASOS/ValorADC)-1);

  fTemp = (1 / (_A1 + fRes*(_B1 + fRes*(_C1+_D1*fRes))))-273.15;
  return fTemp;
}

}

el linker da un error de que estoy sobrepasando la capacidad de la memoria flash del dispositivo, que son 32 kB.

Si comento las lineas en las que hago los cálculos, vuelve a compilar y enlazar sin problemas, por lo que supongo que será por los cálculos de punto flotante, pero también los estoy utilizando en el pic y en el arduino sin problemas.

¿Hay alguna librería de cálculos en punto flotante que sea algo más ligera? ¿Cómo se utilizaría?

Muchas gracias.

¿Te servirán las librerías de CMSIS? Están "optimizadas" para Cortex Ms, aca como configurar un IDE basado en Eclipse para usarlas, que al final es casi lo mismo que configurar un makefile pero con UI.
En concreto el header arm_math.h en lugar de math.h: https://community.nxp.com/thread/386810

Desconectado fuente

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 571
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #12 en: 07 de Septiembre de 2017, 17:33:47 »
Muchas gracias por la ayuda.

He estado probando a compilar con las librerías qfplib (h**ps://www.quinapalus.com/qfplib.html) y algo ha mejorado, aunque no consigo que entre todavía. Este fin de semana probaré a cambiar las librerías HAL por las LL a ver que tal.

De todas formas, aunque lo consiga, me temo que me voy a quedar sin espacio para hacer otras cosas. Es una pena, porque además del precio, me gusta el encapsulado.

Desconectado cristian_elect

  • PIC18
  • ****
  • Mensajes: 453
Re:Cálculos en punto flotante con un cortex M0
« Respuesta #13 en: 08 de Septiembre de 2017, 20:57:43 »
Prueba con el Keil. Probe con numeros float y no tira mas de 10KB de flash con HAL.
« Última modificación: 08 de Septiembre de 2017, 22:26:15 por cristian_elect »