Имеются следующие элементы:
1. Процессор BF533
2. Отладочная плата ADSP-BF533 STAMP rev1.1
3. GNU/Linux, версия ядра 3.0.8 ( blackfin-linux-dist-2011R1-RC3) скачаный с офф. сайта AnalogDev.
На текущем этапе необходимо отладить прием/передачу по SPORT.
Одна утилита непрерывно пишет в /dev/sport1 сообщение из 4 байтов, а вторая непрерывно читает с /dev/sport0 в буфер размером 1024 байта. В двух программах задействован режим DMA.
Соединены они на отладочной плате следующим образом: TCLK1 -> RCLK0, TFS1->RFS0, DT1PRI->DR0PRI.
Суть проблемы:
Судя по выводу отладочной информации драйвера sport (bfin_sport.c) программа записи отрабатывает нормально. Но вот с программой чтения как раз возникли проблемы. При ее запуске она 1 раз отрабатывает цикл чтения (в не зависимости записываются ли данные программой записи в /dev/sport1), второй раз пытается отработать, но виснет на функции в драйверe wait_for_completion_interruptible (функция работы шедуллера) (данный факт был выяснен путем отладки драйвера), но что самое интересное, прерывания на прием ни разу не срабатывают
Из-за чего возникают вопросы:
1. Почему и как один раз отрабатывается цикл чтения ?
2. Почему не срабатывает прерывания по приему (выяснено путем отладочных сообщений)?
Код программ и диагностические выводы драйвером приведены ниже.
Программа записи в /dev/sport1:
Код
#include <errno.h>
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "bfin_sport.h"
#define DEFAULT_SPORT "/dev/sport1"
#define sport_name DEFAULT_SPORT
int main(int argc, char *argv)
{
int sport_fd;
struct sport_config config;
int i;
unsigned char *buffer;
sport_fd = open(sport_name, O_RDWR, 0);
if (sport_fd < 0)
{
printf("Error open file %s\n", sport_name);
return 0;
}
memset(&config, 0, sizeof(struct sport_config));
printf("Cleaning of the structure sport_config\n");
config.mode = NORM_MODE; //normal mode
config.data_format = NORM_FORMAT;
config.act_low = 1;
config.lsb_first = 0;
config.int_clk = 1;
config.fsync = 1;
config.word_len = 32;
config.dma_enabled = 1;
config.sec_en = 0;
config.serial_clk=500000;
config.tckfe = 0;
config.frame_delay = 0;
config.late_fsync = 1;
if (ioctl(sport_fd, SPORT_IOC_CONFIG, &config) < 0)
{
printf("ioctl('%s', SPORT_IOC_CONFIG) failed", sport_name);
goto exit;
}
printf("Configure sport %s\n", sport_name);
while(1)
{
write(sport_fd, "abcd", 4);
}
exit:
close(sport_fd);
printf("File %s is closed\n", sport_name);
return 0;
}
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "bfin_sport.h"
#define DEFAULT_SPORT "/dev/sport1"
#define sport_name DEFAULT_SPORT
int main(int argc, char *argv)
{
int sport_fd;
struct sport_config config;
int i;
unsigned char *buffer;
sport_fd = open(sport_name, O_RDWR, 0);
if (sport_fd < 0)
{
printf("Error open file %s\n", sport_name);
return 0;
}
memset(&config, 0, sizeof(struct sport_config));
printf("Cleaning of the structure sport_config\n");
config.mode = NORM_MODE; //normal mode
config.data_format = NORM_FORMAT;
config.act_low = 1;
config.lsb_first = 0;
config.int_clk = 1;
config.fsync = 1;
config.word_len = 32;
config.dma_enabled = 1;
config.sec_en = 0;
config.serial_clk=500000;
config.tckfe = 0;
config.frame_delay = 0;
config.late_fsync = 1;
if (ioctl(sport_fd, SPORT_IOC_CONFIG, &config) < 0)
{
printf("ioctl('%s', SPORT_IOC_CONFIG) failed", sport_name);
goto exit;
}
printf("Configure sport %s\n", sport_name);
while(1)
{
write(sport_fd, "abcd", 4);
}
exit:
close(sport_fd);
printf("File %s is closed\n", sport_name);
return 0;
}
Программа чтения /dev/sport0:
Код
#include <errno.h>
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "bfin_sport.h"
#define DEFAULT_SPORT "/dev/sport0"
#define sport_name DEFAULT_SPORT
#define BUF_LEN 1024
int main(int argc, char *argv)
{
int sport_fd;
int ret;
struct sport_config config;
unsigned char *buffer;
sport_fd = open(sport_name, O_RDWR, 0);
if (sport_fd < 0)
{
printf("Error open file %s\n", sport_name);
return 0;
}
memset(&config, 0, sizeof(struct sport_config));
printf("Cleaning of the structure sport_config\n");
if ((buffer = malloc(BUF_LEN)) == NULL)
{
printf("Error malloc buffer\n");
goto exit;
}
printf("Malloc is finish\n");
config.mode = NORM_MODE; //normal mode
config.data_format = NORM_FORMAT;
config.lsb_first = 0; //
config.int_clk = 0; //internal clk
config.fsync = 1;
config.late_fsync = 0;
config.word_len = 32;
config.dma_enabled = 1;
config.act_low = 1; //активный низкий уровень кадровой синхронизации
config.sec_en = 0; //задействовать второй канал
config.tckfe = 0; //выбор фронта
config.frame_delay = 0;
if (ioctl(sport_fd, SPORT_IOC_CONFIG, &config) < 0)
{
printf("ioctl('%s', SPORT_IOC_CONFIG) failed", sport_name);
goto exit;
}
while(1)
{
ret = read(sport_fd, buffer, BUF_LEN);
if (ret < 0)
{
printf("Error read %s file\n", sport_name);
goto exit;
}
printf("read from %s file: len - %2d result - %2d byte1 %02x byte2 %02x byte3 %02x\n ", sport_name, BUF_LEN, ret, buffer[0], buffer[1], buffer[2]);
}
free(buffer);
exit:
close(sport_fd);
printf("File %s is closed\n", sport_name);
return 0;
}
#include <stdio.h>
#include <malloc.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "bfin_sport.h"
#define DEFAULT_SPORT "/dev/sport0"
#define sport_name DEFAULT_SPORT
#define BUF_LEN 1024
int main(int argc, char *argv)
{
int sport_fd;
int ret;
struct sport_config config;
unsigned char *buffer;
sport_fd = open(sport_name, O_RDWR, 0);
if (sport_fd < 0)
{
printf("Error open file %s\n", sport_name);
return 0;
}
memset(&config, 0, sizeof(struct sport_config));
printf("Cleaning of the structure sport_config\n");
if ((buffer = malloc(BUF_LEN)) == NULL)
{
printf("Error malloc buffer\n");
goto exit;
}
printf("Malloc is finish\n");
config.mode = NORM_MODE; //normal mode
config.data_format = NORM_FORMAT;
config.lsb_first = 0; //
config.int_clk = 0; //internal clk
config.fsync = 1;
config.late_fsync = 0;
config.word_len = 32;
config.dma_enabled = 1;
config.act_low = 1; //активный низкий уровень кадровой синхронизации
config.sec_en = 0; //задействовать второй канал
config.tckfe = 0; //выбор фронта
config.frame_delay = 0;
if (ioctl(sport_fd, SPORT_IOC_CONFIG, &config) < 0)
{
printf("ioctl('%s', SPORT_IOC_CONFIG) failed", sport_name);
goto exit;
}
while(1)
{
ret = read(sport_fd, buffer, BUF_LEN);
if (ret < 0)
{
printf("Error read %s file\n", sport_name);
goto exit;
}
printf("read from %s file: len - %2d result - %2d byte1 %02x byte2 %02x byte3 %02x\n ", sport_name, BUF_LEN, ret, buffer[0], buffer[1], buffer[2]);
}
free(buffer);
exit:
close(sport_fd);
printf("File %s is closed\n", sport_name);
return 0;
}
Вывод драйвера sport при записи:
Код
[ 1246.647762] sport_open enter
[ 1246.655895] sport_ioctl: enter, arg:0x2995e9c
[ 1246.680058] tcr1:0x3602, tcr2:0x1f, rcr1:0x3602, rcr2:0x1f
[ 1246.680084] mcmc1:0x0, mcmc2:0x0, mtcs0:0x0, mrcs0:0x0
[ 1246.701700] sport_write count:4 dma_tx_chan:4
[ 1246.710778] DMA mode
[ 1246.715472] dma_tx_irq_handler enter
[ 1246.722672] dma_tx_irq_handler status:40
[ 1246.731017] dma_tx_irq_handler enter
[ 1246.738222] dma_tx_irq_handler status:40
[ 1246.746613] wait for transfer finished
[ 1246.754385] waiting over
[ 1246.759724] sport_write count:4 dma_tx_chan:4
[ 1246.768804] DMA mode
[ 1246.773505] dma_tx_irq_handler enter
[ 1246.780704] dma_tx_irq_handler status:40
[ 1246.789023] dma_tx_irq_handler enter
[ 1246.796228] dma_tx_irq_handler status:40
[ 1246.804623] wait for transfer finished
[ 1246.812363] waiting over
[ 1246.817696] sport_write count:4 dma_tx_chan:4
[ 1246.826801] DMA mode
[ 1246.831487] dma_tx_irq_handler enter
[ 1246.838686] dma_tx_irq_handler status:40
[ 1246.847026] dma_tx_irq_handler enter
[ 1246.854231] dma_tx_irq_handler status:40
[ 1246.862620] wait for transfer finished
[ 1246.870394] waiting over
[ 1246.875734] sport_write count:4 dma_tx_chan:4
[ 1246.655895] sport_ioctl: enter, arg:0x2995e9c
[ 1246.680058] tcr1:0x3602, tcr2:0x1f, rcr1:0x3602, rcr2:0x1f
[ 1246.680084] mcmc1:0x0, mcmc2:0x0, mtcs0:0x0, mrcs0:0x0
[ 1246.701700] sport_write count:4 dma_tx_chan:4
[ 1246.710778] DMA mode
[ 1246.715472] dma_tx_irq_handler enter
[ 1246.722672] dma_tx_irq_handler status:40
[ 1246.731017] dma_tx_irq_handler enter
[ 1246.738222] dma_tx_irq_handler status:40
[ 1246.746613] wait for transfer finished
[ 1246.754385] waiting over
[ 1246.759724] sport_write count:4 dma_tx_chan:4
[ 1246.768804] DMA mode
[ 1246.773505] dma_tx_irq_handler enter
[ 1246.780704] dma_tx_irq_handler status:40
[ 1246.789023] dma_tx_irq_handler enter
[ 1246.796228] dma_tx_irq_handler status:40
[ 1246.804623] wait for transfer finished
[ 1246.812363] waiting over
[ 1246.817696] sport_write count:4 dma_tx_chan:4
[ 1246.826801] DMA mode
[ 1246.831487] dma_tx_irq_handler enter
[ 1246.838686] dma_tx_irq_handler status:40
[ 1246.847026] dma_tx_irq_handler enter
[ 1246.854231] dma_tx_irq_handler status:40
[ 1246.862620] wait for transfer finished
[ 1246.870394] waiting over
[ 1246.875734] sport_write count:4 dma_tx_chan:4
Вывод драйвера при чтении
Код
[ 41.663454] sport_ioctl: enter, arg:0x29b5e94
[ 41.687633] tcr1:0x1400, tcr2:0x1f, rcr1:0x1400, rcr2:0x1f
[ 41.687659] mcmc1:0x0, mcmc2:0x0, mtcs0:0x0, mrcs0:0x0
[ 41.710440] sport_read count:1024
[ 41.759880] DMA mode read
[ 41.798458] Complete called in dma rx irq handler
[ 41.809939] sport_read count:1024
[ 41.859234] DMA mode read
[ 41.687633] tcr1:0x1400, tcr2:0x1f, rcr1:0x1400, rcr2:0x1f
[ 41.687659] mcmc1:0x0, mcmc2:0x0, mtcs0:0x0, mrcs0:0x0
[ 41.710440] sport_read count:1024
[ 41.759880] DMA mode read
[ 41.798458] Complete called in dma rx irq handler
[ 41.809939] sport_read count:1024
[ 41.859234] DMA mode read
Заранее спасибо за любую помощь!
ЗЫ: Если у кого нибудь есть наверняка рабочий пример чтения данных из sport'a, c удовольствием ознакомлюсь