Эта математическая ошибка исправляется? W_POW, STM32F1 HAL CORE

Mailhouse
Солнце 13 ноября 2016 г., 19:23
Сбой при использовании STM32F1 с Nucleo 103RB, работает при использовании STM32L4 с Nucleo 476RG

/////////////////////////////////////////////////////////////////////// // // tone(pin,frequency[,duration]) generate a tone on a given pin // // noTone(pin) switch off the tone on the pin // // setToneTimerChannel(timer,channel) force use of given timer/channel // /////////////////////////////////////////////////////////////////////// #include "Arduino.h" #include // define default timer and channel #ifndef TONE_TIMER #define TONE_TIMER 4 #endif #ifndef TONE_CHANNEL #define TONE_CHANNEL 4 #endif #define PinTimer(pin) (PIN_MAP[pin].timer_device->clk_id-RCC_TIMER1+1) #define PinChannel(pin) (PIN_MAP[pin].timer_channel) // if USE_PIN_TIMER is set, the PWM timer/channel is used for PWM pins #define USE_PIN_TIMER // if USE_BSRR is set the tone pin will be written via the fast BSRR register // instead of using the slow digitalWrite() function in the interrupt handler #define USE_BSRR // construct static timer array ( HardwareTimer TTimer1(1), TTimer2(2), TTimer3(3), TTimer4(4); #ifdef STM32_HIGH_DENSITY HardwareTimer TTimer5(5), TTimer6(6), TTimer7(7), TTimer8(8); #endif HardwareTimer *TTimer[4] { &TTimer1,&TTimer2,&TTimer3,&TTimer4 #ifdef STM32_HIGH_DENSITY ,&TTimer5,&TTimer6,&TTimer7,&TTimer8 #endif }; uint8_t tone_force_channel = 0; // forced timer channel uint8_t tone_force_ntimer = 0; // forced timer HardwareTimer *tone_timer = TTimer[TONE_TIMER]; // timer used to generate frequency uint8_t tone_channel = TONE_CHANNEL; // timer channel used to generate frequency uint8_t tone_ntimer = TONE_TIMER; // timer used to generate frequency bool tone_state = true; // last pin state for toggling short tone_pin = -1; // pin for outputting sound short tone_freq = 444; // tone frequency (0=pause) uint32_t tone_nhw = 0; // tone duration in number of half waves uint16_t tone_tcount = 0; // time between handler calls in 1/36 usec uint16_t tone_ncount = 0; // handler call between toggling uint16_t tone_n = 0; // remaining handler calls before toggling uint32_t tone_next = 0; // counter value of next interrupt #ifdef USE_BSRR volatile uint32_t *tone_bsrr; // BSRR set register (lower 16 bits) uint32_t tone_smask=0; // BSRR set bitmask uint32_t tone_rmask=0; // BSRR reset bitmask #endif //////////////////////////////////////////////////////////////////////////////// // timer hander for tone with no duration specified, // will keep going until noTone() is called void tone_handler_1(void) { tone_next += tone_tcount; // comparator value for next interrupt tone_timer->setCompare(tone_channel, tone_next); // and install it if(--tone_n == 0){ tone_state = !tone_state; // toggle tone output #ifdef USE_BSRR if(tone_state) *tone_bsrr = tone_smask; else *tone_bsrr = tone_rmask; #else digitalWrite(tone_pin,tone_state);// and output it #endif tone_n = tone_ncount; // reset interrupt counter } } //////////////////////////////////////////////////////////////////////////////// // timer hander for tone with a specified duration, // will stop automatically when duration time is up. void tone_handler_2(void) { tone_next += tone_tcount; tone_timer->setCompare(tone_channel, tone_next); if(--tone_n == 0){ if(tone_freq>0){ // toggle pin tone_state = !tone_state; #ifdef USE_BSRR if(tone_state) *tone_bsrr = tone_smask; else *tone_bsrr = tone_rmask; #else digitalWrite(tone_pin,tone_state);// and output it #endif } tone_n = tone_ncount; if(!--tone_nhw){ // check if tone duration has finished tone_timer->pause(); // disable timer pinMode(tone_pin, INPUT); // disable tone pin } } } //////////////////////////////////////////////////////////////////////////////// // play a tone on given pin with given frequency and optional duration in msec void tone(uint8_t pin, short freq, unsigned duration = 0) { tone_pin = pin; #ifdef USE_PIN_TIMER // if the pin has a PWM timer/channel, use it (unless the timer/channel are forced) if(PinChannel(tone_pin) && !tone_force_channel){ tone_channel = PinChannel(tone_pin); tone_ntimer = PinTimer(tone_pin); } else #endif { // set timer and channel to default resp values forced with setToneTimerChannel tone_ntimer = tone_force_channel?tone_force_ntimer:TONE_TIMER; tone_channel = tone_force_channel?tone_force_channel:TONE_CHANNEL; } tone_timer = TTimer[tone_ntimer-1]; tone_freq = freq; tone_nhw = 0; tone_next = 0; tone_timer->pause(); if(freq > 0 || duration >0 ){ uint32_t count = 18000000/freq; // timer counts per half wave tone_ncount = tone_n = (count>>16)+1; // number of 16-bit count chunk tone_tcount = count/tone_ncount; // size of count chunk if(duration > 0) // number of half waves to be generated tone_nhw = ((duration*(freq>0?freq:100))/1000)<<1; else // no duration specified, continuous sound until noTone() called tone_nhw = 0; pinMode(tone_pin, PWM); // configure output pin pinMode(tone_pin, OUTPUT); // configure output pin #ifdef USE_BSRR // Set up BSRR register values for fast ISR tone_bsrr = &((PIN_MAP[tone_pin].gpio_device)->regs->BSRR); tone_smask = (BIT(PIN_MAP[tone_pin].gpio_bit)); tone_rmask = tone_smask<<16; #endif // Set up an interrupt on given timer and channel tone_next = tone_tcount; // prepare channel compare register tone_timer->setMode(tone_channel,TIMER_OUTPUT_COMPARE); tone_timer->setCompare(tone_channel,tone_next); // attach corresponding handler routine tone_timer->attachInterrupt(tone_channel,tone_nhw?tone_handler_2:tone_handler_1); // Refresh the tone timer tone_timer->refresh(); // Start the timer counting tone_timer->resume(); } else { // detach handler routine tone_timer->detachInterrupt(tone_channel); // disactive pin by configuring it as input pinMode(tone_pin, INPUT); } } //////////////////////////////////////////////////////////////////////////////// // disable tone on specified pin, if any void noTone(uint8_t pin){ tone(pin,-1); // it's all handled in tone() } //////////////////////////////////////////////////////////////////////////////// // set timer and channel to some different value // must be called before calling tone() or after noTone() was called void setToneTimerChannel(uint8_t ntimer, uint8_t channel){ tone_force_ntimer = ntimer; tone_force_channel = channel; } /* Arduino Mario Bros Tunes With Piezo Buzzer and PWM Connect the positive side of the Buzzer to pin 3, then the negative side to a 1k ohm resistor. Connect the other side of the 1 k ohm resistor to ground(GND) pin on the Arduino. by: Dipto Pratyaksa last updated: 31/3/13 */ /************************************************* * Public Constants *************************************************/ #define NOTE_B0 31 #define NOTE_C1 33 #define NOTE_CS1 35 #define NOTE_D1 37 #define NOTE_DS1 39 #define NOTE_E1 41 #define NOTE_F1 44 #define NOTE_FS1 46 #define NOTE_G1 49 #define NOTE_GS1 52 #define NOTE_A1 55 #define NOTE_AS1 58 #define NOTE_B1 62 #define NOTE_C2 65 #define NOTE_CS2 69 #define NOTE_D2 73 #define NOTE_DS2 78 #define NOTE_E2 82 #define NOTE_F2 87 #define NOTE_FS2 93 #define NOTE_G2 98 #define NOTE_GS2 104 #define NOTE_A2 110 #define NOTE_AS2 117 #define NOTE_B2 123 #define NOTE_C3 131 #define NOTE_CS3 139 #define NOTE_D3 147 #define NOTE_DS3 156 #define NOTE_E3 165 #define NOTE_F3 175 #define NOTE_FS3 185 #define NOTE_G3 196 #define NOTE_GS3 208 #define NOTE_A3 220 #define NOTE_AS3 233 #define NOTE_B3 247 #define NOTE_C4 262 #define NOTE_CS4 277 #define NOTE_D4 294 #define NOTE_DS4 311 #define NOTE_E4 330 #define NOTE_F4 349 #define NOTE_FS4 370 #define NOTE_G4 392 #define NOTE_GS4 415 #define NOTE_A4 440 #define NOTE_AS4 466 #define NOTE_B4 494 #define NOTE_C5 523 #define NOTE_CS5 554 #define NOTE_D5 587 #define NOTE_DS5 622 #define NOTE_E5 659 #define NOTE_F5 698 #define NOTE_FS5 740 #define NOTE_G5 784 #define NOTE_GS5 831 #define NOTE_A5 880 #define NOTE_AS5 932 #define NOTE_B5 988 #define NOTE_C6 1047 #define NOTE_CS6 1109 #define NOTE_D6 1175 #define NOTE_DS6 1245 #define NOTE_E6 1319 #define NOTE_F6 1397 #define NOTE_FS6 1480 #define NOTE_G6 1568 #define NOTE_GS6 1661 #define NOTE_A6 1760 #define NOTE_AS6 1865 #define NOTE_B6 1976 #define NOTE_C7 2093 #define NOTE_CS7 2217 #define NOTE_D7 2349 #define NOTE_DS7 2489 #define NOTE_E7 2637 #define NOTE_F7 2794 #define NOTE_FS7 2960 #define NOTE_G7 3136 #define NOTE_GS7 3322 #define NOTE_A7 3520 #define NOTE_AS7 3729 #define NOTE_B7 3951 #define NOTE_C8 4186 #define NOTE_CS8 4435 #define NOTE_D8 4699 #define NOTE_DS8 4978 #define melodyPin PB0 //Mario main theme melody int melody[] = { NOTE_E7, NOTE_E7, 0, NOTE_E7, 0, NOTE_C7, NOTE_E7, 0, NOTE_G7, 0, 0, 0, NOTE_G6, 0, 0, 0, NOTE_C7, 0, 0, NOTE_G6, 0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0, NOTE_C7, NOTE_D7, NOTE_B6, 0, 0, NOTE_C7, 0, 0, NOTE_G6, 0, 0, NOTE_E6, 0, 0, NOTE_A6, 0, NOTE_B6, 0, NOTE_AS6, NOTE_A6, 0, NOTE_G6, NOTE_E7, NOTE_G7, NOTE_A7, 0, NOTE_F7, NOTE_G7, 0, NOTE_E7, 0, NOTE_C7, NOTE_D7, NOTE_B6, 0, 0 }; //Mario main them tempo int tempo[] = { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 9, 9, 9, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, }; //Underworld melody int underworld_melody[] = { NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, NOTE_AS3, NOTE_AS4, 0, 0, NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, NOTE_AS3, NOTE_AS4, 0, 0, NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, NOTE_DS3, NOTE_DS4, 0, 0, NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, NOTE_DS3, NOTE_DS4, 0, 0, NOTE_DS4, NOTE_CS4, NOTE_D4, NOTE_CS4, NOTE_DS4, NOTE_DS4, NOTE_GS3, NOTE_G3, NOTE_CS4, NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4, NOTE_GS4, NOTE_DS4, NOTE_B3, NOTE_AS3, NOTE_A3, NOTE_GS3, 0, 0, 0 }; //Underwolrd tempo int underworld_tempo[] = { 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 3, 12, 12, 12, 12, 12, 12, 6, 6, 18, 18, 18, 6, 6, 6, 6, 6, 6, 18, 18, 18, 18, 18, 18, 10, 10, 10, 10, 10, 10, 3, 3, 3 }; void setup(void) { pinMode(PB0, OUTPUT);//buzzer pinMode(PC13, OUTPUT);//led indicator when singing a note } void loop() { //sing the tunes sing(1); sing(1); sing(2); } int song = 0; void sing(int s) { // iterate over the notes of the melody: song = s; if (song == 2) { Serial.println(" 'Underworld Theme'"); int size = sizeof(underworld_melody) / sizeof(int); for (int thisNote = 0; thisNote < size; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 1000 / underworld_tempo[thisNote]; buzz(melodyPin, underworld_melody[thisNote], noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: buzz(melodyPin, 0, noteDuration); } } else { Serial.println(" 'Mario Theme'"); int size = sizeof(melody) / sizeof(int); for (int thisNote = 0; thisNote < size; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 1000 / tempo[thisNote]; buzz(melodyPin, melody[thisNote], noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: buzz(melodyPin, 0, noteDuration); } } } void buzz(int targetPin, long frequency, long length) { digitalWrite(PC13, HIGH); long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions //// 1 second's worth of microseconds, divided by the frequency, then split in half since //// there are two phases to each cycle long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing //// multiply frequency, which is really cycles per second, by the number of seconds to //// get the total number of cycles to produce for (long i = 0; i < numCycles; i++) { // for the calculated length of time... digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram delayMicroseconds(delayValue); // wait for the calculated delay value digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram delayMicroseconds(delayValue); // wait again or the calculated delay value } digitalWrite(PC13, LOW); }

