接着分析下半部分ARM等待DSP的中断
// 等待结束信号,即等待DSP触发ARM的中断
IRQEvent *event = irq_event_new("/dev/input/c674x_irq_events");(1)
uint32_t line
assert(irq_event_wait(event, &line) && line == EVENT_LINE_0_ARM);(2)
irq_event_destroy(event);(3)
// 从共享内存中读出内容,存到freq_buffer数组里
float freq_buffer[1024];
memcpy(freq_buffer, data, SR_buffer_size(buffer));
SR_buffer_destroy(buffer);
IRQEvent *event = irq_event_new("/dev/input/c674x_irq_events");(1)
在加载c674x-irq-events.ko驱动后,就可以生成生成/dev/input/c674x_irq_events的设备节点了。
IRQEvent *irq_event_new(const char *dev) {
IRQEvent *event = (IRQEvent *)calloc(1, sizeof(IRQEvent));
/*以只读的方式打开/dev/input/c674x_irq_events该设备节点,并指向event->fd*/
event->fd = open(dev, O_RDONLY);
if (event->fd < 0) {
fprintf(stderr, "fail to open %s
", dev);
}
return event;
}
IRQEvent 是一个结构体,它的内容如下:
struct _IRQEvent {
int fd;
};
assert(irq_event_wait(event, &line) && line == EVENT_LINE_0_ARM);(2)
bool irq_event_wait(IRQEvent *event, uint32_t *line) {
assert(event);
if (event->fd < 0) {
fprintf(stderr, "fail to wait event by previous error
");
return false;
}
// wait event
int i = 0;
for (i = 0; i < 4; i++) {
fd_set input;
/*将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在
系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。*/
FD_ZERO(&input);
/*;用于在文件描述符集合中增加一个新的文件描述符。*/
FD_SET(event->fd, &input);
/*检查input是否可读,不需要监测可写的或者异常的描述符,且超时设置为NULL,select将一直阻塞,直到
某个文件描述符上发生了事件*/
int ret = select(event->fd + 1, &input, NULL, NULL, NULL);
if (ret < 0) {
fprintf(stderr, "fail to wait event : %s
", strerror(errno));
return false;
}
// read event
struct input_event buf;
/*将buf整个清零*/
memset(&buf, 0, sizeof(struct input_event));
/*将从event->fd中读到的内容存到buf中*/
if (read(event->fd, &buf, sizeof(struct input_event)) < 0) {
fprintf(stderr, "fail to read event : %s
", strerror(errno));
return false;
}
if (i == 0) { // 一次只能处理一个中断,
/*后续还可能有KEY_PROG3、KEY_PROG4的处理,但目前只用到前两个*/
switch(buf.code) {
case KEY_PROG1:
*line = EVENT_LINE_0_ARM; break;
case KEY_PROG2:
*line = EVENT_LINE_1_ARM; break;
default:
fprintf(stderr, "unexpected key code");
return false;
}
}
}
return true;//表示接收到了中断
}
综上,(2)的作用就是表示收到了中断,且是中断0。
(3)的作用是关闭相应的文件描述符,释放内存。
void irq_event_destroy(IRQEvent *event) {
if (! event)
return;
close(event->fd);
free(event);
}