This article describes SD card mounting and file reading and writing. Use a button to trigger the reading of SD card files. If there is no file for the first time, it will be created and the file will be printed after it is read.
1. Hardware Principle
The main control SOC of the development board has an SD/MMC controller (SDMC for short), which supports access to SD card/eMMC/SDIO devices. The hardware principle is as follows: SDMC1 is used. There is an SD card holder on the development board, and an SD card is inserted.
Figure 1: SD card interface principle
2. Code Preparation
This section is divided into SD card mounting and SD card file reading and writing, which are described separately below.
●.SD card mounting
1. Configure the SDMC interface. Here, SDMC1 is used according to the hardware principle.
Figure 2: SD interface configuration
2. Set up automatic mounting. Here we slightly rewrite the mount table mount_table in board.c as follows
Figure 3: Setting up automatic mounting
3. Hot-swap configuration. Currently, only SDMC1 hot-swap is implemented under Lite, which just supports it.
Figure 4: SD card hot-swap configuration
At this point, the SD card mounting configuration and preparation are complete.
●.SD card file reading and writing
The functions implemented in this part are: using buttons to trigger file reading and writing, creating a file if the SD card is not opened for the first time, and printing the file directly after reading it.
1. SD card reading and writing uses the file system. Configure the file system below. Here you need to open elm (i.e. FatFS file system) in RT-Thread
Figure 5: File system configuration
2. Define the root path of the SD card, apply for the file read and write memory size FILE_DATA_LEN, as well as the message sending data structure and message classification.
#define SD_PATH "sdcard/"
#define FILE_DATA_LEN_64K 64*1024
#define FILE_DATA_LEN_16K 16*1024
#define FILE_DATA_LEN 5*1024
typedef enum
{
MSG_LED_BUZZER,
MSG_SD,
}MSG_EVT_TYPE;
typedef struct
{
uint8_t msg_type;
uint16_t msg_len;
uint8_t led_value;
uint8_t buzzer_pwm_percent;
}msg_control;
3. Send SD card operation message queue in key interrupt
static void key_irq_handler(void *args)
{
unsigned int ret;
u32 pin = *((u32 *)(args));
printf("Key INT \r\n");
memset(&msg_control_t,0,sizeof(msg_control));
msg_control_t.msg_type=MSG_SD;
msg_control_t.msg_len=sizeof(msg_control_t);
app_msg_send(&msg_control_t,sizeof(msg_control_t));
}
4. Implement the reading and writing of SD card files in the message queue receiving task. The logs added in it can be convenient for subsequent testing.
void app_thread_entry(void *parameter)
{
FILE *fp;
char file_path[128] = { 0 };
char *data;
int ret;
int pin;
msg_control msg_control_p;
while(1)
{
if(rt_mq_recv(&user_mq, &msg_control_p, sizeof(msg_control_p), RT_WAITING_FOREVER)==RT_EOK)
{
rt_kprintf("Receive msg quene.msg_type:%d,msg_len:%d\r\n",msg_control_p.msg_type,msg_control_p.msg_len);
switch(msg_control_p.msg_type)
{
case MSG_LED_BUZZER:
rt_kprintf("led_value:%d,buzzer_pwm_percent:%d%%\r\n",\
msg_control_p.led_value,msg_control_p.buzzer_pwm_percent);
pin = rt_pin_get(LED_PIN);
rt_pin_write(pin, msg_control_p.led_value);
hal_pwm_set(BUZZER_PWM_CH, msg_control_p.buzzer_pwm_percent*BUZZER_FREQ_PARAM/100, BUZZER_FREQ_PARAM,PWM_SET_CMPA_CMPB);
break;
case MSG_SD:
data = aicos_malloc_align(0, FILE_DATA_LEN, CACHE_LINE_SIZE);
if (data == NULL)
{
rt_kprintf("Low memory\r\n");
return;
}
rt_kprintf("To Read File...\r\n");
rt_sprintf(file_path, "%s%s", SD_PATH,"test.txt");
fp=fopen(file_path,"rb");
if(fp==NULL)
{
rt_kprintf("Open read file %s failed!\n", file_path);
fclose(fp);
fp=fopen(file_path,"wb");
if (fp == NULL)
{
printf("create file %s failed!\n", file_path);
}
else
{
rt_kprintf("Open write file %s OK!\n", file_path);
rt_sprintf(data, "%s","你好,欢迎使用匠芯创开发板");
ret=fwrite(data, sizeof(char), FILE_DATA_LEN, fp);
{
rt_kprintf("Write file Success! size:%d\n", ret);
rt_kprintf("Write file Content:\r\n%s\r\n", data);
}
}
fclose(fp);
aicos_free_align(0, data);
}
else
{
rt_kprintf("Open read file %s OK!\n", file_path);
ret=fread(data, sizeof(char), FILE_DATA_LEN, fp);
if(ret)
{
rt_kprintf("Read file Success! size:%d\n", ret);
rt_kprintf("Read file Content:\r\n%s\r\n", data);
}
fclose(fp);
aicos_free_align(0, data);
}
break;
default :
break;
}
}
}
}
The following is the logic function code structure of the project about SD card reading and writing. At this point, the code is ready.
Figure 6: SD card reading and writing project
3. Test
After compiling and burning, we start the test, which is also divided into two parts: SD card mounting and SD card file reading and writing.
1. Query the SD card device and use the command list_device as follows
Figure 7: SD card identification
2. Press the WEAKUP button, and you can see that if there is no file, a file will be created and data will be written. Press it again to read the file. The command is entered into the SD card, and you can check that the test.txt file has been created.
Figure 8: SD card read and write log
At this point, the SD card is successfully mounted and file reading and writing are achieved.