正点原子linux阿尔法开发板使用——Linux内核时间管理_阿尔法linux开发板linux系统内核版本

#define TIMER_NAME “timer”
#define TIMER_COUNT 1

#define TIMEROFF 0 /* 关灯 */
#define TIMERON 1 /* 开灯 */

#define CLOSE_CMD _IO(0xEF,1) //关闭命令
#define OPEN_CMD _IO(0xEF,2) //打开命令
#define SETPRIOD_CMD _IO(0xEF,3) //设置周期

struct timer_dev {

struct cdev cdev;
struct class \*class;/\*类:为了自动创建节点\*/
struct device \*device;/\*设备:为了自动创建节点\*/
dev\_t devid; //设备号
int major;   //主设备号
int minor;   //次设备号
struct device\_node \*nd; //设备节点
int led_gpio;

/\*定义设备结构体\*/
struct timer\_list timer;

int timerperiod;	/\*定时器ms\*/

};

struct timer_dev timerdev; //TIMER设备

static int timer_open(struct inode *inode,struct file *filp)
{
filp->private_data = &timerdev;

return 0;

}

static ssize_t timer_write(struct file *filp, const char __user *buf,size_t cnt, loff_t *offt)
{
//struct timer_dev *dev = (struct timer_dev *)filp->private_data;

return 0;

}

static int timer_release(struct inode *inode,struct file *filp)
{
//struct timer_dev *dev = (struct timer_dev *)filp->private_data;

return 0;

}
long timer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct timer_dev *dev = (struct timer_dev *)filp->private_data;
int value = 0;

int ret = 0;

switch (cmd)
{
	case CLOSE_CMD:
		del\_timer\_sync(&dev->timer);
		break;

	case OPEN_CMD:
		mod\_timer(&dev->timer,jiffies + msecs\_to\_jiffies(500));

		break;
	case SETPRIOD_CMD:
		ret =  copy\_from\_user(&value,(int \*)arg,sizeof(int));
		if (ret < 0)
		{
			return -EFAULT;
		}
		dev->timerperiod = value;
		mod\_timer(&dev->timer,jiffies + msecs\_to\_jiffies(dev->timerperiod));
		break;
}
return 0;

}
static struct file_operations timer_fops = {
.owner = THIS_MODULE,
.write = timer_write,
.open = timer_open,
.release = timer_release,
.unlocked_ioctl = timer_ioctl,
};

static void timer_func(unsigned long arg)
{
struct timer_dev *dev = (struct timer_dev *)arg;

static int sta = 1;

sta = !sta;

gpio\_set\_value(dev->led_gpio,sta);

//重新开启定时器
mod\_timer(&dev->timer,jiffies + msecs\_to\_jiffies(dev->timerperiod));

}

/*初始化LED*/
int led_init(struct timer_dev *dev)
{
int ret = 0;

dev->nd = of\_find\_node\_by\_path("/gpioled");
if (dev->nd == NULL)
{
	ret = -EINVAL;
	goto fail_fd;
}

dev->led_gpio = of\_get\_named\_gpio(dev->nd,"led-goios",0);
if (dev->led_gpio < 0)
{
	ret = -EINVAL;
	goto fail_gpio;
}
	
ret =  gpio\_request(dev->led_gpio,"led");
if(ret){
	ret = -EBUSY;
	printk("gpio\_request fail\r\n");
	goto fail_request;
}

ret = gpio\_direction\_output(dev->led_gpio,1); //默认关灯
if (ret < 0)
{
	ret = -EINVAL;
	goto fail_gpioset;
}


return 0;

fail_gpioset:
fail_request:
gpio_free(dev->led_gpio);
fail_gpio:
fail_fd:
return ret;

}

static int __init timer_init(void)
{

int ret = 0; 

/\*注册字符设备\*/
timerdev.major = 0;
if (timerdev.major){	
	timerdev.devid = MKDEV(timerdev.major,0);//设备号
	ret = register\_chrdev\_region(timerdev.devid,TIMER_COUNT,TIMER_NAME);
}	else{
	ret = alloc\_chrdev\_region(&timerdev.devid,0,TIMER_COUNT,TIMER_NAME);
	timerdev.major = MAJOR(timerdev.devid);
	timerdev.minor = MINOR(timerdev.devid);
}printk("led major = %d led minor = %d \r\n",timerdev.major,timerdev.minor);
if (ret < 0){
	goto faile_devid;
}

/\*2、添加字符设备\*/
timerdev.cdev.owner = THIS_MODULE;
cdev\_init(&timerdev.cdev,&timer_fops);
ret = cdev\_add(&timerdev.cdev,timerdev.devid,TIMER_COUNT);
if(ret<0){
	goto fail_cdev;
}
/\*3、创建设备类\*/
timerdev.class = class\_create(THIS_MODULE,TIMER_NAME);
if(IS\_ERR(timerdev.class)){
	ret = PTR\_ERR(timerdev.class);
	printk("can't class\_create \r\n");
	goto fail_class;
}
/\*4、创建设备节点\*/
timerdev.device = device\_create(timerdev.class,NULL,timerdev.devid,NULL,TIMER_NAME);
if(IS\_ERR(timerdev.device)){
	ret = PTR\_ERR(timerdev.device);
	printk("can't device\_create \r\n");
	goto fail_device;
}



/\*5、初始化led\*/
ret =  led\_init(&timerdev);
if (ret < 0)
{
	ret = -EINVAL;
	goto fail_init;
}

/\*6、定时器初始化\*/


init\_timer(&timerdev.timer);

timerdev.timerperiod = 500;

timerdev.timer.expires 	= jiffies + msecs\_to\_jiffies(timerdev.timerperiod);

timerdev.timer.function = timer_func;

timerdev.timer.data = (unsigned long)&timerdev;

add\_timer(&timerdev.timer); /\*添加到系统\*/





return 0;

fail_init:
fail_device:
class_destroy(timerdev.class);
fail_class:
cdev_del(&timerdev.cdev);
fail_cdev:
unregister_chrdev_region(timerdev.devid,TIMER_COUNT);
faile_devid:
return ret;

}

static void __exit timer_exit(void)
{

/\* 关灯 \*/
gpio\_set\_value(timerdev.led_gpio,1);
/\*删除定时器\*/
del\_timer(&timerdev.timer);

/\*删除设备\*/
cdev\_del(&timerdev.cdev);
/\*释放设备号\*/
unregister\_chrdev\_region(timerdev.devid,TIMER_COUNT);

/\*摧毁设备\*/
device\_destroy(timerdev.class,timerdev.devid);

/\*释放类\*/
class\_destroy(timerdev.class);

/\*释放IO\*/
gpio\_free(timerdev.led_gpio);

}

//模块加载函数
module_init(timer_init);

//模块卸载
module_exit(timer_exit);

MODULE_LICENSE(“GPL”);

MODULE_AUTHOR(“qhy”);


#### 应用编程


应用使用ioctl函数。unlocked\_ioctl和compat\_ioctl。


![在这里插入图片描述](https://img-blog.csdnimg.cn/02b8270ce06a4588b014fb7e8b4a6d7e.png)



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

/**
* 1 表示向驱动读取数据
*
* 2 表示向驱动写入数据
*
*/

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

片转存中…(img-4tSRcQid-1715757414301)]

[外链图片转存中…(img-QhGUm7A8-1715757414301)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值