Error l6218e undefined symbol apbpresctable

Он появляется при использовании библиотеки HAL в Keil. Objects test.axf: Ошибка: L6218E: Неопределенный символ SystemInit (упоминается с самого начала) и т. Д., Русские Блоги, лучший сайт для обмена техническими статьями программиста.

При использовании библиотеки 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:

source that contains *main* function must be added to Source Group category in Keil IDE

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.
Среда — Keil5, контроллер stm32f103. При попытке скомпилить возникает ошибка Error: L6218E: Undefined symbol LCD5110_set_cursor (referred from main.o).
В коде дважды вызывается функция LCD5110_set_cursor(0, 0, &lcd1);
Если закомментировать любой из вызовов, то компилируется без ошибок.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

01.03.2019, 21:27

2

Цитата
Сообщение от domitori
Посмотреть сообщение

В коде дважды вызывается функция 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».
непонятно почему если оставлять один вызов LCD5110_set_cursor(0, 0, &lcd1), то все без ошибок.



0



Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 08:46

4

Цитата
Сообщение от domitori
Посмотреть сообщение

функция описана в lcd5110.h. В main.c подключено с помощью #include «lcd5110.h».

не надо путать кислое с пресным
в lcd5110.h она декларирована т.е говорит компилятору что где то такая функция реализована
а реализована она скорее всего в файле lcd5110.c, этот файл и нужно прикрепить к проекту
как, знаешь?

Цитата
Сообщение от domitori
Посмотреть сообщение

В main.c подключено с помощью #include «lcd5110.h».

это не подключение макрос инклюде просто берет содержимое файла и вставляет в файл main.c
можешь вручную переписать, тот же эффект
тут надо основы языка изучить
наследие ардуины однако это там постоянно звучит «подключим библиотеку xxx #include «xxx.h», не понимая основ
кстати в include кроме таких скобок «» используют и такие <> в чем разница, знаешь?



0



1999 / 1118 / 473

Регистрация: 11.10.2018

Сообщений: 5,707

02.03.2019, 08:59

5

Разница в том, что <> — для системных h-ников. А «» — для самописных h-ников. Правильно?
Вообще #include «lcd5110.h» — это он правильно подключает, только к нему обязательно должен быть соответствующий «lcd5110.cpp»- или «lcd5110.dll»-файлы. Я так считаю.



0



domitori

0 / 0 / 0

Регистрация: 17.11.2015

Сообщений: 8

02.03.2019, 09:04

 [ТС]

6

Цитата
Сообщение от ValeryS
Посмотреть сообщение

не надо путать кислое с пресным
в lcd5110.h она декларирована т.е говорит компилятору что где то такая функция реализована
а реализована она скорее всего в файле lcd5110.c, этот файл и нужно прикрепить к проекту
как, знаешь?

в файле lcd5110.h прописано (сам проект по работе с экраном был взят на просторах интернета):

C
1
2
3
4
inline void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
    LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}

Цитата
Сообщение от ValeryS
Посмотреть сообщение

это не подключение макрос инклюде просто берет содержимое файла и вставляет в файл main.c
можешь вручную переписать, тот же эффект
тут надо основы языка изучить
наследие ардуины однако это там постоянно звучит «подключим библиотеку xxx #include «xxx.h», не понимая основ
кстати в include кроме таких скобок «» используют и такие <> в чем разница, знаешь?

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



0



ValeryS

Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 09:17

7

Цитата
Сообщение от FFPowerMan
Посмотреть сообщение

Разница в том, что <> — для системных h-ников. А «» — для самописных h-ников. Правильно?

не совсем но «действие ведете в правильном направлении»
все дело в поиске файлов. отпуская тонкости <> ищет сначала в папках компилятора и системных а потом в папках проекта, а «» наоборот начинает папок проекта
например такой файл
aaa.h

C
1
#define A 3

разместим в папке компилятора
а такой файл
aaa.h

C
1
#define A 5

разместим в папках проекта

тогда такая программа

C
1
2
#include "aaa.h"
int a=A;

а равно 5
а такая

C
1
2
#include <aaa.h>
int a=A;

а равно 3

зачем это нужно?
один из случаев
нужно изменить стандартный заголовочный файл под себя, портить его есть моветон
копируем его в свою папку и при вызове меняем скобки

Цитата
Сообщение от FFPowerMan
Посмотреть сообщение

только к нему обязательно должен быть соответствующий «lcd5110.cpp»- или «lcd5110.dll»-файлы. Я так считаю.

а так же .S .Lib и еще много чего

Добавлено через 2 минуты

Цитата
Сообщение от domitori
Посмотреть сообщение

LCD5110_wset_cursor

а эта функция откуда?

Цитата
Сообщение от domitori
Посмотреть сообщение

сам проект по работе с экраном был взят на просторах интернета):

покажи где, я посмотрю, может что то упустил(если конечно это не нарушает правил форума, например ссылки на форумы запрещены)



0



domitori

0 / 0 / 0

Регистрация: 17.11.2015

Сообщений: 8

02.03.2019, 09:46

 [ТС]

8

Цитата
Сообщение от ValeryS
Посмотреть сообщение

а эта функция откуда?

покажи где, я посмотрю, может что то упустил(если конечно это не нарушает правил форума, например ссылки на форумы запрещены)

LCD5110_wset_cursor прописана уже в lcd5110.c:

C
1
2
3
4
5
void LCD5110_wset_cursor(int x, int y, LCD5110_canvas_t* win, LCD5110_display* lcd_conf)
{
    win->cursor.x = x;
    win->cursor.y = y;
}

проект скачивал с https://drive.google.com/file/… F0LVE/view



0



Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 10:07

