Драйвер устройства Linux для ИС-модуля смарт-карты - PullRequest
0 голосов
/ 16 мая 2019

У меня есть IC-модуль смарт-карты, и я хочу создать для него драйвер устройства Linux. Этот модуль использует SPI в качестве управляющей линии и имеет линию прерывания, чтобы указать, готова ли карта. Я знаю, как создать устройство SPI в ядре Linux и как читать данные в ядре, когда происходит прерывание. Но я понятия не имею, как передать данные в пользовательское пространство (возможно, необходимо создать для него узел устройства) и как дать прерывание пользовательскому пространству для уведомления об этом. У кого-нибудь есть предложения?

1 Ответ

0 голосов
/ 17 мая 2019

Один из способов добиться этого - создать запись devfs, а затем заинтересованный процесс откроет это устройство и получит асинхронное уведомление от драйвера устройства с помощью fasync.

Получив уведомление в пользовательском пространстве, вы можете уведомить другие заинтересованные процессы любым удобным для вас способом.

Я пишу небольшой урезанный пример, иллюстрирующий эту функцию.

На стороне водителя

/* Appropriate headers */

static int myfasync(int fd, struct file *fp, int on);
static struct fasync_struct *fasyncQueue;

static struct file_operations fops =
{
     .open = charDriverOpen,
     .release = charDriverClose,
     .read = charDriverRead,
     .write = charDriverWrite,
     .unlocked_ioctl = charDriverCtrl,
     // This will be called when the FASYNC flag is set
     .fasync = myfasync,
};

static int __init charDriverEntry()
{
      // Appropriate init for the driver
      // Nothing specific needs to be done here with respect to
      // fasync feature.
 }

static int myfasync(int fd, struct file *fp, int on)
{
      // Register the process pointed to by fp to the list
      // of processes to be notified when any event occurs
      return fasync_helper(fd, fp, 1, &fasyncQueue);
}

// Now to the part where we want to notify the processes listed
// in fasyncQueue when something happens. Here in this example I had
// implemented the timer. Not getting in to the details of timer func
// here
static void send_signal_timerfn(unsigned long data)
{
       ...
       printk(KERN_INFO "timer expired \n");

       kill_fasync(&fasyncQueue, SIGIO, POLL_OUT);
       ...
}

На стороне пользователя наземного процесса

void my_notifier(int signo, siginfo_t *sigInfo, void *data)
{
        printf("Signal received from the driver expected %d got %d \n",SIGIO,signo);
}

int main()
{
       struct sigaction signalInfo;
       int flagInfo;

       signalInfo.sa_sigaction = my_notifier;
       signalInfo.sa_flags = SA_SIGINFO;
       sigemptyset(&signalInfo.sa_mask);

       sigaction(SIGIO, &signalInfo, NULL);


       int fp,i;
       fp = open("/dev/myCharDevice",O_RDWR);
       if (fp<0)
               printf("Failed to open\n");

       /*New we will own the device so that we can get the signal from the device*/
       // Own the process
       fcntl(fp, F_SETOWN, getpid());
       flagInfo = fcntl(fp, F_GETFL);
       // Set the FASYNC flag this triggers the fasync fops 
       fcntl(fp, F_SETFL, flagInfo|FASYNC);
       ...
}

Надеюсь, это прояснит ситуацию. Для более подробного прочтения предлагаю вам прочитать this

...