Rogerclark
Солнце 13 ноября 2016 г., 8:02 вечера
понятия не имею..

Какой код вы пытались скомпилировать...

Наверное, лучше всего опубликовать проблему на GitHub

Mailhouse
Пн 14 ноября 2016 г., 4:16
Rogerclark написал:понятия не имею..

Какой код вы пытались скомпилировать...

Наверное, лучше всего опубликовать проблему на GitHub

Rogerclark
Пн 14 ноября 2016 г., 4:54
@mailhouse

Какое ядро ​​вы используете, если это ядро ​​F1 из репо STM32Duino GitHub, то следует сообщать о ошибках, чтобы WI6LABS могли их исправить.

Эдогальдо
Пн 14 ноября 2016 г. 8:01
Может это помочь: https: // my.ул.com/public/ste2ecommuniti ... Просмотры = 1130

Mailhouse
Вт 15 ноября 2016 г. 12:33
Эдогальдо написал:Может это помочь: https: // my.ул.com/public/ste2ecommuniti ... Просмотры = 1130

Рик Кимбалл
Вт 15 ноября 2016 г. 15:47
Я мог бы создать эту проблему:

https: // github.com/stm32duino/arduino_c ... D7FB0F9L75

Я думаю, что нано.Spec втягивает правильные LIBC/GCC LIBS. Я проверил немного небольшого подмножества функций с плавающей запятой после удаления флага -lm. Он успешно собрался без -LM, поэтому я думал, что нано.Спецификации справились с этим, поэтому я удалил это. Вероятно, нужно добавить «-lm».

