【问题标题】:Raspberry PI uint8_t alignment树莓派 uint8_t 对齐
【发布时间】:2015-01-23 19:11:14
【问题描述】:

使用 uint8_t 作为传递给我的传输函数的数组时,我遇到了这种问题。在从 main 函数传递到 transfer 的那一刻,它将大小更改为 4 个元素。与我在传递函数中创建的数组相同,即使我手动创建另一个数组以从主函数发送具有传递长度的值。我知道这是因为我的处理器上的数据对齐和填充。有什么办法可以解决吗?或者我打印错了。

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>

#define ARRAY_SIZE(a)  (sizeof(a) / sizeof(uint8_t))

static const char *device = "/dev/spidev0.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 1000000;
static uint16_t delay;


static void transfer(int fd, const uint8_t *pass, size_t arsize)
{
int ret,i,k;
printf(" rozmiar tabpass=%d ", arsize);
uint8_t *rx = (uint8_t*) malloc(arsize * sizeof(uint8_t)); 
//this is where I create rx with arsize lenght
uint8_t *tx = (uint8_t*) malloc(arsize * sizeof(uint8_t));
for (i = 0; i < arsize; i++){
    *(rx + i) = 0;
    *(tx + i) = *(pass + i);
}
for (k = 0; k < (sizeof (pass) / sizeof (pass[0])); k++) {
    printf(" a%X\n ", pass[k]); 
//here I check length of passed array
}
for (k = 0; k < (sizeof (tx) / sizeof (tx[0])); k++) {
    printf(" b%X\n ", tx[k]); 
// I check length of newly created array, should be equal to array size
}
printf(" rozmiar tabtx=%d ", ARRAY_SIZE(tx));
struct spi_ioc_transfer tr = {
    .tx_buf = (unsigned long)tx,
    .rx_buf = (unsigned long)rx,
    .len = arsize,
    .delay_usecs = delay,
    .speed_hz = speed,
    .bits_per_word = bits,
    .cs_change = 0,
};

ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
printf(" rozmiar tabrx=%d ", ARRAY_SIZE(rx)); 
//here it prints size of array equals 4
for (ret = 0; ret < arsize; ret++) {
    if (!(ret % 6))
        puts("");

    printf("%d. %.2X ", ret, rx[ret]);

}
puts("");
tr.cs_change = 1;
}

int main(int argc, char *argv[])
{
int ret = 0;
int fd;

fd = open(device, O_RDWR);

/*
* spi mode
*/
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);

ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);

/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);

/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);

printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed / 1000);

uint8_t tx1[] = {
    0x0, 0x1b, 0xa5
};
transfer(fd, tx1, ARRAY_SIZE(tx1));

uint8_t tx2[] = {
    0x0, 0x33, 0x30
};
printf(" %d. ", ARRAY_SIZE(tx2));
transfer(fd, tx2, ARRAY_SIZE(tx2));

uint8_t tx3[] = {
    0x0, 0x52, 0x90
};
transfer(fd, tx3, ARRAY_SIZE(tx3));

uint8_t tx4[] = {
    0x80, 0x60
};
printf(" %d. ", ARRAY_SIZE(tx4));
transfer(fd, tx4, ARRAY_SIZE(tx4));

close(fd);

return ret;
}

【问题讨论】:

    标签: c arrays 32-bit spi uint8t


    【解决方案1】:

    对于sizeof 运算符要给出数组的实际大小,您需要:

    1. 静态分配数组
    2. 在其声明范围内引用数组

    例如:

    void func()
    {
        int arr[10];
        int total_size = sizeof(arr);
        int num_of_elements = sizeof(arr)/sizeof(*arr);
        ...
    }
    

    数组不是静态分配的例子:

    void func()
    {
        int* arr = malloc(sizeof(int)*10);
        int total_size = sizeof(arr); // will give you the size of 'int*'
        ...
    }
    

    数组不在其声明范围内的示例:

    void func(int arr[]) // same as 'int* arr'
    {
        int total_size = sizeof(arr); // will give you the size of 'int*'
        ...
    }
    

    【讨论】:

    • 我要补充一点,对于几乎所有实际目的,作为函数参数的数组是调用指针的另一种语法。这篇文章解释了一个区别:stackoverflow.com/questions/5573310/…
    • @BrianMcFarland:是的,我可能应该补充一点,数组在传递给函数时会衰减为指针。
    • 好的,这就是我尝试创建自己的数组 tx 以在声明范围内引用的原因。当我的 arsize 只取 2 或 3 作为值时,它没有解释为什么数组 rx 是 4 个元素长,它的大小在传递函数中打印。
    • @BrianMcFarland:就语言标准而言,它们是相同的。像void func(int arr[]),甚至void func(int arr[42]) 这样的函数声明,实际上意味着 void func(int *arr)
    • @Eggboard:您似乎错过了我提到sizeof 运算符仅在数组静态分配 时为您提供实际大小的部分。正如我在上面的第二个示例中所示 - 您的 rx 数组是 NOT 静态分配的。
    猜你喜欢
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 2014-09-14
    • 2019-07-16
    • 2014-12-09
    • 2013-11-05
    • 2015-06-02
    相关资源
    最近更新 更多