2017-02-07 7 views
4

Что я делаю:Как имитировать функции в заголовочных файлах?

Я использую для запуска модульных тестов для большого вложенным проекта. Вложенный проект скомпилирован с arm-gcc-compiler. Модульные тесты скомпилированы с нормальным gcc с использованием фрагментов встроенного кода и библиотеки cmocka. Обычно cmocka рекомендует использовать флаг -Wl,--wrap=functionName, чтобы высмеять (заменить) некоторые ненужные подфункции. Это работает очень хорошо.

Проблема:

Ну, в моем встроенном коде есть один файл заголовка (foo.h), который содержит некоторые функции (объявлены как инлайн). Одна из этих функций содержит код ассемблера для arm-gcc-compiler, который, конечно же, не может быть скомпилирован gcc.

Глупо wrap -flag, похоже, не работает над функциями, которые помещаются в заголовочные файлы.

Вопрос:

Как дразнить эту функцию в headerfile прочь?

Как я пытался решить проблему:

Я думал о вставке некоторых #idef макросов, чтобы исключить раздел упомянутого ассемблере. Но это невозможно сделать, потому что этот файл принадлежит лицензированной библиотеке, и мне не разрешено изменять его содержимое.

Я мог бы извлечь мою функцию под тест в дополнительные файлы, так что foo.h больше не нужно включать. Но это путало бы структуру встроенных исходных кодов.

Точные линии задачи

Точный код помещается в portmacro.h из freeRtos в строке 233:

portFORCE_INLINE static void vPortRaiseBASEPRI(void) 
{ 
uint32_t ulNewBASEPRI; 

    __asm volatile 
    (
     " mov %0, %1            \n" \ 
     " msr basepri, %0           \n" \ 
     " isb              \n" \ 
     " dsb              \n" \ 
     :"=r" (ulNewBASEPRI) : "i" (configMAX_SYSCALL_INTERRUPT_PRIORITY) 
    ); 
} 

где, как portFORCE_INLINE определяется как:

#define portFORCE_INLINE inline __attribute__((always_inline)) 

ответ

2

Глупо обернуть флагом, кажется, не работает на func , которые помещаются в заголовочные файлы.

Это не ошибка wrap, функция была встроена в компилятор, поэтому ничего не может сделать компоновщик.

Как издеваться над этой функцией в заголовочном файле?

Один из вариантов - использовать sed, чтобы автоматически исправить нарушающий код, прежде чем передавать его в gcc. Например.изменить

portFORCE_INLINE static void vPortRaiseBASEPRI(void) 
{ 
    uint32_t ulNewBASEPRI; 
    ... 
} 

portFORCE_INLINE static void vPortRaiseBASEPRI_2(void) 
{ 
    uint32_t ulNewBASEPRI; 
    ... 
} 

из вашего примера в

portFORCE_INLINE static void vPortRaiseBASEPRI(void); 

portFORCE_INLINE static void vPortRaiseBASEPRI_2(void); 

сделать

cat tmp.c | sed '/inline\|INLINE/,/^}$/{ s/^\(.*\(inline\|INLINE\).*\)/\1;/; /inline\|INLINE/!d }' 

Регулярное выражение довольно неаккуратно, он опирается на тот факт, что все определения в заголовке будет иметь INLINE маркер, но вероятно, будет достаточно в вашем случае.

Вы можете встроить вышеуказанную команду в свой файл Makefile для создания настраиваемого заголовка во временной папке, а затем переопределить заголовок по умолчанию с флагом -Ipath/to/temp/folder.

+0

@LPs Но как? Linker не имеет доступа к исходному коду, а по истечении времени компоновщика ссылок функция уже была встроена и оптимизирована в значительной степени. – yugr

0

Я не использовал cmocka, поэтому я не уверен, есть ли способ управления этим уже в рамках.

Однако cmock использует метод, при котором заголовок копируются в место где-то выше в иерархии включает испытательную сборку (и только тестовую сборку, местоположение не входят даже неявно сборка выпуска).

Копия этого заголовка затем может быть отредактирована таким образом, что объявление функции просто становится port void vPortRaiseBASEPRI(void);. Затем, когда генерируются mocks, для этого (и других объявлений функций внутри одного и того же заголовка) генерируется макет, как и в любом другом случае. Поскольку генерируются hte mocks, не имеет значения, что не существует соответствующего определения исходного кода (т. Е. .c файла) для функции (функций).

Смотрите раздел «Dealing с компилятором конкретные вещи» в https://dmitryfrank.com/articles/unit_testing_embedded_c_applications

И мой подобный вопрос, и как я решил его здесь: Unit test C with compiler specific keywords

+0

Я не уверен, как он отличается от другого ответа (который, кстати, также предоставляет решение для автогенерации фиксированного заголовка). – yugr

+0

@yugr, да, теперь вы отредактировали с большим количеством объяснений, это очень похоже. Раньше я думал, что вы защищаете использование 'sed', чтобы изменить исходный заголовок, который OP заявил, что он не может этого сделать. Просто другое объяснение одной и той же идеи :-) – Toby

Смежные вопросы