Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ошибка в stm32f4xx_conf.h с assert_param
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Tapochka
Решил разобраться с таймерами в stm32. В итоге прога компилится, однако линкер в Keil выдает timer.axf: Error: L6218E: Undefined symbol assert_param (reffered from stm32f4xx_gpio.o). ну естественно разобрался откуда берется эта assert_param - из stm32f4xx_conf.h(код приведен ниже):

CODE
***************************************************************************
***
* @file USART/HyperTerminal_Interrupt/stm32f4xx_conf.h
* @author MCD Application Team
* @version V1.0.1
* @date 13-April-2012
* @brief Library configuration file.
***************************************************************************
***
* @attention
*
* <h2><center>&copy; COPYRIGHT 2012 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
***************************************************************************
***
*/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_CONF_H
#define __STM32F4xx_CONF_H


#if defined (HSE_VALUE)
/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */
#undef HSE_VALUE
#define HSE_VALUE ((uint32_t)8000000)
#endif /* HSE_VALUE */

/* Includes ------------------------------------------------------------------*/
/* Uncomment the line below to enable peripheral header file inclusion */
/*#include "stm32f4xx_adc.h"
#include "stm32f4xx_can.h"
#include "stm32f4xx_crc.h"
#include "stm32f4xx_cryp.h"
#include "stm32f4xx_dac.h"
#include "stm32f4xx_dbgmcu.h"
#include "stm32f4xx_dcmi.h"
#include "stm32f4xx_dma.h"
#include "stm32f4xx_exti.h"
#include "stm32f4xx_flash.h"
#include "stm32f4xx_fsmc.h"
#include "stm32f4xx_hash.h" */
#include "stm32f4xx_gpio.h"
/* #include "stm32f4xx_i2c.h"
#include "stm32f4xx_iwdg.h"
#include "stm32f4xx_pwr.h" */
#include "stm32f4xx_rcc.h"
/* #include "stm32f4xx_rng.h"
#include "stm32f4xx_rtc.h"
#include "stm32f4xx_sdio.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_syscfg.h"*/
#include "stm32f4xx_tim.h"
/*#include "stm32f4xx_usart.h"
#include "stm32f4xx_wwdg.h"
#include "misc.h" *//* High level functions for NVIC and SysTick (add-on to CMSIS functions) */

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/

/* If an external clock source is used, then the value of the following define
should be set to the value of the external clock source, else, if no external
clock is used, keep this define commented */
/*#define I2S_EXTERNAL_CLOCK_VAL 12288000 */ /* Value of the external clock in Hz */


/* Uncomment the line below to expanse the "assert_param" macro in the
Standard Peripheral Library drivers code */
/* #define USE_FULL_ASSERT 1 */

/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT

/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr: If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /*USE_FULL_ASSERT */

#endif /*__STM32F4xx_CONF_H */

/************************ © COPYRIGHT STMicroelectronics *****END OF FILE****/


Сказано, что нужно раскомментить #define USE_FULL_ASSERT - я раскомментил, так же раскомментил необходимые файлы сверху, однако проблема не решается, выдает все тоже самое. Помогите, у кого было подобное
bseyur
assert_param - runtime-тест значений параметров вызываемых функций. Предполагается, что в случае обнаружения недопустимого значения, в консоль выводится сообщение об ошибке. Вам это действительно нужно?
Tapochka
По идее наверно нет, но ошибка то возникает с ним связана. В таком случае хотелось бы узнать как ее миновать не связываясь с assert_param
bseyur
Так закомментируйте обратно #define USE_FULL_ASSERT - вместо assert_param будет стоять заглушка.
А ошибка, скорее всего, из-за того, что в stm32f4xx_gpio.с не подключен нужный заголовочный файл.
Tapochka
А как в таком случае подключить нужный заголовочный файл в stm32f4xx_gpio.c ? ничего такого там не нашел
bseyur
В stm32f4xx_gpio.c должно быть, как минимум, #include stm32f4xx_conf.h, т.к. в последнем дано определение assert_param
Tapochka
СПАСИБО ОГРОМНОЕ beer.gif
ошибок больше нет. следуя вашему совету прописал в stm32f4xx_gpio.c, stm32f4xx_rcc.c, stm32f4xx_tim.c, stm32f4xx_exti.c в инклудах этот stm32f4xx_conf.h( хотя они были защищены от записи, так что пришлось создать новые файлы с тем же содержанием и с другим названием), и все нормально.
Porolon
столкнулся с такой же проблемой на STM32F103 При использовании драйверов. Необходимо в настройках проекта определить Define : USE_STDPERIPH_DRIVER
aBoomest
Та же проблема на STM32F429. Инфа в инете есть. Проблема решена, но нихрена (простите) не понятна, ни с т.з. физики происходящего, ни с т.з. организации программы. Хотелось бы сообща разобраться.
Конкретика:
Цитата(bseyur @ Jul 2 2013, 15:06) *
В stm32f4xx_gpio.c должно быть, как минимум, #include stm32f4xx_conf.h, т.к. в последнем дано определение assert_param
Цитата(bseyur @ Jul 2 2013, 13:50) *
Так закомментируйте обратно #define USE_FULL_ASSERT - вместо assert_param будет стоять заглушка.
А ошибка, скорее всего, из-за того, что в stm32f4xx_gpio.с не подключен нужный заголовочный файл.
Мне, например, совершенно не ясно а почему же он там не подключен сразу? Т.е. каждому пользователю библиотек (вероятно 99% пользователей) при создании проекта необходимо редактировать библиотеки от производителя МК. Т.е. во всех файлах библиотеки (_gpio.c, _rcc.c, . . . etc) необходимо вручную прописывать либо #include stm32f4xx_conf.h, либо добавить строчку #define assert_param(expr) ((void)0). И это во ВСЕХ ФАЙЛАХ, поставляемых производителем, где есть эта функция.
Более того в stm32f4xx_conf.h имеют место уже свои инклуды. И их не мало. И след-но надо, либо все это протащить в проект (даже если оно вам не нужно), либо опять же, снова, еще раз уже в других местах редактировать файл библиотеки и как-то это обходить. Не исключено, что по цепочке еще что-то вылезет, не проверял.
Логически вытекающий вопрос:
Совершенно не понятен такой подход: обязательная необходимость для создание проекта редактировать библиотеки от производителей. Это уже в этом случае перестает быть похожим на библиотеку, если оно требует обязательных изменений. Так это такой подход, или я чего-то не понимаю?

