gpt4 book ai didi

c - 某种事件驱动程序

转载 作者:太空宇宙 更新时间:2023-11-04 12:24:33 25 4
gpt4 key购买 nike

我正在尝试在 Raspberry pi 3 中制作一个 Linux 内核驱动程序,当按下操纵杆中的按钮时它会打开 LED(将 GPIO 设置为输出然后将其设置为打开状态)并读取该 GPIO 的状态端口。

我打开 LED 的驱动程序是:

#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/slab.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#define ioaddress_SIE_BASE 0x3F200000
#define ioaddress_SIZE 0x38
#define address_LED_on 0x1C
#define address_LED_off 0x28
#define address_LED_estado 0x34
MODULE_LICENSE("Dual BSD/GPL");
static char *nombre="4led";
static unsigned int PrimerMenor=0;
static unsigned int cuenta=1;
static dev_t led_dev_numero;
char *buffer;
int on_off=0;
int leido=0;
static void __iomem *ioaddress_SIE;
struct led_dev *led_dev_puntero;

struct led_dev {
struct cdev led_cdev;
};
int led_open (struct inode *puntero_inode, struct file *puntero_file)
{
struct led_dev *led_dev_puntero;
printk (KERN_INFO "led_SIE: se ha abierto el dispositivo \n" );
led_dev_puntero=container_of(puntero_inode->i_cdev, struct led_dev, led_cdev);
puntero_file->private_data=led_dev_puntero;
return 0;
}

int led_release (struct inode *puntero_inode , struct file *puntero_file)
{
printk (KERN_INFO "led_SIE: se ha liberado el dispositivo \n" );
return 0;
}

static ssize_t led_read (struct file *puntero_file , char *buffer_user, size_t tamano, loff_t *puntero_offset)
{
unsigned int estado;
unsigned long prueba;
printk (KERN_INFO "led_SIE: leyendo el dispositivo \n" );
iowrite32(0x00000000, ioaddress_SIE);
estado=ioread32(ioaddress_SIE + address_LED_estado);

printk("led_SIE: GPIOs 9 to 0 --> 0x%X \n", estado);

*buffer=(char ) (estado >> leido );

prueba=copy_to_user(buffer_user, buffer, 1);
printk("led_SIE: GPIOs 9 to 0 --> 0x%X \n", *buffer);

if(leido>23){
leido=0;}
else
leido=leido+8;
return 1;
}


static ssize_t led_write (struct file *puntero_file , const char *buffer_user, size_t tamano, loff_t *puntero_offset)
{
unsigned long prueba;
/*printk(KERN_INFO "led_SIE: escribiendo en el dispositivo \n");
if(buffer_user[0]!='1'){
if(buffer_user[0]!='0'){
printk(KERN_INFO "led_SIE: Ha ingresado una orden incorrecta! \n");
printk(KERN_INFO "led_SIE: Las ordenes son: 1 para encender, 0 para apagar \n");
return tamano;
}
}*/

prueba=copy_from_user(buffer, buffer_user, tamano);

printk(KERN_INFO "led_SIE: SE escribió %c en el dispositivo \n", buffer);
/*ibuffer_user=(int)buffer_user;*/
/*printk(ibuffer_user);
int ibuffer = (int) buffer;*/
/*if(buffer_user=='1'){
printk(KERN_INFO "Lee maldita sea \n");
}*/
switch(buffer[0]){
case '1':
if(on_off==1){
printk(KERN_INFO "led_SIE: El led ya se encuentra encendido \n");
return tamano;
}
on_off=1;
iowrite32(0x00009240, ioaddress_SIE);
iowrite32(0x00000004, ioaddress_SIE + address_LED_on);
iowrite32(0x00000038, ioaddress_SIE + address_LED_off);
break;

case '2':
if(on_off==2){
printk(KERN_INFO "led_SIE: El led ya se encuentra encendido \n");
return tamano;
}
on_off=2;
iowrite32(0x00009240, ioaddress_SIE);
iowrite32(0x00000008, ioaddress_SIE + address_LED_on);
iowrite32(0x00000034, ioaddress_SIE + address_LED_off);
break;

case '3':
if(on_off==3){
printk(KERN_INFO "led_SIE: El led ya se encuentra encendido \n");
return tamano;
}
on_off=3;
iowrite32(0x00009240, ioaddress_SIE);
iowrite32(0x00000010, ioaddress_SIE + address_LED_on);
iowrite32(0x0000002C, ioaddress_SIE + address_LED_off);
break;

case '4':
if(on_off==4){
printk(KERN_INFO "led_SIE: El led ya se encuentra encendido \n");
return tamano;
}
on_off=4;
iowrite32(0x00009240, ioaddress_SIE);
iowrite32(0x00000020, ioaddress_SIE + address_LED_on);
iowrite32(0x0000001C, ioaddress_SIE + address_LED_off);

break;
case '0':
if(on_off==0){
printk(KERN_INFO "led_SIE: El led ya se encuentra apagado \n");
return tamano;
}
on_off=0;
iowrite32(0x00009240, ioaddress_SIE);
iowrite32(0x0000003C, ioaddress_SIE + address_LED_off);
break;
default:
return tamano;
}
return tamano;
}


