嵌入式课程---嵌入式Linux的直流电机驱动开发

实验环境准备

实验材料:GEC6818实验箱、电脑、
实验环境:VMware下Linux系统、arm-linux-交叉编译环境,windows系统、secureCRT平台

步骤简要说明:

因为需要用到Linux系统环境,所以在Windows下装了个虚拟机,使用虚拟机的环境来开发驱动,并编写了测试驱动的程序,然后把驱动与测试驱动的两个文件传送到实验箱中,接着在实验箱上测试驱动是否可用

第一步:测试三个系统是否连通

  1. 禁用pc机无线网卡、关闭所有防火墙、使用网线连接PC机与实验箱
  2. 设置pc机的IP地址(192.168.1.160)、子网掩码(255.255.255.0)
  3. 设置虚拟机IP地址,在终端下输入:
ifconfig eth0 192.168.1.170
  1. 设置实验箱IP地址,在secureCRT下,输入:
ifconfig eth0 192.168.1.180
  1. 然后三个系统之间互相ping一下,看是否能ping通,注意,一定要ping通才能做接下来的实验

第二步:编写并编译好驱动程序和测试驱动的程序

编写直流电机驱动程序dc_motor.c

/*---------------------------------------

*功能描述:  直流电机驱动 

*创建者:   粤嵌技术部

*创建时间: 2017,01,01

---------------------------------------

*修改日志:

*修改内容:

*修改人:

*修改时间:

----------------------------------------*/



/*************************************************

*头文件

*************************************************/

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/miscdevice.h>

#include <linux/fs.h>

#include <linux/types.h>

#include <linux/moduleparam.h>

#include <linux/slab.h>

#include <linux/ioctl.h>

#include <linux/cdev.h>

#include <linux/delay.h>

#include <linux/gpio.h>

#include <mach/gpio.h>

#include <mach/platform.h>

#include <asm/gpio.h>







#define DEVICE_NAME      "dc_motor"            //设备名字      



//电机管脚

static int motor_gpios[] = {

	(PAD_GPIO_C + 24),

	(PAD_GPIO_C + 25),

};



#define MOTOR_NUM		ARRAY_SIZE(motor_gpios) //电机的数量



/*************************************************

*电机初始化

*************************************************/

static void motor_init(void)

{

	gpio_set_value(motor_gpios[0], 0);

	gpio_set_value(motor_gpios[1], 0);

}



/*************************************************

*电机正传

*************************************************/

static void motor_foreward(void)

{

	gpio_set_value(motor_gpios[0], 1);

	gpio_set_value(motor_gpios[1], 0);

}



/*************************************************

*电机反转

*************************************************/

static void motor_rollback(void)

{

	gpio_set_value(motor_gpios[1], 1);

	gpio_set_value(motor_gpios[0], 0);

}



/*************************************************

*电机设备打开

*************************************************/

static int gec6818_motor_open(struct inode *inode, struct file *filp)

{

	printk(DEVICE_NAME ":open\n");

	motor_init();

	return 0;

}



/*************************************************

*电机控制程序

*************************************************/

static long gec6818_motor_ioctl(struct file *filp, unsigned int cmd,

		unsigned long arg)

{

	switch(cmd) {

		case 0:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}

			motor_init();

			printk("Motor Stop.\n");

			break;

			

		case 1:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}

			motor_rollback();

			printk("Motor Rollback.\n");

			break;

		case 4:

			if (arg > MOTOR_NUM) {

				return -EINVAL;

			}		

			motor_foreward();

			printk("Motor Foreward.\n");

			break;



		default:

			return -EINVAL;

	}



	return 0;

}



/*************************************************

*文件操作集

*************************************************/

static struct file_operations gec6818_motor_dev_fops = {

	.owner			= THIS_MODULE,

	.unlocked_ioctl	= gec6818_motor_ioctl,

	.open = gec6818_motor_open

};



/*************************************************

*杂项设备

*************************************************/

static struct miscdevice gec6818_motor_dev = {

	.minor			= MISC_DYNAMIC_MINOR,

	.name			= DEVICE_NAME,

	.fops			= &gec6818_motor_dev_fops,

};



/********************************************************************

*驱动的初始化函数--->从内核中申请资源(内核、中断、设备号、锁....)

********************************************************************/

static int __init gec6818_motor_dev_init(void)

{

	int ret;

	int i;

	

	for (i = 0; i < MOTOR_NUM; i++) {

		ret = gpio_request(motor_gpios[i], "MOTOR");

		if (ret) {

			printk("%s: request GPIO %d for MOTOR failed, ret = %d\n", DEVICE_NAME,

					motor_gpios[i], ret);

			return ret;

		}

		gpio_direction_output(motor_gpios[i], 0);

	}

	gpio_set_value(motor_gpios[0], 0);

	gpio_set_value(motor_gpios[1], 0);



	ret = misc_register(&gec6818_motor_dev);



	printk(DEVICE_NAME"\tinitialized\n");



	return ret;

}



/*****************************************************************

*驱动退出函数 --->将申请的资源还给内核

*****************************************************************/

static void __exit gec6818_motor_dev_exit(void) 

{

	int i;

	for (i = 0; i < MOTOR_NUM; i++) {

		gpio_free(motor_gpios[i]);

	}



	misc_deregister(&gec6818_motor_dev);

}



