Перейти к содержанию
    

Подключение libc (из состава arm-kgp-eabi) на STM32

Пытаюсь подключить стандартную библиотеку к проекту для STM32. Использую Eclipse + тулчейн от KGP.

 

Насколько я понимаю, линкер должен выдать мне десяток сообщений о том, что не найдены системные вызовы типа sbrk, read, write и т.д., но ничего подобного не происходит все компилится на ура. Однако при попытке вызова printf() проц вываливается в HardFault. Если я правильно понимаю это может происходить из-за проблем с адресацией(?). Т.е., например, указатель указывает на область данных?

 

А куда printf() будет выводить? Наверное, через UART. Но стандартные библиотеки не могут знать особенностей железа в смысле как отправить символ через железо процессора. Как это у Вас решено?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А куда printf() будет выводить? Наверное, через UART. Но стандартные библиотеки не могут знать особенностей железа в смысле как отправить символ через железо процессора. Как это у Вас решено?

А вот для этого как раз и необходима своя реализация системных вызовов (system calls) - sbrk(), write(), read() и т.д. Вообще говоря необходима реализация минимального набора системных вызовов, половина из которых может быть просто заглушками. Если же даже заглушек не будет, то при линковке линкер выдаст ошибки. В системный вызов write() можно запихнуть вызов функции, которая выводит символ через UART, а реализацию этой функции можно разместить в модуле программы, где происходит работа с железом.

 

Пример описанного выше давал AHTOXA здесь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот для этого как раз и необходима своя реализация системных вызовов (system calls) - sbrk(), write(), read() и т.д. Вообще говоря необходима реализация минимального набора системных вызовов, половина из которых может быть просто заглушками. Если же даже заглушек не будет, то при линковке линкер выдаст ошибки. В системный вызов write() можно запихнуть вызов функции, которая выводит символ через UART, а реализацию этой функции можно разместить в модуле программы, где происходит работа с железом.

Пример описанного выше давал AHTOXA здесь

Это все правильно. И Вы сделали соответствующую реализацию? Может быть в ней причина вылета в Hardware Fault?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это все правильно. И Вы сделали соответствующую реализацию? Может быть в ней причина вылета в Hardware Fault?

Реализацию взял из работающего проекта, который выложил АНТОХА. При вызове printf() в моем проекте, проц сразу же вываливается в HardFault, в sbrk() вообще не заходит - пробовал и через дебаггер смотреть и светодиодом моргать без дебаггера. Сейчас пытаюсь вкурить как размотать стек, чтобы точно определить какая команда провоцирует HardFault. Пользуюсь методом, предложенным здесь. Но получаю какую-то ерунду:

 

stacked_r0    0x2000085c    
stacked_r1    0x2000085c    
stacked_r2    0x20000864    
stacked_r3    0x20000864    
stacked_r12    0x2000086c    
stacked_lr    0x2000086c    
stacked_pc    0x20000874    
stacked_psr    0x20000874

Обработчик HardFault'а (взят по ссылке выше):

 

void HardFault_Handler(){
    // start of user stack
    extern unsigned int _susrstack;

    unsigned int stacked_r0;
    unsigned int stacked_r1;
    unsigned int stacked_r2;
    unsigned int stacked_r3;
    unsigned int stacked_r12;
    unsigned int stacked_lr;
    unsigned int stacked_pc;
    unsigned int stacked_psr;
    u32* hardfault_args = (u32*) _susrstack;

    __asm(
    "TST LR, #4 \n"
    "ITE EQ \n"
    "MRSEQ R0, MSP \n"
    "MRSNE R0, PSP \n");

    stacked_r0 = ((unsigned long) hardfault_args[0]);
    stacked_r1 = ((unsigned long) hardfault_args[1]);
    stacked_r2 = ((unsigned long) hardfault_args[2]);
    stacked_r3 = ((unsigned long) hardfault_args[3]);

    stacked_r12 = ((unsigned long) hardfault_args[4]);
    stacked_lr = ((unsigned long) hardfault_args[5]);
    stacked_pc = ((unsigned long) hardfault_args[6]);
    stacked_psr = ((unsigned long) hardfault_args[7]);

    while(1){}
}

Из моих изменений здесь только указатель на стек. Может в этом и косяк?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

У вас есть работающий пример, сравните со своим, найдите отличия. Или возьмите его за основу и добавляйте что надо понемножку. Отладочная выдача там уже работает. А вы уже столько времени воюете с отладчиком.

Ну да ладно, это я так, поворчал просто:)

Насчёт HardFault. Вот тут я постил рабочий пример, может поможет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно не любить калькулятор, но он тем не менее ускоряет работу :) Честно говоря, я первый раз сталкиваюсь с таким глюкаловом при отладке. Хотя может это специфика отладки железок?

 

Спасибо за работающий обработчик HardFault. К сожалению он ясности не добавил, вот что в регистрах:

        r0 = 0x08018238
        r1 = 0x000000FF
        r2 = 0x00000001
        r3 = 0x200008F0
        r12 = 0xFFEFFBFF
        lr = 0x08000829
        pc = 0x0800128C
        psr = 0x21000000

По адресу 0x0800128C вызов printf():

287           printf("New DBGU enabled %d!\n", 0xff);
08001280:   movw r0, #33336; 0x8238
08001284:   movt r0, #2049 ; 0x801
08001288:   mov.w r1, #255 ; 0xff
0800128c:   blx 0x800e050 <printf>

Соответственно по адресу 0x0800e050 printf() и лежит:

          printf:
0800e050:   push {r0, r1, r2, r3}
0800e054:   push {lr}              ; (str lr, [sp, #-4]!)
0800e058:   ldr r3, [pc, #44]      ; 0x800e08c <printf+60>
0800e05c:   sub sp, sp, #12
0800e060:   ldr r0, [r3]
0800e064:   add r12, sp, #20
0800e068:   ldr r1, [r0, #8]
0800e06c:   ldr r2, [sp, #16]
0800e070:   mov r3, r12
0800e074:   str r12, [sp, #4]
0800e078:   bl 0x800e1a4 <_vfprintf_r>
... ... ...

Принципиальных отличий с Вашим примером не смог пока найти... пробовал даже подсовывать в свой проект Ваши sysinit.c и syscalls.c толку ноль. Скрипт линкера тоже такой же. Единственное, что может еще отличаться это Standard Peripheral Library - я качал где-то месяц назад с сайта ST.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно не любить калькулятор, но он тем не менее ускоряет работу :)

Посчитать 2+2 быстрее в уме:)

0800128c:   blx 0x800e050 <printf>

Меня смутило blx. Насколько я понимаю, это вызов с переключением режима. Причём, поскольку операнд имеет сброшенный нулевой бит, то переключение в ARM-моде, которого в кортексах нет. Вот и HardFault... Вы случаем не потеряли ключик -mthumb или что-то типа того?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Меня смутило blx. Насколько я понимаю, это вызов с переключением режима. Причём, поскольку операнд имеет сброшенный нулевой бит, то переключение в ARM-моде, которого в кортексах нет. Вот и HardFault... Вы случаем не потеряли ключик -mthumb или что-то типа того?

Это фейл... Я думал архитектуру только компилятору надо указывать, а оказывается еще и линкеру. Спасибо в очередной раз!

 

PS Всегда всем говорил, что программить надо начинать с ассемблера, а сам до армового ассемблера так и не добрался

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да ерунда всё это. Нормальный процесс начального вхождения. Дальше всё легче пойдёт.

ЗЫ. Ассемблер для АРМ я тоже не знаю, так, читаю со словарём :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...