将UART0_RX转为GPIO或PWM,发现通过*vir_gpioA17_dr&=~(1<<17);无法控制GPIO,但通过终端使用echo命令却可以控制GPIO的电平,我不清楚是哪里出了问题 。我用类似的方法可以控制GPIOA14 。
//pwm_kernel.c
#include "linux/init.h"
#include "linux/module.h"
#include "linux/miscdevice.h"
#include "linux/fs.h"
#include "linux/uaccess.h"
#include "linux/io.h"
#define FMUX_GPIO_REG_IOCTRL_UART0_RX 0x03001044
#define GPIOA_DDR (0x03020000+0x000)
#define GPIOA_DR (0x03020000+0x004)
unsigned int *vir_mux;
unsigned int *vir_gpioA17_ddr;
unsigned int *vir_gpioA17_dr;
ssize_t pwm_read(struct file *file, char __user *user_buf, size_t size, loff_t * loff){
return 0;
}
ssize_t pwm_write(struct file *file, const char __user *user_buf, size_t size, loff_t * loff){
char kernel_buf[64]={0};
printk("led_write\n");
if(copy_from_user(kernel_buf,user_buf,size)!=0) {
printk("copy_from_user error\n");
return -1;
}else {
if (kernel_buf[0]=='1') {
*vir_gpioA17_dr|=(1<<17);
}else if(kernel_buf[0]=='0') {
*vir_gpioA17_dr&=~(1<<17);
}
return 0;
}
}
int pwm_open(struct inode *inode, struct file *file){
return 0;
}
int pwm_release(struct inode *inode, struct file *file){
return 0;
}
struct file_operations pwm_fops={
.owner=THIS_MODULE,
.write=pwm_write,
.read=pwm_read,
.open=pwm_open,
.release=pwm_release
};
static struct miscdevice pwm_dev={
.minor=MISC_DYNAMIC_MINOR,
.fops=&pwm_fops,
.name="pwm_led_dev"
};
static int __init pwm_init(void){
printk("pwm_init\n");
if(misc_register(&pwm_dev)<0){
printk("misc_register error\n");
return -1;
} else{
printk("misc_register succeed\n");
vir_mux=ioremap(FMUX_GPIO_REG_IOCTRL_UART0_RX,4);
vir_gpioA17_ddr=ioremap(GPIOA_DDR,4);
vir_gpioA17_dr=ioremap(GPIOA_DR,4);
if(vir_mux==NULL||vir_gpioA17_ddr==NULL||vir_gpioA17_dr==NULL){
printk("ioremap error\n");
return -1;
} else{
printk("ioremap succeed\n");
}
writel(3,vir_mux);
*vir_gpioA17_ddr|=(1<<17);
*vir_gpioA17_dr&=~(1<<17);
return 0;
}
}
static void __exit pwm_exit(void){
printk("pwm_exit\n");
misc_deregister(&pwm_dev);
iounmap(vir_mux);
iounmap(vir_gpioA17_ddr);
iounmap(vir_gpioA17_dr);
}
MODULE_LICENSE("GPL");
module_init(pwm_init);
module_exit(pwm_exit);
#include "stdio.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[]){
int fd= open("/dev/pwm_led_dev",O_RDWR);
if(fd<0){
perror("open error");
return -1;
} else{
write(fd,argv[1],sizeof(argv[1]));
close(fd);
return 0;
}
}