9

Цитата
Сообщение от domitori
Посмотреть сообщение

проект скачивал с

там нет проекта, просто набор файлов
скинь свой проект, попробую разобраться

Цитата
Сообщение от domitori
Посмотреть сообщение

Среда — Keil5

есть у меня

Цитата
Сообщение от domitori
Посмотреть сообщение

контроллер stm32f103

какой именно? дальше идут буковки которые означают размер ОЗУ, ПЗУ, количество ножек,периферии



0



0 / 0 / 0

Регистрация: 17.11.2015

Сообщений: 8

02.03.2019, 10:18

 [ТС]

10

Цитата
Сообщение от ValeryS
Посмотреть сообщение

там нет проекта, просто набор файлов
скинь свой проект, попробую разобраться

есть у меня

какой именно? дальше идут буковки которые означают размер ОЗУ, ПЗУ, количество ножек,периферии

STM32F103C8T6

мой проект по ссылке https://drive.google.com/open?… cMuH0s_Czx

по предыдущей ссылке брал библиотеку для работы с экраном.

Спасибо за помощь!



0



Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 10:38

11

domitori, перезалей проект сюда
правила п 4.11

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



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 как решение

Решение

судя по

Цитата
Сообщение от domitori
Посмотреть сообщение

inline void LCD5110_set_cursor

библиотека для плюсов, в чем можно убедится компилируя проект с ключом (—CPP)
правда там выскакивает ошибка в

..Srclcd5110.c(206): error: #20: identifier «log2» is undefined

чтото не нравится в файле match.h из за условной компиляции

Добавлено через 7 минут
самый простой выход, но не самый правильный, вырезать
функцию из lcd5110.h
и вставить в майн удалить inline

C
1
2
3
4
void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
    LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}



0



domitori

0 / 0 / 0

Регистрация: 17.11.2015

Сообщений: 8

02.03.2019, 11:23

 [ТС]

14

Цитата
Сообщение от ValeryS
Посмотреть сообщение

самый простой выход, но не самый правильный, вырезать
функцию из lcd5110.h
и вставить в майн удалить inline

C
1
2
3
4
void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
    LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}

Да, так работает. Пусть пока будет так
Огромное спасибо за помощь!!!



0



ValeryS

Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 11:30

15

Цитата
Сообщение от domitori
Посмотреть сообщение

Огромное спасибо за помощь!!!

это не помощь это костыль может выстрелить в любой момент
будет время поковыряюсь поглубже

Добавлено через 2 минуты
еще один вариант вставить static перед функцией

C
1
2
3
4
5
static inline 
    void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
    LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}

Добавлено через 41 секунду
ясно одно
нужно править библиотеку, подгоняя её под стандарт С



0



78 / 77 / 4

Регистрация: 20.11.2016

Сообщений: 233

02.03.2019, 13:16

16

ValerySinline для чего прописывается?



0



Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 13:45

17

Цитата
Сообщение от Radikal_78
Посмотреть сообщение

inline для чего прописывается?

ну это долгий вопрос
inline была введена в C++ вместо #define
грубо говоря, в месте вызова функции компилятор не вызывает функцию, а подставляет код функции
из этого в Си следует куча ограничений
вот я здесь задал вопрос inline в Си
будем посмотреть



1



domitori

0 / 0 / 0

Регистрация: 17.11.2015

Сообщений: 8

02.03.2019, 14:17

 [ТС]

18

в lcd5110.c прописал саму функцию:

C
1
2
3
4
void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
    LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}

а в lcd5110.h :

C
1
void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf);

ошибок не выдает



0



ValeryS

Модератор

Эксперт по электронике

8759 / 6549 / 887

Регистрация: 14.02.2011

Сообщений: 22,972

02.03.2019, 14:29

19

Цитата
Сообщение от domitori
Посмотреть сообщение

ошибок не выдает

так разумеется
но это придется перелопатить всю библиотеку, да и скорость выполнения ниже
достаточно было приписать static перед inline

Цитата
Сообщение от ValeryS
Посмотреть сообщение

еще один вариант вставить static перед функцией

C
1
2
3
4
5
static inline 
 void LCD5110_set_cursor(int x, int y, LCD5110_display* lcd_conf)
{
LCD5110_wset_cursor(x, y, &lcd_conf->def_scr, lcd_conf);
}

все дело в связывании, в котором я не силен, поэтому и задал вопрос в специализированной ветке
inline в Си
там кстати один из вариантов предложил prik

Цитата
Сообщение от prik
Посмотреть сообщение

еще вариант добавить в .h декларацию

C
1
int inline_foo(int a, int b);



0



Эксперт CАвтор FAQ

21264 / 8280 / 637

Регистрация: 30.03.2009

Сообщений: 22,635

Записей в блоге: 30

02.03.2019, 15:15

20

Цитата
Сообщение от ValeryS
Посмотреть сообщение

вот я здесь задал вопрос inline в Си

Для полноты картины:

Как inline трактуется в C99 описано здесь: inline в Си. Там ссылка, где в том числе описана трактовка в GNU C — по смыслу похоже на C99, но немного отличается по синтаксису

Как inline трактуется в C++ описано здесь: https://www.cyberforum.ru/blogs/18334/blog93.html

Добавлено через 3 минуты
Собственно, различная трактовка inline в разных языках программирования и привела к изначальной проблеме, обсуждаемой в данной теме



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» {
#endif

extern 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);

Удачной компиляции без ошибок!

Понравилась статья? Поделить с друзьями:
  • Error l6031u could not open scatter description file
  • Error l121 improper fixup
  • Error l107 address space overflow
  • Error l104 multiple public definitions
  • Error kubridge skprx is not installed