Jump to content

    

WinAVR и адрес статической функции

static basis sum(uint8_t arg_cnt, void **args){
        basis result = 0;
        for(;arg_cnt--;*args++){
               result += evalute(args);
        }
        return result;
    }
    

#define num(x)    ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16UL) & 0xFF), (((x) >> 24UL) & 0xFF)


#define adr(x)    ((uint16_t)(x) & 0xFF), ((uint16_t)(x) & 0xFF00) >> 8
    
    uint8_t massiv[] = {
            TOC_VAR, 0,
                TOC_FUNC,adr(sum), 0, 3,
                    TOC_NUMBER, num(99UL),
                    TOC_NUMBER, num(1UL),
                    TOC_VAR, 0,
            TOC_END
    };

не получается занести в массив адрес функции :( пишет - не константа :( с чего бы это вдруг?

Share this post


Link to post
Share on other sites
пишет - не константа :( с чего бы это вдруг?
Вероятно, хочет явного приведения адреса функции к типу uintptr_t : TOC_FUNC,adr((uintptr_t)sum),

 

Share this post


Link to post
Share on other sites
Вероятно, хочет явного приведения адреса функции к типу uintptr_t : TOC_FUNC,adr((uintptr_t)sum),
не, похоже не так... http://530.ru/wwwboards/mcontrol/3029/messages/1226781.shtml

 

 

во всяком случае ни какие преобразования типов не помогают: не константный аргумент - и точка.

 

 

Share this post


Link to post
Share on other sites
static убрать

убрать статик - не помогает

 

явно привести тип к любому int - не помогает

 

 

определять массив с указателями в PROGMEM - помогает.

 

 

Share this post


Link to post
Share on other sites

static void test()
{

}

#define adr(x)    ((uint16_t)(x) & 0xFF), ((uint16_t)(x) & 0xFF00) >> 8

uint8_t Test[] =
{
        adr(test),
        (uintptr_t)test >> 0,
        (uintptr_t)test >> 8,
        (uintptr_t)test >> 16,
        (uintptr_t)test >> 24,
};

 

Compiling: main.cpp

main.cpp:50: warning: right shift count >= width of type

main.cpp:51: warning: right shift count >= width of type

что и следовало ожидать - размер uintptr_t - 2 байта. Так что ищите проблему в другом месте.

Share this post


Link to post
Share on other sites
Так что ищите проблему в другом месте.

 

#include "plc_editor.h"
static void foo(void){
}

#define adr(x)    ((uint16_t)(x) & 0x00FF), ((uint16_t)(x)>>8)

uint8_t array[] = {
        adr(foo)
};

Building file: ../plc_editor.c

Invoking: AVR Compiler

avr-gcc -Wall -g3 -gdwarf-2 -O0 -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=16000000UL -MMD -MP -MF"plc_editor.d" -MT"plc_editor.d" -c -o"plc_editor.o" "../plc_editor.c"

../plc_editor.c:27: error: initializer element is not constant

../plc_editor.c:27: error: (near initialization for 'array[0]')

../plc_editor.c:28: error: initializer element is not constant

../plc_editor.c:28: error: (near initialization for 'array[1]')

make: *** [plc_editor.o] Error 1

и где искать?

Share this post


Link to post
Share on other sites

static void foo1(void){}
static void foo2(void){}

typedef union
{
    void (*foo)(void);
    uint8_t bytes[sizeof(void*)];
} union_t;

const union_t array[] =
{
    foo1,
    foo2
};

Смените подход. И объявите union вашего пакета данных и массива байт.

 

что и следовало ожидать - размер uintptr_t - 2 байта. Так что ищите проблему в другом месте.
C++ != С

Share this post


Link to post
Share on other sites
и где искать?
Бага. В режиме С++ все компилится. И массив из указателей на функции в режиме С создается. А вот на приведении указателя с целому - спотыкается. Пишите баг-репорт.

 

Share this post


Link to post
Share on other sites
Бага. В режиме С++ все компилится. И массив из указателей на функции в режиме С создается. А вот на приведении указателя с целому - спотыкается. Пишите баг-репорт.

Думаю что с багрепортом рановато. Нужно стандарт изучить на сей счёт ибо и RealView-MDK-ARM - тоже даёт предупреждение, но проект собирает.

Хотя и по моему мнению разницы быть не должно, что приводишь к целому что нет.

 

2ТС:

Cмените диалект с gnu99 на c99. Есть разница?

Share this post


Link to post
Share on other sites

static void foo(void){
}

static uint8_t array[] = {foo};

Building file: ../plc_editor.c

Invoking: AVR Compiler

avr-gcc -Wall -g3 -gdwarf-2 -O0 -fpack-struct -fshort-enums -std=c99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=16000000UL -MMD -MP -MF"plc_editor.d" -MT"plc_editor.d" -c -o"plc_editor.o" "../plc_editor.c"

../plc_editor.c: At top level:

../plc_editor.c:95: warning: initialization makes integer from pointer without a cast

../plc_editor.c:95: error: initializer element is not computable at load time

../plc_editor.c:95: error: (near initialization for 'array[0]')

make: *** [plc_editor.o] Error 1

 

ну на счет предупреждений - бог с ними, но пишет ведь ошибку - элемент не может быть вычислен на этапе компиляции! в run-time я могу записать туда адрес любой функции, не проходит только инициализация

Share this post


Link to post
Share on other sites
не проходит только инициализация

 

static void foo(void){
}

typedef void (*fptr)();
fptr array[] = {
        foo
};

Компиляция проходит. Проблема начинается при попытке занести в массив целых чисел.

 

Share this post


Link to post
Share on other sites
Компиляция проходит. Проблема начинается при попытке занести в массив целых чисел.
совершенно верно! причем если массив uint16_t - то тоже пролетает на ура (с варнингами о преобразовании указателя в целое), а вот uint8_t дает ошибку...

то есть это БАГ? по идее ведь батовый массив или не байтовый - какая разница для Си?

Share this post


Link to post
Share on other sites
совершенно верно! причем если массив uint16_t - то тоже пролетает на ура (с варнингами о преобразовании указателя в целое),
А если сделать явное приведение - не ругается.

 

а вот uint8_t дает ошибку...

то есть это БАГ?

Да. Причем бага именно avr-gcc. Потому что именно avr-gcc ругается (проверил и на 3.4.6 и на 4.3.3), в то время как mingw-gcc прекрасно компилит.

 

Share this post


Link to post
Share on other sites

Хм ... а можно дурацкий вопрос ? откуда компилятор возмет адрес функции что-бы вычислить значение adr(x) ?? IMHO адрес может проявиться только на этапе сборки (если не выпендриваться с __attribute__ ) ?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this