2014-10-12 7 views
0

У меня есть данные массива uint8_t [256]. Но каждый элемент представляет собой один байт. Моя шина данных имеет длину 32 бит. Так, если я хочу получить доступ к 32 бита, я:Как получить доступ к нескольким элементам массива за один раз?

DATA = Данные [I] + (данные [I + 1] <) + (данные [I + 2] < < 16) + (данные [i + 3] < < 24);

Но это означает 4 отдельных запроса на чтение в памяти по 1 байт каждый.

Как я могу получить доступ ко всем 4 байтам в виде одной транзакции?

+1

Если 'data' имеет тип' int [256] ', для каждого слагаемого считывается не только один байт. – mafso

+1

Вам нужно будет использовать очень нестандартный компилятор, чтобы иметь 'int data [256];' быть состоящим из одного байта. «Байты» должны быть не менее 16 бит каждый (CHAR_BIT == 16). Я думаю, что есть некоторые путаницы в предположениях, которые вы делаете. Если, как предлагает один из ваших комментариев, вы имеете в виду 'uint8_t data [256];', то один вопрос: «Собираетесь ли вы индексировать значения« i », которые не кратно 4? и еще один вопрос: «что произойдет, если вы попытаетесь получить доступ к« неправильно настроенному »адресу памяти в виде 4-байтового блока?» Вы должны знать ответы на оба перед риском коротких сокращений. –

ответ

0

Может быть, вы должны хранить данные в виде массива 32-битном:

uint32_t data[64]; 
DATA = data[i]; 
DATA = data[i+1]; 
... 
+0

Я не могу изменить массив. Это ограничение. Но если мы посмотрим на это, с точки зрения памяти, разве это не одно и то же? данные uint32_t [64] и uint8_t [256]? – Rgarg

+0

@Rgarg: Каков тип вашего массива? В этом вопросе вы говорите 'int data [256];' но вот в вашем комментарии вы, кажется, говорите 'uint8_t data [256];' - это очень разные! На самом деле это делает крушение из вашего вопроса. –

1

Если вы знаете, порядка байтов ваших данных (или, если вы не заботитесь), и ваши данные выровнены (или есть процесс байт-адресации и вы не заботитесь об эффективности) можно привести данные к uint32_t * и доступ к нему в 4-байтовых патронах, так как:

DATA = ((uint32_t *)data)[i/4]; 

Это, конечно, предполагает i кратна от 4.

1

Только литой data по uint32_t.

uint8_t data[256] = {1,2,3,4,5,6,7,8} ; 

int main(int argc, char **argv) 
{ 
    int index = 1 ; 
    uint32_t d = *(uint32_t *)(data + index) ; 
    printf ("%08x\n", d) ; 
} 

Выхода на небольшую архитектуре Endian будет

05040302 

Выход на большой архитектуре Endian будет

02030405 

Однако в зависимости от achitecture процессора вашего Progam выполняется на , вы можете столкнуться с проблемами с выравниванием памяти (производительность ударяется, если вы обращаетесь к неравномерной памяти или даже к сбою, если ваш процессор не поддерживает некорректную адресацию памяти).

+0

Я пробовал это, и это почти сработало: данные, которые у меня есть, являются 01,02,03,04,05,06,07,08 ... Когда я получаю доступ к первому местоположению как * (long *) (данные + 0) , Я получаю 0x01030201 вместо 0x04030201. И когда я получаю доступ к * (long *) (данные + 1), я получаю 0x05040302.Это означает данные [4] = 4, но возвращаемое значение неверно, есть ли у вас какие-либо идеи, почему это так? – Rgarg

+0

Код здесь отлично работает. Задайте новый вопрос о stackoverflow с этой конкретной проблемой. –

-1

Как упоминалось в @ dwayne-towell - вам нужно заботиться о контентоспособности данных. В одной транзакции это может быть реализовано, например, как показано ниже:

#include <stdio.h> 
#include <stdint.h> 

int 
main() 
{ 
     uint8_t data[256]; 
     uint32_t i, *p; 

     // Add some 32bit numbers 
     p = (uint32_t *)data; 
     for (i = 0; i < sizeof(data)/sizeof(uint32_t); ++i) { 
       *(p++) = i; 
     } 

     // Print some 32bit numbers 
     p = (uint32_t *)data; 
     for (i = 0; i < sizeof(data)/sizeof(uint32_t); ++i) { 
       printf("value=%u\n", *(p++)); 
     } 

     return (0); 
} 
+0

Интересно, зачем голосовать? – soerium

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