- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试在 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/
我是 C 语言新手,我编写了这个 C 程序,让用户输入一年中的某一天,作为返回,程序将输出月份以及该月的哪一天。该程序运行良好,但我现在想简化该程序。我知道我需要一个循环,但我不知道如何去做。这是程序
我一直在努力找出我的代码有什么问题。这个想法是创建一个小的画图程序,并有红色、绿色、蓝色和清除按钮。我有我能想到的一切让它工作,但无法弄清楚代码有什么问题。程序打开,然后立即关闭。 import ja
我想安装screen,但是接下来我应该做什么? $ brew search screen imgur-screenshot screen
我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将
我有一个 shell 脚本,它运行一个 Python 程序来预处理一些数据,然后运行一个 R 程序来执行一些长时间运行的任务。我正在学习使用 Docker 并且我一直在运行 FROM r-base:l
在 Linux 中。我有一个 c 程序,它读取一个 2048 字节的文本文件作为输入。我想从 Python 脚本启动 c 程序。我希望 Python 脚本将文本字符串作为参数传递给 c 程序,而不是将
对于一个类,我被要求编写一个 VHDL 程序,该程序接受两个整数输入 A 和 B,并用 A+B 替换 A,用 A-B 替换 B。我编写了以下程序和测试平台。它完成了实现和行为语法检查,但它不会模拟。尽
module Algorithm where import System.Random import Data.Maybe import Data.List type Atom = String ty
我想找到两个以上数字的最小公倍数 求给定N个数的最小公倍数的C++程序 最佳答案 int lcm(int a, int b) { return (a/gcd(a,b))*b; } 对于gcd,请查看
这个程序有错误。谁能解决这个问题? Error is :TempRecord already defines a member called 'this' with the same paramete
当我运行下面的程序时,我在 str1 和 str2 中得到了垃圾值。所以 #include #include #include using namespace std; int main() {
这是我的作业: 一对刚出生的兔子(一公一母)被放在田里。兔子在一个月大时可以交配,因此在第二个月的月底,每对兔子都会生出两对新兔子,然后死去。 注:在第0个月,有0对兔子。第 1 个月,有 1 对兔子
我编写了一个程序,通过对字母使用 switch 命令将十进制字符串转换为十六进制,但是如果我使用 char,该程序无法正常工作!没有 switch 我无法处理 9 以上的数字。我希望你能理解我,因为我
我是 C++ 新手(虽然我有一些 C 语言经验)和 MySQL,我正在尝试制作一个从 MySQL 读取数据库的程序,我一直在关注这个 tutorial但当我尝试“构建”解决方案时出现错误。 (我正在使
仍然是一个初学者,只是尝试使用 swift 中的一些基本函数。 有人能告诉我这段代码有什么问题吗? import UIKit var guessInt: Int var randomNum = arc
我正在用 C++11 编写一个函数,它采用 constant1 + constant2 形式的表达式并将它们折叠起来。 constant1 和 constant2 存储在 std::string 中,
我用 C++ 编写了这段代码,使用运算符重载对 2 个矩阵进行加法和乘法运算。当我执行代码时,它会在第 57 行和第 59 行产生错误,非法结构操作(两行都出现相同的错误)。请解释我的错误。提前致谢:
我是 C++ 的初学者,我想编写一个简单的程序来交换字符串中的两个字符。 例如;我们输入这个字符串:“EXAMPLE”,我们给它交换这两个字符:“E”和“A”,输出应该类似于“AXEMPLA”。 我在
我需要以下代码的帮助: 声明 3 个 double 类型变量,每个代表三角形的三个边中的一个。 提示用户为第一面输入一个值,然后 将用户的输入设置为您创建的代表三角形第一条边的变量。 将最后 2 个步
我是新来的,如果问题不好请见谅 任务:将给定矩阵旋转180度 输入: 1 4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 输出: 16 15 14 13 12 11
我是一名优秀的程序员,十分优秀!