1

我想从 Linux 用户空间控制 FlashAir SD 卡。我决定选择 mmc ioctl 向 SD 卡发送命令。我在这里这里参考

我的代码是

#define MMC_BLOCK_MAJOR     179

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <linux/mmc/ioctl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <sys/ioctl.h>

#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1)        /* 136 bit response */
#define MMC_RSP_CRC (1 << 2)        /* expect valid crc */
#define MMC_RSP_BUSY    (1 << 3)        /* card may send busy */
#define MMC_RSP_OPCODE  (1 << 4)        /* response contains opcode */
#define MMC_RSP_SPI_S1  (1 << 7)        /* one status byte */

#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R2  (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3  (MMC_RSP_PRESENT)

#define MMC_SEND_STATUS         13
#define MMC_READ_SINGLE_BLOCK   17
#define READ_MULTIPLE_BLOCK     18
#define MMC_READ_EXTR_SINGLE    48

#define MMC_DATA_READ   (1 << 9)
#define MMC_CMD_AC  (0 << 5)
#define MMC_CMD_ADTC    (1 << 5)
#define MMC_CMD_BC  (2 << 5)
#define MMC_CMD_BCR (3 << 5)

uint8_t data_buffer[512];

int main(int argc, char *argv[])
{
    int i, fd;
    int ret = 0;
    struct mmc_ioc_cmd cmd;
    uint8_t mio = 1, func = 1; 
    uint16_t count = 0x200;
    uint32_t addr = 0x400;
    uint32_t offset = addr & 0x1FF;
    if (offset + count > 512) count = 512 - offset;   
    uint32_t arg = 
                    (((uint32_t)mio & 0x1) << 31) | 
                    (mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
                    ((addr & 0x1FFFF) << 9) |
                    ((count - 1) & 0x1FF);                          


    fd = open("/dev/mmcblk0", O_WRONLY);

    if(fd < 0)
    {
        perror("file open");
        return fd;
    }



#if 1  // CMD48 
    memset(&cmd, 0, sizeof(struct mmc_ioc_cmd));
    memset(data_buffer, 0, sizeof(data_buffer));

    cmd.opcode = MMC_READ_EXTR_SINGLE;
    cmd.arg = 0x900001ff;
    cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
    cmd.blksz = 512;
    cmd.blocks = 1;
    mmc_ioc_cmd_set_data(cmd, &data_buffer); // I also try with mmc_ioc_cmd_set_data(cmd, data_buffer)
    ret = ioctl(fd, MMC_IOC_CMD, &cmd); 
    printf("MMC_READ_EXTR_SINGLE response[0] = %x\n", cmd.response[0]);
    printf("ret = %d\n", ret);
    printf("data_buffer[1] = %d\n", data_buffer[1]);    
    printf("data_buffer[2] = %d\n", data_buffer[2]);
#endif

#if 1  // CMD17 
    memset(&cmd, 0, sizeof(struct mmc_ioc_cmd));
    memset(data_buffer, 0, sizeof(data_buffer));

    cmd.opcode = MMC_READ_SINGLE_BLOCK;
    cmd.arg = 0x0;
    cmd.flags = 0xb5;
    cmd.blksz = 512;
    cmd.blocks = 1;
    mmc_ioc_cmd_set_data(cmd, &data_buffer); // I also try with mmc_ioc_cmd_set_data(cmd, data_buffer)
    ret = ioctl(fd, MMC_IOC_CMD, &cmd); 
    printf("READ_MULTIPLE_BLOCK response[0] = %x\n", cmd.response[0]);
    printf("ret = %d\n", ret);  
    printf("data_buffer[1] = %d\n", data_buffer[1]);    
    printf("data_buffer[2] = %d\n", data_buffer[2]);
#endif

    close(fd);

    return 1;
}

ret = 0(似乎没有错误)但 data_buffer[i] 总是得到值 0。实际上,我想在此创建一个像 Arduino 示例这样的示例,我使用 Linux 的自定义板。

谢谢你的帮助!

4

0 回答 0