struct file_operations led_fops = {

.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
.open = led_open,
.release = led_release
};

static int hello_init(void)
{
int resultado, error;

printk(KERN_ALERT "Hola, mundo\n");
resultado=alloc_chrdev_region(&led_dev_numero, PrimerMenor, cuenta, nombre);
if (resultado ==0)
printk(KERN_INFO "Se reservaron los siguientes numeros \n Mayor: %d\n Menor: %d\n", MAJOR(led_dev_numero), MINOR(led_dev_numero));
else
printk(KERN_INFO "Hubo un error y los numeros no se reservaron. Error: %d\n", resultado);

led_dev_puntero = kmalloc (sizeof(struct led_dev), GFP_ATOMIC);
buffer=kmalloc(8,GFP_ATOMIC);//GFP_KERNEL---Difícil
cdev_init(&led_dev_puntero->led_cdev, &led_fops);
led_dev_puntero->led_cdev.owner=THIS_MODULE;
led_dev_puntero->led_cdev.ops=&led_fops;
error=cdev_add(&led_dev_puntero->led_cdev, led_dev_numero, cuenta);
if(error)
printk (KERN_INFO "error $d al anadir led_dev");
ioaddress_SIE=ioremap(ioaddress_SIE_BASE, ioaddress_SIZE);
printk(KERN_ALERT "ioadress_SIE_BASE fue mapeado a: %p \n", ioaddress_SIE);
return 0;
}
module_init(hello_init);

static void hello_exit(void)
{
printk(KERN_ALERT "Adios, mundo cruel\n");
unregister_chrdev_region(led_dev_numero,cuenta);
cdev_del(&led_dev_puntero->led_cdev);
kfree(led_dev_puntero);
kfree(buffer);
if(on_off==1){
iowrite32(0xFFFFFFFF, ioaddress_SIE + address_LED_off);
}
iounmap(ioaddress_SIE);
}

module_exit(hello_exit);

与驱动器和操纵杆交互的应用程序是:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

struct js_event {
unsigned int time; /* event timestamp in milliseconds */
short value; /* value */
unsigned char type; /* event type */
unsigned char number; /* axis/button number */
};

#define JS_EVENT_BUTTON 0x01 /* button pressed/released */
#define JS_EVENT_AXIS 0x02 /* joystick moved */
#define JS_EVENT_INIT 0x80 /* initial state of device */

