嵌入式课程---嵌入式Linux的Led灯移植

实验目的

通过对 LED 驱动的移植,明白如何把驱动程序直接编译到内核中

实验环境准备

实验材料:GEC6818实验箱、电脑、OTG线
实验环境:VMware下Linux系统,windows系统、secureCRT平台

第一步:编写led驱动程序led.c及kconfig文件、config文件

  1. 找好实验箱的内核源码,并将其放到虚拟机中,并进入虚拟机下该内核源码目录,我这里是:/home/Hello/demo/6818GEC/kernel
cd /home/Hello/demo/6818GEC/kernel
  1. 接着进入drivers/char
Hello@University:~/demo/6818GEC/kernel$ cd drivers/char
  1. 在当前目录下新建led目录,并进入
mkdir led

cd led
  1. 编写Kconfig文件
config GEC6818_LED_DRIVER
	bool "GEC6818 led driver"
	default n
	help
	compile for leddriver,y for kernel,m for module.
  1. 编写Makefile文件
obj-$(CONFIG_GEC6818_LED_DRIVER) += led.o
  1. 编写led驱动程序led.c
/*---------------------------------------

*功能描述:  实现LED的驱动

*创建者:   kaoyangou

*创建时间: 2021,05,03

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

*修改日志:

*修改内容:

*修改人:

*修改时间:

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



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

*头文件

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

#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 <cfg_type.h>



#define DEVICE_NAME "Led"                    //定义设备名字



//定义Led的结构体,包括管脚和名字

struct led {

	int gpio;

	char *name;	

};



//定义Led的管脚和名字                                          

static struct led led_gpios[] = {

	{PAD_GPIO_B+26,"led1"},

    	{PAD_GPIO_C+11,"led2"},

    	{PAD_GPIO_C+7,"led3"},

	{PAD_GPIO_C+12,"led4"},

};



#define LED_NUM		4                     //ARRAY_SIZE(led_gpios)

#define TEST_MAX_NR 4 		              //定义命令的最大序数

#define TEST_MAGIC 'x'                    //定义幻数



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

*led_open函数

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

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

{

	printk(DEVICE_NAME ":open\n");

	return 0;				     

}



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

*LED控制函数

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

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

		unsigned long arg)

{

#if 1

	printk("led_num = %d \n", LED_NUM);

	if(_IOC_TYPE(cmd) != TEST_MAGIC) return - EINVAL;

	if(_IOC_NR(cmd) > TEST_MAX_NR) return - EINVAL;	

	

	gpio_set_value(led_gpios[_IOC_NR(cmd)].gpio, arg);

	printk(DEVICE_NAME": %d %lu\n", _IOC_NR(cmd), arg);



#endif

	//printk("xxxx %lu, %d xxxxx \n", cmd, arg);

	return 0;

}



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

*文件操作集

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

static struct file_operations gec5260_led_dev_fops = {

	.owner			= THIS_MODULE,

	.open                   = led_open,

	.unlocked_ioctl	= gec5260_leds_ioctl,

};



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

*杂项设备

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

static struct miscdevice gec5260_led_dev = {

	.minor			= MISC_DYNAMIC_MINOR,

	.name			= DEVICE_NAME,

	.fops			= &gec5260_led_dev_fops,

};



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

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

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

static int __init gec5260_led_dev_init(void) 

{

	int ret, i;

	gpio_free(PAD_GPIO_B+26);

	gpio_free(PAD_GPIO_C+11);

	gpio_free(PAD_GPIO_C+7);

	gpio_free(PAD_GPIO_C+12);



	for (i = 0; i < LED_NUM; i++)

	{

		ret = gpio_request(led_gpios[i].gpio, led_gpios[i].name);            //io申请

		if (ret) 															 //失败则打印出那个管教申请失败

		{

			printk("%s: request GPIO %d for LED failed, ret = %d\n", led_gpios[i].name, led_gpios[i].gpio, ret);

			return ret;

		}

		gpio_direction_output(led_gpios[i].gpio,0);                 //设置io为输出管脚              

	}

	

	ret = misc_register(&gec5260_led_dev);                                   //杂项设备申请

	printk(DEVICE_NAME"\tinitialized\n");									 //显示申请成功

	return ret;

}



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

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

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

static void __exit gec5260_led_dev_exit(void) 

{

	int i;

	//释放管教

	for (i = 0; i < LED_NUM; i++) 

	{

		gpio_free(led_gpios[i].gpio);

	}

	//移除杂项设备

	misc_deregister(&gec5260_led_dev);

}



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

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



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

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

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

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

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

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

第二步:将led驱动程序编译进内核中

  1. 进到kernel顶层目录使用make menuconfig,弹出图形界面,进行配置
Hello@University:~/demo/6818GEC/kernel$ make menuconfig
  1. 选择Device Drivers,然后选择select:
    在这里插入图片描述
  2. 选择Character devices,然后选择select:
    在这里插入图片描述
  3. 选择GEC6818 led driver,键盘按y进行选择,星号*表示选中,然后exit:
    在这里插入图片描述
  4. 然后一直exit,直到弹出是否确认保存配置,选择yes:
    在这里插入图片描述
  5. 最后拷贝配置文件.config 到当前目录的arch/arm/configs/GEC6818_defconfig目录下
Hello@University:~/demo/6818GEC/kernel$ cp .config arch/arm/configs/GEC6818_defconfig

第三步:将驱动编译进内核

注意:将驱动编译进内核,即:先将驱动程序放入内核源码中,然后写好相关配置,然后把内核源码编译一下

  1. 进到kernel目录的上一级目录:
  2. 然后输入以下命令进行内核编译,生成boot.img文件:
Hello@University:~/demo/6818GEC$ mk -k
  1. 在当前目录~/demo/6818GEC/out/target/product/GEC6818下找到boot.img文件,将其拖拽到pc机(Windows系统下)

第四步:将内核移植到实验箱当中

  1. 首先,使用串口线将电脑与实验箱相连,注意要安装好串口线的驱动,启动实验箱,然后在securityCRT上按空格进入uboot模式(自行配置和securityCRT与实验箱相连)
  2. uboot模式下,在securityCRT命令行输入fastboot进入实验箱的刷机模式:
fastboot
  1. 接着在电脑的设备管理器上看是否能找到实验箱设备,
    注意:更新下该设备的驱动,选择adb驱动(注意事先已装好adb工具的驱动,adb驱动是配合fastboot使用的),使得能正常刷机
  2. 使用fastboot工具进行刷机,将GECuboot.bin、rootfs-6818-restore.ext4以及刚编译好的boot.img文件放在fastboot工具的目录下,在cmd命令行下进入该目录,目录结构如下:
    在这里插入图片描述
  3. 在cmd命令行下输入一下命令进行操作:
fastboot flash boot boot.img

在这里插入图片描述

  1. 等待cmd命令行上显示刷入成功,然后重启实验箱,等待其正常启动,然后在securityCRT上键入CTRL+C进入实验箱的系统,输入以下命令,出现预想结果,则成功:
ls /dev/Led -l

结果如下:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您提供的两个课设,我将具体介绍完成流程和结果分析: 1. 嵌入式操作系统移植: 完成流程: - 硬件平台介绍:本次课设使用的硬件平台为ARM Cortex-M3处理器,外设包括LED、按键、LCD显示器等。 - 操作系统介绍:本次课设选择的操作系统为FreeRTOS,该操作系统具有开源、可移植、低功耗、实时性强的特点。 - 移植过程: 1)下载FreeRTOS源码,将其移植到ARM Cortex-M3平台上。 2)根据硬件平台的特点,进行配置和裁剪,以达到最优性能。 3)进行编译和链接,生成可执行文件。 - 移植结果:经过测试,移植后的FreeRTOS操作系统启动时间短,系统稳定性好,占用资源少,具有很好的实时性能和可移植性。 结果分析: - 性能测试:使用uC/Probe工具对FreeRTOS操作系统进行性能测试,测试结果表明,FreeRTOS操作系统的任务切换时间平均在100us左右,系统延迟时间在3ms以内。 - 比较分析:与其他操作系统进行比较分析,FreeRTOS操作系统在实时性能、可移植性和资源占用等方面表现优异。 2. 八位流水驱动程序测试: 完成流程: - 硬件平台介绍:本次课设使用的硬件平台为STC89C52RC单片机,外设为八个LED。 - 驱动程序介绍:本次课设编写了一个八位流水驱动程序,通过改变LED的亮灭状态,实现流水的效果。 - 测试过程: 1)编写测试程序,调用八位流水驱动程序。 2)将测试程序下载到单片机中,连接外设,对程序进行测试。 - 测试结果:经过测试,八位流水驱动程序能够正常运行,的亮灭状态符合预期,流水速度可通过修改程序实现。 结果分析: - 性能测试:通过对八位流水驱动程序进行性能测试,测试结果表明,程序运行稳定,的亮灭状态准确无误。 - 比较分析:与其他八位流水驱动程序进行比较分析,本次课设编写的驱动程序在功能、实现方法和程序设计等方面表现优异。 希望以上的具体完成流程和结果分析能够对您的课设有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值