리눅스 임베디드 보드 (imx233 기반)와 MSP430 MCU를 연결합니다. 그들은 4 핀 SPI를 통해 연결되지만 Linux 보드의 칩 선택 목적을 위해 GPIO를 사용합니다. 내가하는 일은 다음 코드 위 중 ioctl
또는 read()
read()/ioctl은 GPIO 신호를 방해합니까?
int main(void)
{
/********************************LINUX SCHEDULING**********************************/
sp.sched_priority = sched_get_priority_max(SCHED_FIFO); //scheduling
sched_setscheduler(0, SCHED_FIFO, &sp); //scheduling
/********************************LINUX SCHEDULING_END******************************/
struct pollfd fdset[2]; //declare the poll to be used in interrupt catching
int nfds = 2;
int gpio_fd, timeout, rc;
char *buf[MAX_BUF]; //max=64byte
int len;
initialize(); //gpio's are set to SPI_SLAVE
// spi_init();
gpio_fd = gpio_fd_open(CHIP_SELECT_PIN); //the CS(SS) pin is opened
timeout = POLL_TIMEOUT; //timeout 3 sec is set
// uint8_t voidFirstDetection = 1;
while (1) {
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = NULL;
fdset[0].events = POLLIN;
fdset[1].fd = gpio_fd;
fdset[1].events = POLLPRI;
/*** POLL starts to detect chipselects****/
rc = poll(fdset, nfds, timeout);
if (rc < 0) {
printf("\npoll() failed!\n");
return -1;
}
if (rc == 0) {
printf(".");
}
if (fdset[1].revents & POLLPRI) { //HERE I need to run SPI_read
len = read(fdset[1].fd, buf, MAX_BUF);
/* if(voidFirstDetection){
voidFirstDetection = 0;
}else{*/
printf("\npoll() GPIO %d interrupt occurred\n", CHIP_SELECT_PIN);
int fd = open(device, O_RDWR);
if (fd < 0){
// snprintf(systemlogmsg, sizeof(systemlogmsg), "[1181]: errno:%s Cannot open /dev/spidev ", strerror(errno));
// error_logging(systemlogmsg, LOGLEVEL_ERROR);
printf("error spi recive\n");
}
//spi_transfer(fd);
do_read(fd);
close(fd);
// }
}
}
gpio_fd_close(gpio_fd);
return 0;
}
는 신호의 하강 에지에서이 인터럽트를 생성하는 잘 작동 읽는 SPI를 수행 (52 NR)가 GPIO의 하강 에지를 검출하기 위해 설문 조사를 사용하는 것입니다 . 인터럽트 spi_transfer()
또는 do_read()
에 status = read(fd, buf, len);
에 ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
라인 중 하나가 실행될 때마다, I는 GPIO52에 인터럽트를 검출하는 무한 루프를 참조 /dev/spidev1-0
static void do_read(int fd)
{
unsigned char buf[1], *bp;
int status;
int len = 1;
/* read at least 2 bytes, no more than 32 */
memset(buf, 0, sizeof buf);
status = read(fd, buf, len);
if (status < 0) {
perror("read");
return;
}
if (status != len) {
fprintf(stderr, "short read\n");
return;
}
printf("read(%2d, %2d): %02x %02x,", len, status,
buf[0], buf[1]);
status -= 2;
bp = buf + 2;
while (status-- > 0)
printf(" %02x", *bp++);
printf("\n");
}
static void spi_transfer(int fd)
{
int ret;
uint8_t tx[2];
uint8_t rx[3] = {0 };
struct spi_ioc_transfer tr = {
.tx_buf = 0,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1){
printf("can't send spi message");
exit(1);
}
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
if (!(ret % 6))
puts("");
printf("%.2X ", rx[ret]);
}
puts("");
}
를 읽어 검출되면 나도 아래의 코드를 사용하여 (칩 선택). 나는 오실로스코프를 통해 GPIO를 관찰하려고 노력했지만, 신호 선택 (오실로스코프가 감지 할 수없는 스파이크 일 수 있음)을 볼 수 없었습니다. 그러나 Vcc에 chipselect를 연결하면 무한 루프가 발생하지 않습니다. 내가 초기 단계에있을 때, MCU의 GPIO 중 하나를 출력으로하고 일정한 로직 하이로 설정했다. 내 목표는 MCU에서 리눅스 보드로 데이터를 전송하기 때문에 입력으로 GPIO52 (칩 선택)를 사용합니다.
아마도 read()
과 ioctl
은 GPIO가 제공하는 것보다 더 많은 전류를 싱크하도록 GPIO에 영향을 미칩니다. 그것이 문제라면, ioctl이나 read()가 GPIO를 방해하지 않을 것입니다. 아니면 뭔가 다른 문제가 있다고 생각합니까?