int main(int argc, char **argv)
{ //Acceso al driver Xdriv
int fd = open ("/dev/input/js0", O_RDONLY);
FILE *archivo;
int tamano;
int a;int b;

/*Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
*/

if( fd < 0 )
printf( "cannot open dev\n" );
else
printf( "opened success...:)\n" );

struct js_event e;
while( 1 ) //event loop
{
read( fd, &e, sizeof(e) );
//printf( "%d %d %d %d\n", e.time, e.value, e.type, e.number );

if( e.type == JS_EVENT_BUTTON || e.type == JS_EVENT_AXIS )
{
if( e.type == JS_EVENT_BUTTON ){
printf( "button#%d value:%d\n", (int) e.number, e.value );

switch((int) e.number) {
case 0 ://Btn A, Motor 1---Atrás
if ((int) e.value == 1){
printf("Hola esto es 0\n Btn A, Motor 1---Atrás");
char escribe[1] = "1";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 1 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c ",*escribe);}
else{
printf("Hola esto es 0 pero no presionado\n");
}

break;

case 1 ://Btn B, Motor 1---Adelante
if ((int) e.value == 1){
printf("Hola esto es 1\n Btn B, Motor 1---Adelante");
char escribe[1] = "2";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 2 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c \n",*escribe);}
else{
printf("Hola esto es 1 pero no presionado\n");
}
break;

case 2 ://Btn X, Motor 2---Abajo
if ((int) e.value == 1){
printf("Hola esto es 2 \n Btn X, Motor 2---Abajo");
char escribe[1] = "3";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 3 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c \n",*escribe);}
else{
printf("Hola esto es 2 pero no presionado\n");
}
break;

case 3 ://Btn Y, Motor 2---Arriba
if ((int) e.value == 1){
printf("Hola esto es 3 \n Btn Y, Motor 2---Arriba");
char escribe[1] = "4";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 4 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c \n",*escribe);}
else{
printf("Hola esto es 3 pero no presionado\n");
}
break;

case 7 ://Detener
if ((int) e.value == 1){
printf("Hola esto es Start/Stop \n");
char escribe[1] = "0";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 0 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c \n",*escribe);}
else{
printf("Hola esto es 7 pero no presionado\n");
}
break;

default : /* Optional */
printf("Hola esto es default también sirve como stop\n");
char escribe[1] = "0";
//Acceso al driver 4_leds

system("sudo chmod 777 /dev/4leds");
archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}
//
fwrite(escribe ,sizeof(char) ,tamano , archivo);//Escribe 0 en driver
fclose(archivo);
sleep(3);
printf("Este es escribe :%c \n",*escribe);
}
printf("El último presionado fue: %X \n",(char) e.number);}
else{
printf( "axis#%d value:%d \n", (int) e.number, e.value );}
}
else
{
printf( "Init Events\n" );
}

}
return 0;
}

我遇到段错误,所以我认为这可能是 copy_from_user 缓冲区中的内存分配问题...但我现在不知道如何解决它。

我之前试过打开文件,然后在每个 switch case 中写入,还打开文件并在 switch case 中写入...等等。

驱动程序与另一个非事件应用程序一起工作正常。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>

int main(int argc, char **argv){

FILE *archivo;
char escribe[1];
char lee[1];
int tamano, i;
int registro=0;
int registro2=0;

tamano=1;

printf("introduzca el numero que quiere escribir: ");
scanf("%c" ,escribe);
printf("%c ",*escribe);
system("sudo chmod 777 /dev/4leds");

archivo=fopen("/dev/4leds" ,"w");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}

fwrite(escribe ,sizeof(char) ,tamano , archivo);

printf("El valor escrito fue: %c \n" , *escribe);

fclose(archivo);

sleep(3);

/*archivo=fopen("/dev/4leds", "r");
if (archivo==NULL){fputs("No existe el archivo" ,stderr); exit(1);}

for (i=0;i<4;i++)
{
registro=registro << 8;
fread(lee ,tamano*sizeof(char),1,archivo);
registro=registro | *lee;
}

registro2=registro2 | (registro << 24 & 0xFF000000);
registro2=registro2 | (registro << 8 & 0x00FF0000);
registro2=registro2 | (registro >> 8 & 0x0000FF00);
registro2=registro2 | (registro >> 24 & 0x000000FF);

printf("El valor leido es: 0x%X \n" , registro2);

fclose(archivo);*/

return 0;
}

感谢您的帮助和建议。对注释代码感到抱歉,但我正在测试驱动程序的所有部分。

最佳答案

tamano 或元素数量已声明但从未在 main() 中定义。

fwrite(escribe ,sizeof(char) ,tamano , archivo);

关于c - 某种事件驱动程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45154115/

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