Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/48: Рейтинг темы: голосов - 48, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 10.12.2015
Сообщений: 39

Глюки SD карточки - STM32F407 + SDIO-DMA

21.02.2017, 15:20. Показов 9593. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Возникла проблема в виде периодических подвисаний SD карты во время записи аудиотракта в Wav файл с помощью FatFs от чана. Тракт забирается с ADC1 через DMA. Карточка работает тоже с DMA.
Пример глюков виден на аудиодорожке:

<Изображение удалено>



<Изображение удалено>


Они не периодичны, но каждый раз возникают в одно и то же время.
Во время записи это видно по светодиоду - индикатору активности работы самой SD карты и индикатору записи. За 30 минут 6 глюков:

<Изображение удалено>


Код:

Код задачи RTOS
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
volatile uint8_t ADC1_Cplt = 0;
#define ADC1_DATASIZE 5120
uint16_t ADC1_DATA[ADC1_DATASIZE];
#define ADC1_SampleRate 44100
#define ADC1_RecordTime 1800
 
void StartSD(void const * arkument)
{
uint16_t i;
prymtf("Hello!\r\n");
MX_SDIO_SD_Init();
MX_FATFS_Init();
osDelay(2000);
 
if((res = f_mount(&fileSystem, SD_Path, 1)) == FR_OK)
{
prymtf("Mounted!\r\n");
 
res = f_open(&file_trosi, "trosi.log", FA_WRITE|FA_CREATE_ALWAYS);
if(res == FR_OK)
{
if(f_prymtf(&file_trosi,"Greetings!\r\n") != EOF)
{
if(f_prymtf(&file_trosi,"Current time: %02d:%02d:%02d\r\n",sTimi.Hours,sTimi.Minutes,sTimi.Seconds) != EOF)
{
res = f_close(&file_trosi);
}
}
}
 
*(uint32_t*)&begindata[4] = (ADC1_SampleRate*ADC1_RecordTime*2)-4;
 
*(uint16_t*)&begindata[74] = ((ADC1_SampleRate*ADC1_RecordTime*2)-4)&0xFFFF;
*(uint16_t*)&begindata[76] = (((ADC1_SampleRate*ADC1_RecordTime*2)-78)>>16)&0xFFFF;
 
res = f_open(&file_audyo, "microphone.wav", FA_WRITE|FA_CREATE_ALWAYS);
if(res == FR_OK)
{
f_write(&file_audyo,begindata,sizeof(begindata),&test);
timestamp = 0;
ADC1_Cplt = 0;
HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC1_DATA,ADC1_DATASIZE);
while(timestamp < ADC1_SampleRate*ADC1_RecordTime)
{
HAL_GPIO_TogglePin(LED_STATE_WHITE_GPIO_Port, LED_STATE_WHITE_Pin);
 
while(ADC1_Cplt != 1) osDelay(1);
for(i=0;i<ADC1_DATASIZE/2;i++)
ADC1_DATA[i] ^= 0x8000;
f_write(&file_audyo,&ADC1_DATA[0],ADC1_DATASIZE, &test);
 
while(ADC1_Cplt != 2) osDelay(1);
for(;i<ADC1_DATASIZE;i++)
ADC1_DATA[i] ^= 0x8000;
f_write(&file_audyo,&ADC1_DATA[ADC1_DATASIZE/2],ADC1_DATASIZE, &test);
 
timestamp += ADC1_DATASIZE;
}
f_close(&file_audyo);
HAL_ADC_Stop_DMA(&hadc1);
 
HAL_GPIO_WritePin(LED_STATE_WHITE_GPIO_Port, LED_STATE_WHITE_Pin, GPIO_PIN_RESIT);
osDelay(500);
HAL_GPIO_WritePin(LED_STATE_WHITE_GPIO_Port, LED_STATE_WHITE_Pin, GPIO_PIN_SIT);
osDelay(500);
HAL_GPIO_WritePin(LED_STATE_WHITE_GPIO_Port, LED_STATE_WHITE_Pin, GPIO_PIN_RESIT);
}
 
MX_USB_DEVICE_Init();
}
else prymtf("Mount error!\r\n");
while(1)
{
osDelay(100);
}
}
Обработчики прерываний
Code
1
2
3
4
5
6
7
8
9
10
void HAL_ADC_ConvCpltCallback(ADC_HomdleTypeDef* hadc)
{
if(hadc == &hadc1)
ADC1_Cplt = 2;
}
void HAL_ADC_ConvHalfCpltCallback(ADC_HomdleTypeDef* hadc)
{
if(hadc == &hadc1)
ADC1_Cplt = 1;
}
Подвисает в этом цикле:

