gpt4 book ai didi

c# - 使用单声道等待 UIO 中断

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:25:00 25 4
gpt4 key购买 nike

我的问题是如何使用单声道等待 UIO 驱动程序生成的中断。我已经为嵌入式系统创建了一个 UIO 驱动程序,它将在按下 gpio 按钮之前阻止读取,我已经用 C 程序对其进行了测试并且它可以工作。它是如何通过简单地读取/dev/uioX 文件来完成的,一旦收到中断,阻塞读取就会被释放。我想做同样的事情,但如果有人可以帮助我,我会使用 C#,非常感谢。

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>

static void *base_address;
#define GPIO_DATA_OFFSET 0x00
#define GPIO_TRI_OFFSET 0x04
#define GPIO_DATA2_OFFSET 0x08
#define GPIO_TRI2_OFFSET 0x0C
#define GPIO_GLOBAL_IRQ 0x11C
#define GPIO_IRQ_CONTROL 0x128
#define GPIO_IRQ_STATUS 0x120

#define GLOBAL_INTERRUPT_ENABLE 0x80000000
#define GLOBAL_INTERRUPT_DISABLE 0x0
#define IP_INTERRUPT_ENABLE 0x1
#define IP_INTERRUPT_DISABLE 0x0
#define INTERRUPT_CLEAR 0x1

/* GLOBAL VATIABLES */

char* uioFile;
char uioNumber;

/* END GLOBALS */

inline void disable_interrupt()
{
*((volatile unsigned *)(base_address + GPIO_GLOBAL_IRQ)) = GLOBAL_INTERRUPT_DISABLE;
*((volatile unsigned *)(base_address + GPIO_IRQ_CONTROL)) = IP_INTERRUPT_DISABLE;
}
inline void enable_interrupt()
{
*((volatile unsigned *)(base_address + GPIO_GLOBAL_IRQ)) = GLOBAL_INTERRUPT_ENABLE;
*((volatile unsigned *)(base_address + GPIO_IRQ_CONTROL)) = IP_INTERRUPT_ENABLE;
}

inline void clear_interrupt()
{
*((volatile unsigned *)(base_address + GPIO_IRQ_STATUS)) = INTERRUPT_CLEAR;
}

unsigned int gpio_read(void *gpio_base, unsigned int offset)
{
return *((unsigned *)(gpio_base + offset));
}

void wait_for_interrupt(int fd)
{
int pending = 0;
int reenable = 1;
unsigned int reg;

/* block on the file waiting for an interrupt */

read(fd, (void *)&pending, sizeof(int));

reg = gpio_read(gpio_ptr, GPIO_IRQ_STATUS);
if (reg)
clear_interrupt();

/* re-enable the interrupt again now that it's been handled */

write(fd, (void *)&reenable, sizeof(int));
}

unsigned int get_memory_size()
{
FILE *size_fp;
unsigned int size;
char* filePath;

/* open the file that describes the memory range needed to map the GPIO into
* this address space, this is the range of the GPIO in the device tree
*/
size_fp = fopen("/sys/class/uio/uio0/maps/map0/size", "r");
if (!size_fp) {
printf("unable to open the %s size file\n", filePath);
exit(-1);
}

/* Get the size which is an ASCII string such as 0xXXXXXXXX and then be stop
* using the file
*/
fscanf(size_fp, "0x%08X", &size);
fclose(size_fp);

return size;
}

int main(int argc, char *argv[])
{
int fd;
unsigned int size;

printf("UIO test\n");

/* open the UIO device file to allow access to control the device */

fd = open("/dev/uio0", O_RDWR);
if (fd < 1) {
printf("Unable to open %s device file", uioFile);
return -1;
}

/* get the size of the memory to be mapped into this process address space
* and then map it in such that the device memory is accessible
*/
size = get_memory_size();
base_address = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

enable_interrupt();
printf("Enabled Interrupt, waiting for the interrupt\n");

wait_for_interrupt(fd);
printf("interrupt complete\n");

munmap(base_address, size);
close(fd);

return 0;
}

最佳答案

根据 this documentation , 读取 4 个字节 block 直到中断并为您提供中断计数作为 32 位整数。

using (FileStream f = new FileStream("/dev/uioX", FileMode.Open, FileAccess.Read, FileShare.Read))
using (BinaryReader reader = new BinaryReader(f))
{
int interruptCount = reader.ReadInt32();
}

如果所有其他方法都失败了,您始终可以使用 Mono.Posix dll 下降到 native 方法。

using System;
using System.Runtime.InteropServices;
using Mono.Unix.Native;

static class Test
{
static int WaitForInterrupt()
{
byte[] buffer = new byte[4];
GCHandle hBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);

int fd = Syscall.open("/dev/uioX", OpenFlags.O_RDONLY);
long result = Syscall.read(fd, hBuffer.AddrOfPinnedObject(), Convert.ToUInt64(buffer.Length));
Syscall.close(fd);

hBuffer.Free();

return BitConverter.ToInt32(buffer, 0);
}
}

关于c# - 使用单声道等待 UIO 中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36633752/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com