Фон
Я пытаюсь реализовать переход между приложениями на микроконтроллере STM32F1. Я использую qemu (предоставленный GNU MCU Eclipse) для эмуляции платы Olimex-H103, в которой используется микроконтроллер STM32F103RBT6. Я использую «голубую таблетку», которую я купил на Ebay, чтобы проверить ее на реальном оборудовании. Синяя таблетка оснащена микроконтроллером STM32F103C8T6. Два микроконтроллера очень похожи и даже используют таблицы из некоторых источников.
STM32F103RBT6 Заголовок Olimex
STM32F103C8T6 BluePill
Мои приложения - это одно основное приложение, которое загружает второе в память, а затем переходит к нему. Основное приложение компилируется и связывается как проект STM32F1 по умолчанию с помощью GNU MCU Eclipse, а второе - это программа на C, скомпилированная и связанная с помощью скрипта связывания (просто указывающего области памяти и размеры), поэтому выравнивание для таблицы векторов отсутствует. Второе приложение связано с основным приложением в виде массива char, который копируется в память. Основное приложение также имеет таблицу поиска для приложений, которые должны быть доступны для дополнительного приложения.
void hello_world();
unsigned int lookup_table[] = {
(unsigned int)&hello_world
};
После того, как вторичное приложение помещено в память (и проверено, что оно правильно скопировано), основное приложение переходит к нему и передает ссылку на свою справочную таблицу:
typedef int(*AppFunc)(unsigned int);
// Application is compiled with -mthumb, hence the +1 to the address
AppFunc appFunc = (AppFunc)(((uint32_t)0x20003000) + 1);
appFunc((unsigned int)&lookup_table);
Вторичное приложение должно иметь возможность вызывать функции из ссылок в таблице поиска.
void start(unsigned int *lookup_table)
{
typedef void(*void_f)();
static void_f hello_func = (void_f)*(lookup_table);
hello_func();
}
Когда приложение закончено, выполнение должно вернуться к основному приложению (так как адрес возврата находится в стеке?).
Для пояснения: Я (в настоящее время) не изменяю таблицу векторов или указатель стека, поскольку я хотел бы, чтобы они были согласованными (если это возможно).
Проблема
Все это прекрасно работает с qemu, но не с реальным оборудованием. В qemu он переходит ко второму приложению, выполняет функции в главном приложении, а после завершения возвращается к основному приложению. Однако на реальном оборудовании он останавливается после перехода, если start () вызывает методы из таблицы поиска, в противном случае он работает нормально (пустой start ()), но я хочу иметь возможность вернуться назад в основное приложение и выполнять там функции.
Это ошибка в qemu, которая заставляет его работать? Это аппаратная проблема или код? Я не совсем понимаю, в чем проблема, поскольку qemu безупречно запускает приложения.
Заранее спасибо!