module_init(gec6818_motor_dev_init);                //驱动的入口函数会调用一个用户的初始化函数

module_exit(gec6818_motor_dev_exit);                //驱动的出口函数会调用一个用户的退出函数



//驱动的描述信息: #modinfo  *.ko , 驱动的描述信息并不是必需的。

MODULE_AUTHOR("kaoyangou");                         //驱动的作者

MODULE_DESCRIPTION("Dc_Motor of driver");           //驱动的描述

MODULE_LICENSE("GPL");                              //遵循的协议


编写驱动程序的Makefile文件

INSTALLDIR	=  /home/Hello



ifneq ($(KERNELRELEASE),)

obj-m:=dc_motor.o

else

KERNELDIR:=/home/Hello/demo/6818GEC/kernel

CROSS_COMPILE:=/home/Hello/demo/6818GEC/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-



PWD:=$(shell pwd)



default:

	mkdir -p $(INSTALLDIR)

	$(MAKE) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) -C $(KERNELDIR) M=$(PWD) modules

	cp --target-dir=$(INSTALLDIR) dc_motor.ko



clean:

	rm -rf *.o *.order .*.cmd *.ko *.mod.c *.symvers

endif

编写驱动测试程序dcMotor_test.c

/*---------------------------------------

*功能描述:  直流电机测试程序

*创建者:   粤嵌技术部

*创建时间: 2015,01,01

---------------------------------------

*修改日志:

*修改内容:

*修改人:

*修改时间:

----------------------------------------*/



/*************************************************

*头文件

*************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/ioctl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>







#define PATH  	"/dev/dc_motor"                 //绝对路径



/*************************************************

*主函数

*************************************************/

int main(void)

{

	int fd;

	unsigned int val;



	fd = open(PATH, O_RDWR);                         //打开设备,成功返回0

	if (fd < 0) {

		perror("Failed to open!\n");

		exit(1);

	}



	do{ 

		printf(" Please select how to operate the DC motor.\n");

		printf("0 ->Stop\n");

     		printf("1 -> Rollback\n");

		printf("4 -> Foreward\n");

		printf("9 -> Exit!\n");

     		scanf("%d", &val);

		

		if(val == 9) 

			break;

		ioctl(fd, val, 0);

	}while(1);



	close(fd);

	return 0;

}

编写测试驱动程序的Makefile文件

#

# Makefile for Linux application test example.

#

#---------------------------------------------------------------

# Linux application Makefile sample

# make          -- the optical output without debug info

# make clean    -- clean the object file(s)

# make install  -- install the execute file(s) to INSTALLDIR

#---------------------------------------------------------------

# History:

#			



INSTALLDIR	= /home/Hello



#---------------------------------	/* execute file(s) */

TESTFILE 	= dcMotor_test

#---------------------------------	/* object file(s) */

SRCFILE		= dcMotor_test.c

#---------------------------------	/* header file(s) */

TESTFILE_H	=



CROSS = arm-none-linux-gnueabi-

CC = $(CROSS)gcc

AS = $(CROSS)as

LD = $(CROSS)ld



CFLAGS  += -O2 -Wall



all:   $(TESTFILE)



$(TESTFILE):  $(SRCFILE) $(TESTFILE_H) Makefile

	mkdir -p $(INSTALLDIR) 

	$(CC) $(CFLAGS) -o $@ $@.c

	cp --target-dir=$(INSTALLDIR) $(TESTFILE)



clean:

	rm -f $(TESTFILE)

第三步:编译生成dc_motor.ko与dcMotor_test二进制执行文件

  1. 将驱动程序dc_motor.c与其对应Makefile文件放在同一目录下,然后在该目录下执行命令make,生成目标文件dc_motor.ko
    注意:Makefile中可能制定了生成的二进制执行文件安装路径:INSTALLDIR = 某某某
  2. 将驱动程序dcMotor_test.c与其对应Makefile文件放在同一目录下,然后在该目录下执行命令make,生成目标文件dcMotor_test
    注意:Makefile中可能制定了生成的二进制执行文件安装路径:INSTALLDIR = 某某某
    需要知道的是,以上的编译属于交叉编译,Makefile文件中已指定相应的交叉编译器

第四步:将dc_motor.ko文件与dcMotor_test文件挂载到实验箱板子

  1. 将dc_motor.ko文件与dcMotor_test文件统一放在虚拟机的nfs_share目录上
  2. 在secureCRT命令框使用mount命令进行挂载,命令中的ip地址是虚拟机的ip地址
mount -o nolock,tcp 192.168.1.170:/home/Hello/nfs_share /mnt

第五步:在实验箱装载驱动并使用程序进行测试

  1. 在secureCRT中输入命令lsmod,然后回车,在返回的消息中如果找到有dc_motor字眼的一行,则使用rmmod dc_motor进行卸载原有驱动,确保实验箱系统不存在直流电机的驱动程序
lsmod    //查看已存在驱动

rmmod dc_motor   //卸载dc_motor直流电机的驱动
  1. 进入到目录 /mnt,然后插入驱动dc_motor.ko,因为刚才把自己制作的驱动挂载到了/mnt目录下
insmod dc_motor.ko   
  1. 测试,输入命令打开直流电机
./dcMotor_test

然后,选择1或4选项,发现直流电机转动,实验成功!
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值