PS: Вообще, первый раз в жизни с подобным сталкиваюсь. И ведь это не глюк, это типа нормально. Я понимаю (несколько раз сталкивался), когда имеет место глюк, и приходится библиотеку производителя корректировать и вкомпиливать себе уже что-то свое - переделанное. Но в данном же случае получается, что это надо делать всегда, для каждого проекта. В моем понимании, библиотека (тем более написанная не энтузиастами, а самими производителями, это то, что подключается к проекту и используется, но никак не редактируется)
Arlleex
Цитата(aBoomest @ Aug 17 2018, 00:20) *
Та же проблема на STM32F429...

Какая такая проблема-то? У меня прекрасно все собирается в тех проектах, где использую SPL для настройки периферии, а самое главное, без редактирования файлов библиотек...
Давайте по порядку. Я свой проект открыл на STM32F429 и из него писать буду. Среда Keil, раз уж за нее говорим.
1. Настраиваем пути проекта в опциях


2. Любой заголовочный файл из библиотеки SPL подключает "stm32f4xx.h". В этом Вы можете убедиться лично.

3. Лезем в "stm32f4xx.h" и вверху видим
Код
#if !defined (STM32F40_41xxx) && !defined (STM32F427_437xx) && !defined (STM32F429_439xx) && !defined (STM32F401xx)
  /* #define STM32F40_41xxx */   /*!< STM32F405RG, STM32F405VG, STM32F405ZG, STM32F415RG, STM32F415VG, STM32F415ZG,  
                                     STM32F407VG, STM32F407VE, STM32F407ZG, STM32F407ZE, STM32F407IG, STM32F407IE,
                                     STM32F417VG, STM32F417VE, STM32F417ZG, STM32F417ZE, STM32F417IG and STM32F417IE Devices */

/*#define STM32F427_437xx   !< STM32F427VG, STM32F427VI, STM32F427ZG, STM32F427ZI, STM32F427IG, STM32F427II,  
                                       STM32F437VG, STM32F437VI, STM32F437ZG, STM32F437ZI, STM32F437IG, STM32F437II Devices */
                                    
   #define STM32F429_439xx   /* !< STM32F429VG, STM32F429VI, STM32F429ZG, STM32F429ZI, STM32F429BG, STM32F429BI,  
                                       STM32F429NG, STM32F439NI, STM32F429IG, STM32F429II, STM32F439VG, STM32F439VI,
                                       STM32F439ZG, STM32F439ZI, STM32F439BG, STM32F439BI, STM32F439NG, STM32F439NI,
                                       STM32F439IG and STM32F439II Devices */
                                    
  /* #define STM32F401xx */     /*!< STM32F401CB, STM32F401CC,  STM32F401RB, STM32F401RC, STM32F401VB, STM32F401VC  
                                     STM32F401CD, STM32F401RD, STM32F401VD, STM32F401CExx, STM32F401RE, STM32F401VE Devices */  
  
#endif

Тут просто разблокируем макроопределение на нужный микроконтроллер.

Дальше в том же файле "stm32f4xx.h" есть строки
Код
#if !defined  (USE_STDPERIPH_DRIVER)
/**
* @brief Comment the line below if you will not use the peripherals drivers.
   In this case, these drivers will not be included and the application code will
   be based on direct access to peripherals registers
   */
  #define USE_STDPERIPH_DRIVER
#endif /* USE_STDPERIPH_DRIVER */

От этих строк зависит, будет ли подключаться файл "stm32f4xx_conf.h" (внизу файла "stm32f4xx.h")
Код
#ifdef USE_STDPERIPH_DRIVER
  #include "stm32f4xx_conf.h"
#endif /* USE_STDPERIPH_DRIVER */

4. В "stm32f4xx_conf.h" у меня
Цитата
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif

Я особо не трогал его даже.

5. Собираем проект и радуемся, что он прекрасно собирается.

Да. Можно проще. Можно обойтись без кучи связок заголовочных файлов, для этого нужно подумать головой и выкинуть лишнее, перенеся нужное в свои файлы. Либо вовсе избавиться от SPL, что иногда разумнее.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.