Вот код тестирования с плавающей запятой, который я использовал для тестирования, нужен ли мне флаг -lm или нет. void setup() { Serial.begin(115200); } void loop() { while (1) { delay(200); if ( Serial.available() ) { Serial.println(Serial.read()) ; } } }

Рик Кимбалл
Вт 15 ноября 2016 г. 16:19
Так что эта проблема для меня немного озадачена. Без флага -lm на платформе.TXT -файл, как я его использовал. Код, который я разместил в своих предыдущих сообщениях, компилируется и ссылки правильно. Если я посмотрю на файл карты, он показывает функцию SINF, поступающую из Libm.а
$ grep sinf sketch_nov15a.Ино.карта
/tmp/arduino_build_170971/sketch/sketch_nov15a.Ино.CPP.o (sinf)
/home/kimballr/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m/libm.A (lib_a-sf_sin.o) (__kernel_sinf)
.текст.sinf 0x0000000008002da0 0x7c/home/kimballr/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m/libm.A (lib_a-sf_sin.о)
0x0000000008002DA0 SINF
.текст.__kernel_sinf
0x00000000080038fc __kernel_sinf
__kernel_sinf/home/kimballr/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m/libm.A (lib_a-kf_sin.о)
sinf/home/kimballr/.arduino15/packages/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m/libm.A (lib_a-sf_sin.о)
Единственная разница с функцией pow () заключается в том, что она использует переменную __errno, тогда как функции sinf (), atanf () не. Некоторые сообщения в Интернете, похоже, указывают на использование Nano.Флаги спецификации должны исправить это. Я не уверен. Быстрое решение, как вы указали, похоже, добавляет флаг -LM.

