我想从 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 的自定义板。
谢谢你的帮助!