hrtimer

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/uaccess.h> 
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#define SEC_TO_NS(x) (x * 1E9L)
#define MS_TO_NS(x)  (x * 1E6L)
#define US_TO_NS(x)  (x * 1E3L)



#define WRITE_REG(Addr, Value)    ((*(volatile unsigned int *)(Addr)) = (Value))
#define READ_REG(Addr)            (*(volatile unsigned int *)(Addr))
#define REG_USR_ADDR(RegAddr)      *((volatile unsigned int *)(RegAddr))

#define GPIO_SEL_REG_BASE         IO_ADDRESS(0x10203000)
#define GPIO5_2_SEL_REG           (GPIO_SEL_REG_BASE + 0x078)
#define GPIO5_7_SEL_REG           (GPIO_SEL_REG_BASE + 0x08c)
#define GPIO10_5_SEL_REG          (GPIO_SEL_REG_BASE + 0x0ac)
#define GPIO5_5_SEL_REG           (GPIO_SEL_REG_BASE + 0x84)

#define GPIO5_REG_BASE            IO_ADDRESS(0x101E4000)
#define GPIO5_DATA                (GPIO5_REG_BASE + 0x000) 
#define GPIO5_DIR                 (GPIO5_REG_BASE + 0x400) 

#define GPIO5_IS                    (GPIO5_REG_BASE + 0x404) //GPIO 中断触发寄存器
#define GPIO5_IBE                   (GPIO5_REG_BASE + 0x408) //GPIO 双沿触发中断寄存器
#define GPIO5_IEV                   (GPIO5_REG_BASE + 0x40C) //GPIO 触发中断条件寄存器
#define GPIO5_IE                    (GPIO5_REG_BASE + 0x410) //GPIO 中断屏蔽寄存器
#define GPIO5_RIS                   (GPIO5_REG_BASE + 0x414) //GPIO 原始中断状态寄存器
#define GPIO5_MIS                   (GPIO5_REG_BASE + 0x418) //GPIO 屏蔽状态中断寄存器
#define GPIO5_IC                    (GPIO5_REG_BASE + 0x41C) //GPIO 中断清除寄存器


#define GPIO10_REG_BASE           IO_ADDRESS(0x101F0000)
#define GPIO10_DATA               (GPIO10_REG_BASE + 0x000) 
#define GPIO10_DIR                (GPIO10_REG_BASE + 0x400) 

static struct hrtimer hr_timer;
struct proc_dir_entry   *gpio_proc_dir = NULL;
struct proc_dir_entry *stFileEntry = NULL;
static struct timer_list  mytest_timer;
static ktime_t ktime;
static unsigned long delay_in_us = 15L;


void GPIO5_5_Pin_INIT(void)
{
    unsigned int tmp = 1;
    // 1. 设置GPIO5_5 为 gpio模式
    WRITE_REG(GPIO5_5_SEL_REG, 0x00);
    // 2. 设置 GPIO5_5 输出模式
    tmp = READ_REG(GPIO5_DIR);
    tmp |= (0x01<<5);
    WRITE_REG(GPIO5_DIR, tmp); 
}


void GPIO5_5WriteBit(void)
{
	unsigned int   GpioUsrAddr = GPIO5_REG_BASE;
	unsigned int   GpioBitNum = 5;
	static unsigned char bHighVolt = 0;
	if (bHighVolt)
	{
		REG_USR_ADDR(GpioUsrAddr + (4 << GpioBitNum)) = 1 << GpioBitNum;
	}
	else
	{
		REG_USR_ADDR(GpioUsrAddr + (4 << GpioBitNum)) = 0;
	}
	bHighVolt = !bHighVolt;
	return;
}

enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
{
	GPIO5_5WriteBit();
	hrtimer_forward_now(timer, ktime);
	return HRTIMER_RESTART;
}

void start_hard_timer(unsigned long arg)
{ 
	hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );
	return;
}

static int gpio_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
{
	char *sub_str = NULL;
	const char *start_string = "start";
	int len = 0;
	unsigned char pdata[100] = {0};
	len = (count > 100) ? 100 : count;
	memset(pdata,0,sizeof(pdata));
	if(copy_from_user(pdata, buffer, len))
	{
		printk("Fail to get data from user space !\n");
		return -1;
	}
	else
	{
		//printk("user space data: %s\n",pdata);
		if(NULL != strstr((const char*)pdata,start_string))
		{
			GPIO5_5_Pin_INIT();
			printk("HR Timer module installing\n");
			ktime = ktime_set(0,US_TO_NS(delay_in_us));
			hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
			hr_timer.function = &my_hrtimer_callback;
			printk( "Starting timer to fire in %ldus (%ld)\n", delay_in_us, jiffies );

			init_timer(&mytest_timer);
			mytest_timer.expires = jiffies + HZ;
			mytest_timer.function = start_hard_timer;
			mytest_timer.data = 0;
			add_timer(&mytest_timer);   
		}
	}
	return 1;
}
static int __init ker_driver_init(void)
{


	gpio_proc_dir = proc_mkdir("driver/gpio", NULL);
	if(gpio_proc_dir == NULL)
	{
		printk("proc_mkdir driver/gpio fail\n");
		goto err_dir;
	}
	stFileEntry = create_proc_entry("input", 0666, gpio_proc_dir);
	if(stFileEntry == NULL)
	{
		printk("create_proc_entry driver/gpio/input fail\n");
		goto err_sub_dir;
	}
	stFileEntry->write_proc = gpio_proc_write;
	return 0;
err_sub_dir:
	remove_proc_entry("input", gpio_proc_dir);
err_dir:
	remove_proc_entry("driver/gpio", NULL);
	return -1;
}

static int  cleanup_proc_gpio(void)
{
    if(NULL != stFileEntry)
        remove_proc_entry("input", gpio_proc_dir);
    if(NULL != gpio_proc_dir)
        remove_proc_entry("driver/gpio", NULL);
    stFileEntry = NULL;
    gpio_proc_dir = NULL;
    return 1;
}

static void __exit ker_driver_exit(void)
{
	int ret;
	cleanup_proc_gpio();
	ret = hrtimer_cancel( &hr_timer );
	if (ret) 
		printk("The timer was still in use...\n");
	printk("HR Timer module uninstalling\n");
	return;
}
module_init(ker_driver_init);
module_exit(ker_driver_exit);

MODULE_AUTHOR("cupidove@163.com");
MODULE_DESCRIPTION("Kernel driver");
MODULE_LICENSE("GPL");

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值