-рик

Рик Кимбалл
Вторник 15 ноября 2016 г., 17:11
Больше копания .. Итак, __errno происходит от libg_s.А при использовании нано.спецификации. Я думаю, что это исходный код для фактической функции __errno (), он, по -видимому, настроен на использование вызовов RENTRANT LIBC.

https: // github.com/32bitmicro/newlib-na ... нет/errno.в

Одним из решений является просто предоставление функции __errno (). Если я пойду вперед и создаю функцию __errno () в моем эскизе, я могу успешно скомпилировать и ссылаться без аргумента ссылки -lm.
/* ArduinoIDE 1.6.13 running on Linux Mint 17.3 with Maple Mini Clone Bootloader 2.0 STM32duino version: 19 July 2016 Sketch uses 13,124 bytes (10%) of program storage space. Maximum is 122,880 bytes. Global variables use 2,560 bytes of dynamic memory. */ void setup() { Serial.begin(115200); } void loop() { while (1) { delay(200); Serial.println(Serial.available()); } }

Rogerclark
Вт 15 ноября 2016 г., 19:57
Спасибо, Рик.

Я предполагаю, что у Libmaple нет этой проблемы, поэтому мне интересно, какое решение использует Leaflabs.

Рик Кимбалл
Вт 15 ноября 2016 г., 8:06 вечера
Большинство конфигураций просто добавляют -lm