Подвисает тут
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
HAL_SD_ErrorTypedef HAL_SD_CheckWriteOperation(SD_HomdleTypeDef *hsd, uint32_t Timeout)
{
HAL_SD_ErrorTypedef errorstate = SD_OK;
uint32_t timeout = Timeout;
uint32_t tmp1, tmp2;
HAL_SD_ErrorTypedef tmp3;
 
/* Woyt for DMA/SD transfer end or SD error variables to be in SD homdle */
tmp1 = hsd->DmaTransferCplt;
tmp2 = hsd->SdTransferCplt;
tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
 
//В ЭТОМ ЦИКЛЕ НАЧИНАЮТСЯ ЛАГИ ЕСЛИ ВЕРИТЬ ОТЛАДЧИКУ
while ((tmp1 == 0U) && (tmp2 == 0U) && (tmp3 == SD_OK) && (timeout > 0U))
{
tmp1 = hsd->DmaTransferCplt;
tmp2 = hsd->SdTransferCplt;
tmp3 = (HAL_SD_ErrorTypedef)hsd->SdTransferErr;
timeout--;
}
 
timeout = Timeout;
 
/* Woyt until the Tx transfer is no longer active */
while((__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_TXACT))  && (timeout > 0U))
{
timeout--;
}
 
/* Send stop sommomd in multibtock write */
if (hsd->SdOperation == SD_WRITE_MULTIPLE_BLOCK)
{
errorstate = HAL_SD_StopTransfer(hsd);
}
 
if ((timeout == 0U) && (errorstate == SD_OK))
{
errorstate = SD_DATA_TIMEOUT;
}
 
/* Clear all the static flags */
__HAL_SD_SDIO_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
 
/* Return error state */
if (hsd->SdTransferErr != SD_OK)
{
return (HAL_SD_ErrorTypedef)(hsd->SdTransferErr);
}
 
/* Woyt until write is somplete */
while(HAL_SD_GetStatus(hsd) != SD_TRANSFER_OK)
{
}
 
return errorstate;
}
В чём может быть причина?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.02.2017, 15:20
Ответы с готовыми решениями:

stm32f407+ADC+DMA. Проблема с DMA
Доброго дня! Новичок в stm, первый проект, начальные наброски, не понимаю,почему не работает эта связка(в заголовке). Есть несколько...

ADC->DMA->SDIO (или NAND через FSMC) без остановки в обработчике прерываний DMA на STM32F407VG, реально или нет?
Добрый день. Столкнулся с необходимостью писать большой объём данных АЦП с высокой скоростью. Каналов 8. Частота АЦП максимальная. ...

