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

Keil и Cortex M4

Доброго времени суток.

 

Сам я Keil не использую, но была необходимость сделать проект именно на этом компиляторе. Проект собран под два проца - первый STM32F107 (Cortex M3) второй под STM32L475 (Cortex M4). Проект связан с передачей данных по USB с использованием встроенного в МК USB OTG модуля, по этому в проекте есть объявленные в виде структур данные всевозможных USB дескрипторов. Так вот, при работе программы под М3 глюков не наблюдалось и он был перенесен на М4. Тут начались глюки. Пр передаче первой же послыки (т.е. еще на этапе нумерации) по USB проц падает в HardFault. Копание показало, что Keil, при использованиии первого МК (М3) размещает все данные по выровненным на 32-бит адресам. При компилировании проекта под М4 он размещает данные с выравниванием в 16-бит... Как так то? или я чего то не понимаю/не знаю?

 

В IAR проект под М3 проверял, под М4 с целевым процом (STM32L475) нет, но адреса расположены с правильным выравниванием. С другим МК - STM32F407 проект работает нормально.

 

Четогдето в Keil подкрутить нужно? Или мне? :cranky:

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


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

Без примера некорректного размещения дать какой-либо комментарий затруднительно.

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


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

Во вложении файлы, в которых размещены дескрипторы. Ничего особенного - объявлены структуры дескрипторов устройств.

Вот функция, которая записывает данные в FIFO IN OTG

/*******************************************************************************
Put data to EP IN FIFO over SW cycle
*******************************************************************************/
static void FIFO_IN_Put(UINT32 volatile *in_fifo, UINT32 const *p_src, INT src_len)
{
    INT w_count = (src_len + 3) >> 2;
    while(w_count--)
        *in_fifo = *p_src++;
}

Программа падает в хардфолт в ней сразу после обращения к данным в указателе p_src сразу же при первом вызове функции. При этом в p_src находится адрес дескриптора устройства. См. картинку.

111.jpg

 

Ниже вырезка из MAP-фала для STM32F107. Видно, что все данные, которым положено быть выровненными - выровнены:

g_PUSBD_DeviceDescriptor                 0x08002928   Data          18  usbd_desc_device.o(.constdata)
    g_PUSBD_LanguageStringDescriptor         0x0800293c   Data           4  usbd_desc_device.o(.constdata)
    g_PUSBD_VendorStringDescriptor           0x08002940   Data          18  usbd_desc_device.o(.constdata)
    g_PUSBD_ProductStringDescriptor          0x08002954   Data          44  usbd_desc_device.o(.constdata)
    g_PUSBD_SerialStringDescriptor           0x08002980   Data          34  usbd_desc_device.o(.constdata)
    g_PUSBD_HID_Report                       0x080029a2   Data          25  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_HID_ReportLen                    0x080029bb   Data           1  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_ConfigDescriptor                 0x080029bc   Data          64  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_MSD_MediaInquiryData             0x080029fc   Data          44  usbd_desc_msd_hid.o(.constdata)

 

 

А это для STM32L475

g_PUSBD_DeviceDescriptor                 0x08002348   Data          18  usbd_desc_device.o(.constdata)
    g_PUSBD_LanguageStringDescriptor         0x0800235a   Data           4  usbd_desc_device.o(.constdata)
    g_PUSBD_VendorStringDescriptor           0x0800235e   Data          18  usbd_desc_device.o(.constdata)
    g_PUSBD_ProductStringDescriptor          0x08002370   Data          44  usbd_desc_device.o(.constdata)
    g_PUSBD_SerialStringDescriptor           0x0800239c   Data          34  usbd_desc_device.o(.constdata)
    g_PUSBD_HID_Report                       0x080023be   Data          25  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_HID_ReportLen                    0x080023d7   Data           1  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_ConfigDescriptor                 0x080023d8   Data          64  usbd_desc_msd_hid.o(.constdata)
    g_PUSBD_MSD_MediaInquiryData             0x08002418   Data          44  usbd_desc_msd_hid.o(.constdata)

DESCS.ZIP

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


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

В файлах нет типов, но на каком основании, например, должен быть выровнен FARCONST UINT8 g_PUSBD_HID_Report[]?

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


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

В файлах нет типов, но на каком основании, например, должен быть выровнен FARCONST UINT8 g_PUSBD_HID_Report[]?
Я считаю что компилятор должен выровнять адрес массива на том основании, что размер массива больше 3 байт.

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


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

Остается убедить в этом компилятор :) Нет, не должен, и AAPCS такого не требует.

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


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

Остается убедить в этом компилятор :) Нет, не должен, и AAPCS такого не требует.
С 8-битным массивом понятно - не должен. Но как быть со структурами данных? Неужели там тоже этого не требуется?

 

 

В принципе, я нашел как договорится с компилятором с помощью __attribute__(align(4)). Блин, но я тогда гвоздями прибью этот код к конкретному компилятору

 

И, опять же не понятно, почему для М3 компилятор данные выравнивает, а для М4 нет?

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


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

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

 

В принципе, я нашел как договорится с компилятором с помощью __attribute__(align(4)). Блин, но я тогда гвоздями прибью этот код к конкретному компилятору
Да.

И, опять же не понятно, почему для М3 компилятор данные выравнивает, а для М4 нет?
Вероятнее всего там вам просто повезло.

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


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

...
Да. Сейчас все изучил, прочитал и понял - где ошибался. Но. Ладно - в Keil мне повезло с одним проектом. В IAR повезло с двумя??? Сроду никогда таким везучим не был.

 

Вспомнил. До этого делал еще один проект с STM32L151 год назад - стек USB такой же - свой, самописный. Те же структуры и данные. ХардФолтов не было точно. И еще один проект делал тоже год назад но на STM32F103. На этом же стеке, но в IAR - и тоже без проблем. Вот и привык, что компилятор сам все адреса выравнивает... Т.е. вылезло только вчера и только на М4 и только на Keil.

 

Выравнивается любая структура или массив.

Но, в принципе, чтобы уйти от __attribute__(align(4)) я могу все структуры сделать как union c переменной типа UINT32:

#pragma pack(4)
typedef struct __Foo
{
    ....

} Foo, *p_Foo
#pragma pack()

union __uFoo
{
    Foo DataStructure;
    UINT32 dwValue;

} uFoo, *p_uFoo;

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


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

Сергей Борщ, а можно я один вопрос задам. Тему новую не хочется постить.

Компилятор IAR. Процессор stm32f407.

Допустим я делаю следующее

typedef enum TIP_COMPORT {RS232, RS485} typecomport_t;                            // Типы COM портов
...
typedef struct
{
  typecomport_t            typecomport;    // Тип COM порта
  uint8_t                responseDelay;    // Пауза м/у запросом и ответом в мс
  uint16_t                baudrate;        // Скорость порта
  nbitscomport_t        nbits;            // Число бит в байте
  paritycomport_t        parity;            // паритет
  stopbitscomport_t        stopbits;        // Число стоп-бит
//  flowcontrolcomport_t    flowcontrol;    // тип управления потоком
  protokolcomport_t        protokol;        // тип протокола
} ComSetting_t;

Вроде бы как читал, что любой enum компилятор определяет как тип int. То есть для данной платформы это должно быть 16 бит.

Но по факту в данной структуре это 8 бит. Почему?

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


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

SasaVitebsk, потому что в IAR в документации написано, что тип enum берется наименьший из возможных.

У Вас 2 занчения всего - {0, 1} - они прекрасно вмещаются в 1 байт.

 

Если не нравится - задайте ручками

typecomport PortType :16;

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


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

Но, в принципе, чтобы уйти от __attribute__(align(4)) я могу все структуры сделать как union c переменной типа UINT32:

Да, можете. Я иногда использую анонимные структуры:

typedef union
{
    struct 
    {
        uint8_t Member_a;
        uint32_t Memeber_b;
        .....
    } __attribute__((__packed__));
    uint32_t Raw[1];
} foo;
foo Foo, *p_Foo;

 

Вроде бы как читал, что любой enum компилятор определяет как тип int. То есть для данной платформы это должно быть 16 бит.

Но по факту в данной структуре это 8 бит. Почему?

У компилятора есть галочка "делать по Стандарту или короткие enum". Короткие мне кажутся более удобными. В конце концов можно в enum добавить лишний член со значением 0xFFFF. А в целом, переходите на плюсы - там можно указать явно
enum typecomport_t : uint16_t 
{
    RS232,
    RS485,
};

не считая остальных вкусняшек.

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


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

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

#ifndef _COMPILER_H_
#define _COMPILER_H_ 1

#if   defined(__GNUC__)
#    include "compiler_gcc.h"
#elif defined(__CC_ARM)
#    include "compiler_arm.h"
#else
#    error unsuported compiler!
#endif

#endif

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


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

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

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

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

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

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

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

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

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

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