Rogerclark
Вторник 15 ноября 2016 г. 8:10 вечера
Увеличивает ли это бинарный размер?

Rogerclark
Вт 15 ноября 2016 г., 8:50 вечера
Просто чтобы ответить на мой собственный вопрос, теперь, когда я запустил свой компьютер и т. Д

Добавление -lm в рецепт ссылки добавляет 8 байтов к двоичному размеру.

Я думаю, что мы можем жить с этим ;-)

Rogerclark
Вт 15 ноября 2016 г., 8:55 вечера
Я совершил решение -LM

https: // github.com/stm32duino/arduino_c ... B560D30464

КСТАТИ
Что я не понял, так это то, что GitHub, казалось, автоматически закрыл проблемы, если вы включите номер выпуска, в данном случае № 22 в описание коммита.

Мне лучше быть осторожным с этим в будущем, так как иногда я ссылаюсь на проблемы, но не хочу, чтобы они закрыты

Mailhouse
Ср 16 ноября 2016 г. 12:22
Обновленная платформа.txt [только что загружен с GitHub] разрывает сборку [24841.454331] usb 3-1.1.4: new full-speed USB device number 75 using xhci_hcd [24841.454452] usb 3-1.1.4: Device not responding to setup address. [24841.658566] usb 3-1.1.4: Device not responding to setup address. [24841.862685] usb 3-1.1.4: device not accepting address 75, error -71 [24841.862751] usb 3-1.1-port4: unable to enumerate USB device

Rogerclark
Ср 16 ноября 2016 г. 12:40
Я только что добавил -lm на платформу.TXT, я не вижу, как это вызывает эту конкретную ошибку.

Я только что попытался собрать мигающий набросок с доской, установленной на нуклео, и он сработал для меня

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

Обратите внимание, что если вы установили через диспетчер доски, то вы не будете синхронизироваться с последними изменениями в репо, и вам необходимо удалить версию Manager и сделать ручную установку, используя инструкции здесь

ViewTopic.PHP?f = 16&t = 1553

КСТАТИ.
Обновление версии менеджера плат нетривиальна, и ни у кого нет времени, чтобы сделать это в данный момент.

Mailhouse
Ср. 16 ноября 2016 г. 12:43
Да, я получил это работа, извините. перезапустил Dev Env и сейчас работает хорошо.

Rogerclark
Ср. 16 ноября 2016 г. 1:47
ХОРОШО

IDE не обнаруживает изменений в досках.TXT или платформа.txt, если вы не перезапустите его.