2014-09-04 6 views
1

Я работаю над платформой 8051, которая имеет ширину указателя 16 бит.Не понимаю преобразования от целочисленной к меньшей ошибке указателя

У меня есть общий модуль кода для обработки эмуляции флэш и есть функция, которая возвращает 16 битный начальный адрес страницы:

volatile u16_t start_address = find_start_address_of_page(page); 

Я думаю, хочу передать этот «адрес» для функции CRC, что хочет u8_t * в качестве параметра, так что я бросил его в вызове функции, как так:

(u8_t *)start_address 

Это генерирует предупреждение

Предупреждение [Pe1053]: преобразование из целого числа к меньшему указателю

Что меня смущает немного, потому что u8_t * имеет ширину 16 бит, и моя переменная является переменной величиной 16 бит. Это просто, что компилятор предупреждает о преобразовании «целое число в указатель» вообще?

код работает отлично, я просто хочу быть уверен, что я не хватает чего-то глупого здесь ...

+0

start_address - целое число с 16 битами, а не указатель на целое число. Попробуйте использовать (u8_t *) (& start_address) – braindf

+0

Да, но это не то, чего я хочу достичь - это даст мне _address_ start_address. start_address - это самое значение адреса, которое хранится как целое число. – Matt

+1

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

ответ

2

Вы пишете, что ваша платформа 8051 имеет ширину указателя шириной 16 бит.

Насколько я знаю, 8051 имеет различные диапазоны адресов для - внутреннее ОЗУ в процессоре (макс 256 байт) - внешнее ОЗУ (макс 64k) - Программа памяти (макс 64k)

У компилятора, с которым я работал (Keil), было, по крайней мере, четыре разных типа указателей. Указатель шириной 8 бит для внутренней памяти. 16-разрядный указатель «xdata» для внешней оперативной памяти. Указатель 16-разрядного «кода» для памяти программы. Универсальный указатель шириной 24 бит, который может быть настроен на любой из трех типов памяти. Первый байт использовался для выбора типа памяти.

Текст предупреждения может означать, что компилятор хочет преобразовать ваше 16-битное значение в адрес внутренней памяти, ширина которого составляет всего 8 бит.

+0

Отличная точка - я об этом никогда не думал. Я передумаю это с учетом этого. – Matt

-3

start_address имеет тип u16_t, а не указатель.

если вы хотите передать свой адрес к КПР, то попробуйте следующее:

((u8_t *)((u16_t *)start_address)) 
+0

Как следует из названия переменной, 'start_address' содержит сам адрес. – interjay

+0

в этом случае попробуйте это, ((u8_t *) ((u16_t *) start_address)) – shoham

+0

Создает такую ​​же ошибку. – Matt

1

Если вы хотите, чтобы заглушить ваше предупреждение, вы можете использовать объединение, чтобы переместить информацию в другой тип, т.е.

union { 
    u16_t origType; 
    u8_t *newtype; 
} u; 

u.origType = start_address; 

Предполагая, что они того же размера, вы можете передать u.newtype в вашу функцию.

+0

Cheers - к сожалению, MISRA не разрешает союзы! Хорошо, хотя, рад подавить предупреждение, я просто убедился, что мое мышление верное. – Matt

1

Поскольку start_address является переменная, которая содержит адрес памяти, вы должны объявить и использовать его в качестве такового, то есть указатель:

volatile u16_t *start_address = find_start_address_of_page(page); 

Конечно, это также означает, что функция find_start_address_of_page(); должна возвращать указатель.

Кстати, тот факт, что int и int * оба являются шириной 16 бит (на вашем процессоре), недостаточно. Например, указатель на int на большинстве (всех?) 16-разрядных процессоров должен быть выровнен с четным (кратным 2) адресу из-за ограничений инструкций ассемблера и/или реализации шины данных.

Точно так же, такие вещи, как приращений по-разному в зависимости от того, что является int или int * (или даже char *). Если он равен int (или char *), он будет увеличиваться на единицу, но если он равен int *, он будет увеличиваться на два.

К этому я пытаюсь показать, что компилятор делает много проверок за пределами количества бит, в зависимости от типа переменной (и возможностей процессора).

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

  • Нет связанных вопросов^_^