При использовании библиотеки HAL в Keil возникают такие проблемы, как. Objects test.axf: Ошибка: L6218E: Неопределенный символ SystemInit (ссылка из startup_stm32f107xc.o).
В предыдущей статье я говорил об использовании библиотеки HAL stm32f107. На практике возникали следующие проблемы:
.Objectstest.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f107xc.o).
.Objectstest.axf: Error: L6218E: Undefined symbol __UNALIGNED_UINT32_WRITE (referred from stm32f1xx_ll_usb.o).
.Objectstest.axf: Error: L6218E: Undefined symbol __UNALIGNED_UINT32_READ (referred from stm32f1xx_ll_usb.o).
.Objectstest.axf: Error: L6218E: Undefined symbol SystemCoreClock (referred from stm32f1xx_hal.o).
.Objectstest.axf: Error: L6218E: Undefined symbol AHBPrescTable (referred from stm32f1xx_hal_rcc.o).
.Objectstest.axf: Error: L6218E: Undefined symbol APBPrescTable (referred from stm32f1xx_hal_rcc.o).
.Objectstest.axf: Error: L6218E: Undefined symbol __UNALIGNED_UINT32_READ (referred from stm32f1xx_ll_usb.o).
причина
Проблема в том, что что-то не определено, даже если я пойду определять
void SystemInit()
{
}
Есть еще некоторые проблемы, но позже выяснилось, что файл заголовка stm32f107xc.h не был добавлен.
Решение
Каталог: (каталог под STM32Cube_FW_F1_V1.8.0, который вы скачали на официальном сайте) STM32Cube_FW_F1_V1.8.0 Drivers CMSIS Device ST STM32F1xx Include
Скопируйте в файл проекта в KEIL files Hal_test STM32F1xx_HAL_Driver
Что касается следующих двух решений ошибок, добавьте определения в файл c
.Objectstest.axf: Error: L6218E: Undefined symbol __UNALIGNED_UINT32_WRITE (referred from stm32f1xx_ll_usb.o).
.Objectstest.axf: Error: L6218E: Undefined symbol __UNALIGNED_UINT32_READ (referred from stm32f1xx_ll_usb.o).
void __UNALIGNED_UINT32_READ(){}
void __UNALIGNED_UINT32_WRITE(){}
Примечание. Если вы столкнулись с такой проблемой: «Сначала выберите целевое устройство STM32F1xx, используемое в вашем приложении (в файле stm32f1xx.h)»
Решение: просто раскомментируйте mcu, которое вы используете, в файле stm32f1xx.h. Я использовал STM32F107VC, поэтому измените его, как показано на рисунке.
Это напрямую используется проектом f107, который я тестировал.link
Эта тема
- Везде
-
- Эта тема
- Этот форум
-
- Расширенный поиск
Поиск
I am trying to run a simple tutorial (external interrupt example) on my NUCLEO-F746ZG board. I use STM32CubeMx software version 5.2.0 and Keil software version 5.28.0.0 as compiler. I get the following error:
EXTI_callbackEXTI_callback.axf: Error: L6218E: Undefined symbol ex0 (referred from stm32f7xx_it.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 1 error messages.
Target not created.
where ex0 is a variable that is defined in main.c as
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
char ext0;
/* USER CODE END PV */
and it is used as the external variable inside the stm32f7xx_it.c as follows :
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
extern char ex0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
if ( GPIO_Pin == GPIO_PIN_13 ) {
ex0 = 1;
}
}
/* USER CODE END EV */
by using the HAL_GPIO_EXTI_Callback function I want to assign the value of 1 to the ex0 variable, whenever the blue push button (GPIO_PIN_13) is pressed on the NUCLEO-F746ZG board.
It seems the code can not find the reference to ex0 variable, while it is defined in the main.c file. I don’t understand what is cause of this problem. Should I add some .h / .c files to the my project? In addition, many users have also complained about the «Error: L6218E: Undefined symbol VAR_NAME» when they have tried to compile their code with Keil Software. I have read some of them, but I didn’t find the main reason behind this error. I appreciate those of you who can share their experience on how to solve this error.
I found the solution is easy, but before going deeper into the solution, keep in mind that C compilation unit (C Compiler and Assembler at least) compiles each pure C source file after resolving necessary pre-processor directives, and generates a relocatable object file as a result of compilation.
After the compilation unit does its job, there is another unit that is responsible for combining individually every source file that is compiled successfully into the relocatable form of one big object file for all. This unit is called Linker and the operation is called Linking
A very important feature in relocatable object file is that what is called variable, function will be noted as symbol so far. The linker has to solve the symbols, defining what is originally defined in an object file, reference what is being used in another to their original object file.
After this motivation, now we can call main() function as main() symbol.
I Found that the problem is because the source file that contains the main() function was not compiled. As a result, there is no a relocatable object file that contains the symbol corresponding to main() function. Hence, the compiler is complaining: you asked me to use (reference) a symbol you guaranteed to be found (defined) in another file but I found no such symbol!
The solution:
For Kiel IDE, to queue a source file for a compilation; you gotta shortlist it in the category «Source Group»,by clicking right, either adding new files to group, or existing files to group. It will result in something like the following figure:
Now we have a main function, is turned (defined) to main symbol later, and found by the linker to reference it to whatever use it in any other relocatable object files.
0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
|
1 |
|
01.03.2019, 17:21. Показов 12491. Ответов 19
Не знаю в какую сторону уже копать. Не так давно начал разбираться с STM32.
__________________
0 |
Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
|
01.03.2019, 21:27 |
2 |
В коде дважды вызывается функция LCD5110_set_cursor(0, 0, &lcd1); а где эта функция описана?
0 |
0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
|
02.03.2019, 08:25 [ТС] |
3 |
функция описана в lcd5110.h. В main.c подключено с помощью #include «lcd5110.h».
0 |
Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
|
02.03.2019, 08:46 |
4 |
функция описана в lcd5110.h. В main.c подключено с помощью #include «lcd5110.h». не надо путать кислое с пресным
В main.c подключено с помощью #include «lcd5110.h». это не подключение макрос инклюде просто берет содержимое файла и вставляет в файл main.c
0 |
1999 / 1118 / 473 Регистрация: 11.10.2018 Сообщений: 5,707 |
|
02.03.2019, 08:59 |
5 |
Разница в том, что <> — для системных h-ников. А «» — для самописных h-ников. Правильно?
0 |
domitori 0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
||||
02.03.2019, 09:04 [ТС] |
6 |
|||
не надо путать кислое с пресным в файле lcd5110.h прописано (сам проект по работе с экраном был взят на просторах интернета):
это не подключение макрос инклюде просто берет содержимое файла и вставляет в файл main.c с ардуиной никогда не работал. а основы видимо придется подтянуть
0 |
ValeryS Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
||||||||||||||||
02.03.2019, 09:17 |
7 |
|||||||||||||||
Разница в том, что <> — для системных h-ников. А «» — для самописных h-ников. Правильно? не совсем но «действие ведете в правильном направлении»
разместим в папке компилятора
разместим в папках проекта тогда такая программа
а равно 5
а равно 3 зачем это нужно?
только к нему обязательно должен быть соответствующий «lcd5110.cpp»- или «lcd5110.dll»-файлы. Я так считаю. а так же .S .Lib и еще много чего Добавлено через 2 минуты
LCD5110_wset_cursor а эта функция откуда?
сам проект по работе с экраном был взят на просторах интернета): покажи где, я посмотрю, может что то упустил(если конечно это не нарушает правил форума, например ссылки на форумы запрещены)
0 |
domitori 0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
||||
02.03.2019, 09:46 [ТС] |
8 |
|||
а эта функция откуда? покажи где, я посмотрю, может что то упустил(если конечно это не нарушает правил форума, например ссылки на форумы запрещены) LCD5110_wset_cursor прописана уже в lcd5110.c:
проект скачивал с https://drive.google.com/file/… F0LVE/view
0 |
Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
|
02.03.2019, 10:07 |
9 |
проект скачивал с там нет проекта, просто набор файлов
Среда — Keil5 есть у меня
контроллер stm32f103 какой именно? дальше идут буковки которые означают размер ОЗУ, ПЗУ, количество ножек,периферии
0 |
0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
|
02.03.2019, 10:18 [ТС] |
10 |
там нет проекта, просто набор файлов есть у меня какой именно? дальше идут буковки которые означают размер ОЗУ, ПЗУ, количество ножек,периферии STM32F103C8T6 мой проект по ссылке https://drive.google.com/open?… cMuH0s_Czx по предыдущей ссылке брал библиотеку для работы с экраном. Спасибо за помощь!
0 |
Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
|
02.03.2019, 10:38 |
11 |
domitori, перезалей проект сюда Картинки и любые другие файлы загружайте на форум, во избежание их удаления или потери на сторонних ресурсах. По этой же причине коды программ также должны находиться на форуме.
0 |
0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
|
02.03.2019, 10:50 [ТС] |
12 |
загрузил.
0 |
ValeryS Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
||||
02.03.2019, 11:08 |
13 |
|||
Сообщение было отмечено domitori как решение Решениесудя по
inline void LCD5110_set_cursor библиотека для плюсов, в чем можно убедится компилируя проект с ключом (—CPP) ..Srclcd5110.c(206): error: #20: identifier «log2» is undefined чтото не нравится в файле match.h из за условной компиляции Добавлено через 7 минут
0 |
domitori 0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
||||
02.03.2019, 11:23 [ТС] |
14 |
|||
самый простой выход, но не самый правильный, вырезать
Да, так работает. Пусть пока будет так
0 |
ValeryS Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
||||
02.03.2019, 11:30 |
15 |
|||
Огромное спасибо за помощь!!! это не помощь это костыль может выстрелить в любой момент Добавлено через 2 минуты
Добавлено через 41 секунду
0 |
78 / 77 / 4 Регистрация: 20.11.2016 Сообщений: 233 |
|
02.03.2019, 13:16 |
16 |
ValeryS,а inline для чего прописывается?
0 |
Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
|
02.03.2019, 13:45 |
17 |
inline для чего прописывается? ну это долгий вопрос
1 |
domitori 0 / 0 / 0 Регистрация: 17.11.2015 Сообщений: 8 |
||||||||
02.03.2019, 14:17 [ТС] |
18 |
|||||||
в lcd5110.c прописал саму функцию:
а в lcd5110.h :
ошибок не выдает
0 |
ValeryS Модератор 8759 / 6549 / 887 Регистрация: 14.02.2011 Сообщений: 22,972 |
||||||||
02.03.2019, 14:29 |
19 |
|||||||
ошибок не выдает так разумеется
еще один вариант вставить static перед функцией
все дело в связывании, в котором я не силен, поэтому и задал вопрос в специализированной ветке
еще вариант добавить в .h декларацию
0 |
21264 / 8280 / 637 Регистрация: 30.03.2009 Сообщений: 22,635 Записей в блоге: 30 |
|
02.03.2019, 15:15 |
20 |
вот я здесь задал вопрос inline в Си Для полноты картины: Как inline трактуется в C99 описано здесь: inline в Си. Там ссылка, где в том числе описана трактовка в GNU C — по смыслу похоже на C99, но немного отличается по синтаксису Как inline трактуется в C++ описано здесь: https://www.cyberforum.ru/blogs/18334/blog93.html Добавлено через 3 минуты
1 |
При создании проекта с использованием C++, часто подключаются разные файлы .c или .cpp.
KEIL между разными файлами может не видеть внешние функции и сообщаться об этом ошибкой: Error: L6218E: Undefined symbol xxxxxxxxxxxxxxxxxxxx (referred from main.o).
Это связано с тем что линковщик ругается на компоновку. Не видит из других модулей.
Ключевое слово extern
объявляет переменную или функцию и указывает, что она имеет внешние компоновки (ее имя будет видимым не только в пределах файла, в котором она определена, но и в других файлах). Когда выполняется изменение переменной, ключевое слово extern
обозначает, что переменная имеет статическую длительность (она выделяется в начале программы и высвобождается при завершении). Переменная или функция может быть определена в другом исходном файле или позднее в том же самом файле. Объявления переменных и функций в области видимости файла являются внешними по умолчанию.
Если в C++ ключевое слово extern
используется со строковым объектом, это означает, что для деклараторов используются соглашения о компоновках другого языка. К функциям и данным C можно обращаться, только если ранее они были объявлены как имеющие компоновки C. Однако они должны быть определены в блоке трансляции, который компилируется отдельно.
Чтобы вызвать функцию C из C++, используйте следующую нотацию преобразования типов:
extern "C" void my_func (void);
Это сообщает компоновщику, что для функции my_func требуется компоновка для модуля на языке С++ с соглашением языка С.
Есть два пути решения:
1. В модуле обьявить стиль C для всех внешних ссылок.
В файле MyFile.h нужно добавить:
#include «cmsis_os2.h»
#include «stm32f10x.h»#ifdef __cplusplus
extern «C» {
#endifextern uint16_t BUF;
extern void TFT_START(void);#define TFT_RST_LOW GPIOB->BRR = (1<<7) //CS = L
#define TFT_RST_HIGH GPIOB->BSRR = (1<<7) //CS = H#ifdef __cplusplus
}
#endif
Это позволит компилировать в зависимости от настроек компилятора.
2. Это самостоятельно указывать соглашение для каждой внешней ссылки.
К пример есть два модуля main.cpp и display.c
В модулей main.cpp есть реализация функции Delay, чтобы модуль display.c ее увидел нужно обьявить ее прототип как внешняя в модуле main.h.
extern void Delay (uint32_t Count);
Компоновщик не увидит ее из-за разницы соглашений, для этого добавляем соглашение.
extern «C» void Delay (uint32_t Count);
После этого компоновщик будет видеть ее и функция станет доступна другим модулям которые используют ее.
В случае, если модули используются одинаковые, тогда достаточно одного обьявления прототипа в модуле display.c
extern void Delay (uint32_t Count);
Удачной компиляции без ошибок!