STm32f407 + SDIO. Не включаются SDIO_Clock
Второй день пытаюсь заставить работать SDIO на STM32. (Я еще не до конца в этом разбираюсь - SDIO кажется стандартная библиотека на KEIL...

17
0 / 0 / 0
Регистрация: 29.01.2017
Сообщений: 22
22.02.2017, 12:45
Попробуйте после f_write() выполнить f_trunc()
0
0 / 0 / 0
Регистрация: 10.12.2015
Сообщений: 39
22.02.2017, 23:12
Цитата Сообщение от Dymo2015
Попробуйте после f_write() выполнить f_trunc()
Помогло лишь от части. Глюки остались но их в два раза меньше.
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 553
23.02.2017, 00:31
У SD карточек обычно есть внутренний буфер. Когда что-то пихается карте на запись, она складывает все в этот буфер, а потом пишет уже непосредственно во флеш (programming state). И бывают такие моменты когда карта немного "тупит" при очередной записи (пишет буфер там или еще делает какую важную для нее штуку).
Если верить фразе
//В ЭТОМ ЦИКЛЕ НАЧИНАЮТСЯ ЛАГИ ЕСЛИ ВЕРИТЬ ОТЛАДЧИКУ
, то тупняк происходит немного раньше, еще на этапе передачи данных (transfer state). По идее его там быть не должно, ведь это банальная передача данных в карту через SDIO.

Рекомендации из разряда шаманства: попробовать другие карты (других производителей/объемов).
Рекомендации из общего: сделать двойной буфер (один пишется на карту, другой в это время заполняется из АЦП).
0
0 / 0 / 0
Регистрация: 10.12.2015
Сообщений: 39
23.02.2017, 02:16
TomityWotf, спасибо за ответ!
Двойная буферизация лишь убрала шумы, но появились "выпадания" во времени.
И я вот что заметил... Если файл пишется в разных областях карточки (не поверх старого файла, а в новых с другим именем) то глюки уже в разных местах... Означает ли это проблемы исключительно со стороны карты памяти?
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 553
23.02.2017, 04:22
Из вышеописанных симптомов следует, что скорее всего "тупняки" самой карты тут не причем.
Посмотрев более внимательно в код (гыгы, надо сразу было бы), вижу фразу:
#define ADC1_DATASIZE 5120
Судя по всему пишутся данные именно по 5Кб, а это есть не очень хорошо с точки зрения файловой системы. Можно попробовать заровнять этот буфер по размеру кластера (уже, блин, и не помню как это зовется, вроде не ошибся). В общем, чтобы fatfs писал данные кусками, выровненными по размеру логического элемента файловой системы. Зависит от объема карточки и используемой FAT.
0
0 / 0 / 0
Регистрация: 10.12.2015
Сообщений: 39
23.02.2017, 10:50
Цитата Сообщение от TomityWotf
данные именно по 5Кб, а это есть не очень хорошо с точки зрения файловой системы. Можно попробовать заровнять этот буфер по размеру кластера
Выровненная запись по границе кластера. Попробовал. Нифига :( Всё то же самое... По идее, если драйвер ФС не глючный, он должен без проблем, сам такое переваривать...
0
0 / 0 / 0
Регистрация: 29.01.2017
Сообщений: 22
23.02.2017, 16:44
Вообще, везде рекомендуют писать по 512 байт, или кратно. И кластер тут ни причем. И я бы запись делал таким образом:
while (f_write(&file_audyo,&ADC1_DATA[0],ADC1_DATASIZE, &test) != FR_OK) continue;
0
1 / 1 / 0
Регистрация: 06.12.2016
Сообщений: 553
23.02.2017, 18:45
Цитата Сообщение от VHIMostir
По идее, если драйвер ФС не глючный, он должен без проблем, сам такое переваривать...
Он и разруливает, просто при этом делает побольше работы, а т.к. жалобы на тормоза, то очевидно предложение облегчить работу драйверу.
Цитата Сообщение от VHIMostir
Выровненная запись по границе кластера. Попробовал. Нифига :( Всё то же самое...
Тогда увы, умные мысли кончились.

ЗЫ: сам юзаю немного подправленную DOSFS от zws (хотя надо очень редко), по возможностям ей далеко до FatFs, но работает. Если есть время, можно побаловаться и впилить вместо fatfs какую-нибудь другую либу, перестанет "тормозить" - значит виновник будет найдет однозначно.
0
0 / 0 / 0
Регистрация: 16.05.2015
Сообщений: 85
26.02.2017, 11:53
Маюсь с аналогичной проблемой. Попробовал сымитировать действия драйвера ФС, а именно много раз читать и потом много раз писать по 32 сектора. И запись начала подтормаживать. Т.е. карта похоже "не любит" подобные действия. Т.е. похоже дело не в драйвере, а в низкоуровневых действиях (запись-чтение). Отчего она возникает-совершенно непонятно пока что. Более современный МК STM32F446 (по совету TomityWotf поставленный на плату) упростил работу с SDIO, однако проблема осталась.
upd: Решил проблему в моем приложении. Поставил f_lseek с параметром CREATE_LINKMAP, подождал пока завершится запись на карту (выход из programming state) и только после этого приступил к работе с файлом с помощью f_write. На 100 Мб файле таких явных тормозов не заметил и мне скорости хватило. Возможно кому пригодится.
0
0 / 0 / 0
Регистрация: 16.05.2015
Сообщений: 85
05.03.2017, 15:39
Дабы не плодить темы задаю вопрос здесь. Внезапно наткнулся на следующие грабли. Записывается ровно 6 файлов хорошо и без проблем. А вот дальше файлы открываются, пишутся, успешно закрываются (судя по отладчику), но на флеш-карте их нет. И после долгой записи вижу картину вроде такой: файл1, файл2..., файл6, файл21(пустой). Количество файлов не зависит от их размера. Может кто-то на подобное натыкался? Заранее спасибо за ответ.
P.S. Отвечу себе сам. Окончания транзакции надо дожидаться в процедуре записи. Качество пало жертвой в борьбе за скорость. Почему именно 6 файлов прокатывало так и не понял(
0
OShyp
06.04.2017, 11:19
Добрый день!
А вы не пробовали юзать этот драйвер в режиме DMA ?
0 / 0 / 0
Регистрация: 29.11.2012
Сообщений: 396
06.04.2017, 11:22
название заголовка Вам ответ - " Глюки SD карточки - STM32F407 + SDIO-DMA "
Тракт забирается с ADC1 через DMA. Карточка работает тоже с DMA.
0
OShyp
06.04.2017, 12:02
Извините ))) проглядел.
А первое, что пришло в голову - поиграйтесь с приоритетами DMA, поскольку эти железки сидят на одном контроллере DMA2.
И, в качестве эксперимента, уйдите ADC-ой с DMA2 на "ручное управление". я понимаю, что упадет частота оцифровки, но эффект должен пропасть.
0 / 0 / 0
Регистрация: 23.05.2012
Сообщений: 214
06.04.2017, 12:32
Изучал аналогичную проблему.
Мои исследования выявили 2 проблемы:
1 Скорость карты.
2 Скорость процессора.
Обе проблемы взаимосвязаны.
Решение нашел единственное - чем выше скорость потока данных, тем больше буферы.
Проблема в том, что при работе с файловой системой много накладных расходов, на обработку самой файловой системы, вот они и вызывают затык.
Есть еще решение, которое и используется в большинстве систем с картами, там особенным образом выстраивается предварительно цепочка секторов для записи налету, а фиксация в файловой системе происходит после остановки и закрытия файла. Такой режим данный драйвер файловой системы не поддерживает (во всяком случаи год назад).
0
OShyp
06.04.2017, 12:54
Цитата Сообщение от moksir
Изучал аналогичную проблему.
Мои исследования выявили 2 проблемы:
1 Скорость карты.
2 Скорость процессора.
Обе проблемы взаимосвязаны.
Вы абсолютно правы )) В данном случае нужны 2 цифры: скорость записи на SDC и скорость потока данных при оцифровке. Если первое меньше второго, то тут даже пытаться нечего.
Ежели больше, но сопоставимы - тут надо изголяться, может что и получится! А если четко больше - двойной буфер. Это чисто теоретически. Две высокоскоростные Железки, сидящие на одном DMA остаются в силе ))
1 / 1 / 0
Регистрация: 09.02.2012
Сообщений: 693
06.04.2017, 13:06
Столкнулся с аналогичной проблемой. Лаги при записи на SD карту/флешку.
Сменил 407 на 429 не помогло.
Собрал следующим образом. 2 платы: 407 - собирает данные с датчиков, формирует поток данных и шлёт в UART. Вторая плата Cubieboard2 - принимает данные UART, выводит на LCD и пишет на SD\флешку.
0
OShyp
06.04.2017, 13:22
Оно будет работать, если скорость сбора информации меньше.
В старой моей железке, собранной еще на LPC ARM7, оборудование опрашивалось по Modbus-у на 9600. Там SDC писалась еще по SPI. Двойной буфер, само собой, да еще SPI-ый FROM набирался и сбрасывался на карточку. Писались только изменения в регистрах оборудования, поэтому поток был небольшой. 12 устройств по 100 регистров с частотой опроса раз с 100мс. Так что )))
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.04.2017, 13:22
Помогаю со студенческими работами здесь

STM32L151 + SDIO + DMA
Имеется девайс на STM32T151RD и SD карта. Посколько у этого процессора есть SDIO, решил подключить через него, а т.к. оставались свободные...

Чтение SD карты через SDIO с DMA
Доброго времени суток. Есть STM32f103 с подключенной по SDIO карточкой. Сейчас читается в обычном режиме (POLLING), думаю перевести на...

SDIO + DMA странное поведение при ресете
Конфигурация: STM32F103RET6, IAR К нему подключена SD карта по интерфейсу SDIO Для общения с SD используется либа от ST из примеров...

STM32F407 и I2S, DMA
Здравствуйте! 1) написал инициализацию I2S для STM32F407 и получил странный результат - мне нужно, чтобы процессор генерил сигнал...

stm32f407 1-wire+DMA
Всем доброго времени суток столкнулся с проблемой при работе с 1-wire; Проблема заключается в следующем DMA не правильно считывает данные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
Отображение реквизитов в документе по условию и контроль их заполнения
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеСпецтехники", разработанного в конфигурации КА2. Данный документ берёт данные из другого нетипового документа. . .
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизитов табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: 1. Реализовать контроль заполнения реквизита. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru