mini2440 led驱动代码(原创)基于iomap<测试初始化没有问题,其它功能待开发>

#include<linux/miscdevice.h>
#include<linux/init.h>
#include<linux/module.h>
#include<linux/delay.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/io.h>

#define DEVICE_NAME "LED"
static void __iomem *led_base_addr;

#define GPBCON (*(volatile unsigned long*)(led_base_addr+0x00))//S3C2410_GPBCON
#define GPBDAT (*(volatile unsigned long*)(led_base_addr+0x04))//S3C2410_GPBDAT
#define GPBUP (*(volatile unsigned long*)(led_base_addr+0x08))//S3C2410_GPBUP
static int s3c2440_leds_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned int arg)
{
switch(cmd){
case 0:
GPBDAT &=~(1<<arg);
break;
case 1:
GPBDAT |= (1<<arg);
break;

default:
return -EINVAL;
}
}


static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.ioctl = s3c2440_leds_ioctl,
};
static struct miscdevice misc ={
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
int led_cfg_output;
led_base_addr=ioremap(0x56000010,0x60);
if(led_base_addr==NULL){
printk(KERN_ERR"Faild to remap register block\n");
return -ENOENT;
}
led_cfg_output = (GPBCON&0xFFFFFFFF)|(3<<10|3<<12|3<<14|3<<16)&(~(1<<11|1<<13|1<<15|1<<17));
GPBCON = led_cfg_output;
GPBUP = 0x1E1;
led_cfg_output = GPBDAT&0x21F;
printk("led_cfg_output:%x\n",&led_cfg_output);
GPBDAT = led_cfg_output;
ret = misc_register(&misc);
printk("GPBCTL:%x\n",GPBCON);
printk("GPBDAT:%x\n",GPBDAT);
printk("GPBUP:%x\n",GPBUP);
printk(DEVICE_NAME"\tinitialized\n");
return ret;
}

static void __exit dev_exit(void)
{
int led_cfg_output;
misc_deregister(&misc);
led_cfg_output = GPBDAT|0x1E0;
GPBDAT = led_cfg_output;
iounmap(0x56000010);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");

MODULE_AUTHOR("SKY");



//测试程序

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/ioctl.h>
int main(int argc,int **argv)
{
int fd;
unsigned char led_num=0;
unsigned char i=0;
fd=open("/dev/led",0);
if(fd<0){
printf("open led error!\n");
return 0;
}
while(1){
ioctl(fd, 0, led_num);
led_num++;
if(led_num==5)
{
sleep(1);
led_num=0;
for(i=1;i<5;i++){
ioctl(fd, 1, i);
}
}
perror("once again!\n");
sleep(1);

}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个简单的基于Linux内核的PCIe Mailbox测试用例驱动,用于测试PCIe设备与主机之间的通讯。 1.包含头文件 #include <linux/module.h> #include <linux/init.h> #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/irq.h> 2.定义PCIe设备的Vendor ID和Device ID #define VENDOR_ID 0x10EC #define DEVICE_ID 0x8168 3.定义PCIe设备的寄存器偏移量 #define MAILBOX_CTRL_REG 0x00 #define MAILBOX_STATUS_REG 0x04 #define MAILBOX_DATA_REG 0x08 4.定义PCIe设备的寄存器结构 struct mailbox_regs { u32 ctrl_reg; u32 status_reg; u32 data_reg; }; 5.定义设备驱动程序的数据结构 struct mailbox_dev { struct pci_dev *pdev; void __iomem *regs; }; 6.定义设备驱动程序的常量 #define DRIVER_NAME "mailbox_driver" 7.定义设备驱动程序的probe函数 static int mailbox_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct mailbox_dev *mdev; int ret; printk(KERN_INFO "Mailbox device detected\n"); mdev = kzalloc(sizeof(struct mailbox_dev), GFP_KERNEL); if (!mdev) { printk(KERN_ERR "Failed to allocate memory for mailbox device\n"); return -ENOMEM; } ret = pci_enable_device(pdev); if (ret) { printk(KERN_ERR "Failed to enable PCI device\n"); goto err_free; } ret = pci_request_regions(pdev, DRIVER_NAME); if (ret) { printk(KERN_ERR "Failed to request PCI regions\n"); goto err_disable; } mdev->pdev = pdev; mdev->regs = pci_iomap(pdev, 0, 0); if (!mdev->regs) { printk(KERN_ERR "Failed to map PCI IO space\n"); goto err_release; } printk(KERN_INFO "Mailbox device initialized\n"); return 0; err_release: pci_release_regions(pdev); err_disable: pci_disable_device(pdev); err_free: kfree(mdev); return ret; } 8.定义设备驱动程序的remove函数 static void mailbox_remove(struct pci_dev *pdev) { struct mailbox_dev *mdev = pci_get_drvdata(pdev); printk(KERN_INFO "Removing Mailbox device\n"); pci_iounmap(pdev, mdev->regs); pci_release_regions(pdev); pci_disable_device(pdev); kfree(mdev); } 9.定义设备驱动程序的PCIe设备ID和Vendor ID static const struct pci_device_id mailbox_id_table[] = { { PCI_DEVICE(VENDOR_ID, DEVICE_ID), }, { 0, } }; MODULE_DEVICE_TABLE(pci, mailbox_id_table); 10.定义设备驱动程序的PCIe设备驱动结构 static struct pci_driver mailbox_driver = { .name = DRIVER_NAME, .id_table = mailbox_id_table, .probe = mailbox_probe, .remove = mailbox_remove, }; 11.定义驱动程序的入口函数 static int __init mailbox_init(void) { int ret; ret = pci_register_driver(&mailbox_driver); if (ret) { printk(KERN_ERR "Failed to register Mailbox driver\n"); return ret; } printk(KERN_INFO "Mailbox driver registered\n"); return 0; } 12.定义驱动程序的出口函数 static void __exit mailbox_exit(void) { pci_unregister_driver(&mailbox_driver); printk(KERN_INFO "Mailbox driver unregistered\n"); } 13.将驱动程序的入口和出口函数注册到内核 module_init(mailbox_init); module_exit(mailbox_exit); 14.在模块描述符中添加模块许可证信息和作者信息 MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); 15.编译和安装模块 make sudo insmod mailbox_driver.ko 16.测试PCIe Mailbox功能 通过读写PCIe设备的寄存器来测试PCIe Mailbox功能: #define MAILBOX_ENABLE_BIT (1 << 0) void mailbox_test(struct mailbox_dev *mdev) { struct mailbox_regs *regs = (struct mailbox_regs *)mdev->regs; // Enable the mailbox writel(MAILBOX_ENABLE_BIT, &regs->ctrl_reg); // Write data to the mailbox writel(0x12345678, &regs->data_reg); // Wait for the mailbox to be ready while (!(readl(&regs->status_reg) & MAILBOX_ENABLE_BIT)); // Read data from the mailbox u32 data = readl(&regs->data_reg); printk(KERN_INFO "Mailbox data: %08x\n", data); } 17.卸载模块 sudo rmmod mailbox_driver

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值