AT91SAM9260开发板驱动编写
来源:互联网 发布:淘宝和易趣的共同点 编辑:程序博客网 时间:2024/05/02 06:09
一、 编写目的 2
二、 驱动移植 2
1. RTC驱动(PCF8563) 2
2. Led驱动 3
3. 按键驱动 4
4. NAND FLASH驱动 6
5. LCD1602驱动 8
三、 总结 11
一、编写目的
根据“1.AT91SAM9260建立开发环境.doc”搭建好开发环境后,接下来就是进行各个硬件驱动的调试了。本文档用于记录硬件驱动的调试过程,方便日后快速参考设计相关驱动。
二、驱动移植
1. RTC驱动(PCF8563)
本核心板上使用的RTC芯片型号为PCF8563。LINUX内核对其驱动已经有完整的支持,因此只需要进行相关配置即可。
a) 修改内核中的RTC配置
Device Drivers ---> Real Time Clock --->
< > AT91SAM9x/AT91CAP9 RTT as RTC //取消内部RTC设置
<*> Philips PCF8563/Epson RTC8564 //打开外部IIC RTC配置
b) 修改板级配置文件
# gedit ./arch/arm/mach-at91/board-sam9260ek.c
static struct i2c_board_info __initdata ek_i2c_devices[] = {
{
I2C_BOARD_INFO("pcf8563", 0x51), //add
/* delete
I2C_BOARD_INFO("24c512", 0x50),
.platform_data = &at24c512,
*/
},
/* more devices can be added using expansion connectors */
};
c) 设置 系统时钟并写到RTC上(设置为2014年7月8日 02:43:00)
# date -s "2014-07-08 02:43:00"
# hwclock -w
2. Led驱动
LINUX内核对于LED有完善的架构支持,可以在内核配置时打开相关配置项。
a) 修改内核中的配置
Device Drivers ---> [*] LED Support --->
[*] LED Class Support
<*> LED Support for GPIO connected LEDs
[*] Platform device bindings for GPIO LEDs
[*] LED Trigger support
<*> LED Timer Trigger
<*> LED Heartbeat Trigger
<*> LED backlight Trigger
<*> LED GPIO Trigger
<*> LED Default ON Trigger
b) 修改板级配置文件
# gedit ./arch/arm/mach-at91/board-sam9260ek.c
/*
* LEDs
*/
static struct gpio_led ek_leds[] = {
{
.name = "ds1",
.gpio = AT91_PIN_PC6,
.active_low = 1,
.default_trigger = "timer",
},
{
.name = "ds2",
.gpio = AT91_PIN_PC7,
.active_low = 1,
.default_trigger = "timer",
},
{
.name = "ds3",
.gpio = AT91_PIN_PC9,
.default_trigger = "heartbeat",
}
};
c) 测试驱动
由于使用了LINUX的LED子系统作为LED驱动架构,如下图所示,设备文件的路径在/sys/class/leds/dsx目录下。
使用以下命令可以控制LED的亮、灭:
# echo 1 > /sys/class/leds/ds1/brightness //亮
# echo 0 > /sys/class/leds/ds1/brightness //灭
3. 按键驱动
a) 修改内核中的配置
Device Drivers ---> Input device support --->
<*> Event interface
Device Drivers ---> Input device support ---> [*] Keyboards --->
<*> GPIO Buttons
b) 修改板级配置文件
# gedit ./arch/arm/mach-at91/board-sam9260ek.c
/*
* GPIO Buttons
*/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button ek_buttons[] = {
{
.gpio = AT91_PIN_PC10,
.code = BTN_1,
.desc = "Button 1",
.active_low = 1,
.wakeup = 1,
.debounce_interval = 20, /* 去抖动间隔,单位微毫秒*/
},
{
.gpio = AT91_PIN_PC11,
.code = BTN_2,
.desc = "Button 2",
.active_low = 1,
.wakeup = 1,
.debounce_interval = 20,
},
{
.gpio = AT91_PIN_PC13,
.code = BTN_3,
.desc = "Button 3",
.active_low = 1,
.wakeup = 1,
.debounce_interval = 20,
},
{
.gpio = AT91_PIN_PB30,
.code = BTN_4,
.desc = "Button 4",
.active_low = 1,
.wakeup = 1,
.debounce_interval = 20,
},
};
static struct gpio_keys_platform_data ek_button_data = {
.buttons = ek_buttons,
.nbuttons = ARRAY_SIZE(ek_buttons),
};
static struct platform_device ek_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
.dev = {
.platform_data = &ek_button_data,
}
};
static void __init ek_add_device_buttons(void)
{
at91_set_gpio_input(AT91_PIN_PC10, 1); /* btn1 */
at91_set_deglitch(AT91_PIN_PC10, 1);
at91_set_gpio_input(AT91_PIN_PC11, 1); /* btn2 */
at91_set_deglitch(AT91_PIN_PC11, 1);
at91_set_gpio_input(AT91_PIN_PC13, 1); /* btn3 */
at91_set_deglitch(AT91_PIN_PC13, 1);
at91_set_gpio_input(AT91_PIN_PB30, 1); /* btn4 */
at91_set_deglitch(AT91_PIN_PB30, 1);
platform_device_register(&ek_button_device);
}
#else
static void __init ek_add_device_buttons(void) {}
#endif
c) 测试驱动
该按键驱动使用了LINUX输入子系统框架,在打开了事件接口配置后,在/dev/input/event0设备文件中可读取按键的事件值。在控制台上测试可以使用以下命令。
# hexdump /dev/input/event0
此时按下按键,将会有数据输出,如下图所示。其中每一次按键动作输出两行数据,从图中分析可知K1~K4的键值分别为101~104。
4. NAND FLASH驱动
a) 修改内核中的配置
Device Drivers ---> <*> Memory Technology Device (MTD) support
[*] MTD partitioning support
<*> Direct char device access to MTD devices
-*- Common interface to block layer for MTD 'translation layers
<*> Caching block device access to MTD devices
Device Drivers ---> <*> Memory Technology Device (MTD) support ---> <*> NAND Device Support
<*> Support for NAND Flash / SmartMedia on AT91 and AVR32
ECC management for NAND Flash / SmartMedia on AT91 / AVR32 (Software ECC) --->
(X) Software ECC
b) 测试nand驱动
从启动信息中可以看出已经成功识别了改NAND FLASH了,如下图所示。
使用flash_eraseall、 nanddump、nandwrite 这三个工具对NAND进行操作(mtd-utils工具/http://pan.baidu.com/s/1mgG8dbq)。以下测试方法是在Linux下将uImage镜像烧写至nand中,通过是否能正常启动Linux来检验Nand驱动是否正确。
目前开发板的NAND中已经烧写了Bootstrap和u-boot,使用nanddump指令可以读取这两个分区的数据,并与BIN文件进行对比,对比结果正确。
# nanddump /dev/mtd0 -s 0x00000000 -l 0x00000200 -p //bootstrap的分区
# nanddump /dev/mtd1 -s 0x00000000 -l 0x00000200 -p //u-boot的分区
使用nandwrite烧写uImage到NAND中,修改U-BOOT启动命令后,让其从NAND读取内核,经验证可以正常启动LINUX内核,说明NAND驱动可以使用。
# flash_eraseall /dev/mtd4
# nandwrite -a -p /dev/mtd4 /uImage
# setenv bootcmd 'nand read 0x22000000 0xA0000 0x200000; bootm'
5. LCD1602驱动
LCD1602属于一个简单的字符设备,因此这里不对其驱动代码进行详细说明。这部分文字主要说明在LINUX内核中加入新设备驱动的操作,驱动以模块化的方式进行加载。
a) 复制驱动源码至LINUX内核源码目录(使用以前开发过的驱动)
# cp at91_lcd.c ./drivers/char
b) 修改./drivers/char目录下的Kconfig文件,增加LCD1602相关配置菜单
# gedit ./drivers/char/Kconfig
config MSM_SMD_PKT
bool "Enable device interface for some SMD packet ports"
default n
depends on MSM_SMD
help
Enables userspace clients to read and write to some packet SMD
ports via device interface for MSM chipset.
config AT91_LCD
tristate "LCD12232 interface"
default y
help
------------ No help! ----------------------------
endmenu
c) 修改./drivers/char目录下的Makefile文件,增加编译选项
# gedit ./drivers/char/Makefile
obj-$(CONFIG_AT91_LCD) += at91_lcd.o
d) 进入menuconfig配置菜单,进行驱动配置
Device Drivers ---> Character devices --->
<M> LCD12232 interface (NEW)
e) 编译内核模块
# make ARCH=arm CROSS_COMPILE=arm-linux- modules
编译成功后,将./drivers/char目录下的at91_lcd.ko文件复制到目标板的文件系统中,并在目录板的控制台上使用insmod指令加载驱动模块,使用lsmod指令可以查看已经加载的模块,使用rmmod命令删除模块。注意,模块文件必须放在/lib/modules/2.6.39目录下,否则不能正常卸载。
# cp drivers/char/at91_lcd.ko /opt/AT91SAM9260EK/4.FS/NFS/lib/modules/2.6.39/
# insmod /lib/modules/2.6.39/at91_lcd.ko
# lsmod
# rmmod at91_lcd
f) 生成设备文件
# mknod /dev/at91_lcd c 217 0
加载驱动模块与生成设备文件的命令可以放到/etc/init.d/rcS文件中,让其开机自动执行。
g) 测试程序
#include <stdint.h> //标准输入输出定义
#include <stdio.h> //Unix标准函数定义
#include <string.h> //字符串处理函数定义
#include <fcntl.h> //文件控制定
#define DEV_LCD "/dev/at91_lcd"
int clearLCD(int fd);
int fd_lcd;
int main(void)
{
char bufLcd[124];
fd_lcd = open(DEV_LCD, O_RDWR);
if (fd_lcd < 0)
{
printf("Open \"%s\" fail!\n", DEV_LCD);
}
clearLCD(fd_lcd);
bufLcd[0] = 0; // 列
bufLcd[1] = 0; //行
strcpy(&bufLcd[2], "----Welcome!----");
write(fd_lcd, bufLcd, strlen(&bufLcd[2]) + 2);
bufLcd[0] = 0; // 列
bufLcd[1] = 1; //行
strcpy(&bufLcd[2], "---LSHICEMAN!---");
write(fd_lcd, bufLcd, strlen(&bufLcd[2]) + 2);
while(1);
return 0;
}
int clearLCD(int fd)
{
int i;
char bufLCD[124];
if (fd < 0) return -1;
memset(bufLCD, 20, 124);
for (i = 0; i < 2; i++)
{
bufLCD[0] = 0;
bufLCD[1] = i;
write(fd, bufLCD, 124);
}
return 0;
}
三、总结
AT91SAM9260核心板的各个驱动已经基本完成。像继电器、LCD背光这类GPIO控制类的驱动还没有进行编写,可以参考LED驱动的方式进行编写/设置。将本文档中的LINUX系统打包为201407091104_at91sam9260ek_linux.2.6.39.tar.bz2,可通过以下地址下载。
# tar -jcvf 201407091104_at91sam9260ek_linux.2.6.39.tar.bz2 ./linux-at91-linux-2.6.39-at91/
http://pan.baidu.com/s/1o6LTNRW
- AT91SAM9260开发板驱动编写
- AT91SAM9260开发板
- at91sam9260驱动
- 驱动程序开发--AT91SAM9260的GPIO驱动笔记
- AT91SAM9260的SMC的驱动开发
- 驱动程序开发--AT91SAM9260的GPIO驱动笔记
- at91sam9260的Telnet远程登录开发板
- at91sam9260中断驱动
- AT91Sam9260的网卡驱动
- at91sam9260 开发环境的建立
- at91sam9260 开发环境的建立
- at91sam9260 开发环境的建立
- AT91SAM9260开发环境的搭建
- RTEMS 的 AT91SAM9260 移植(3): 时钟驱动
- RTEMS 的 AT91SAM9260 移植(4): 中断驱动
- AT91SAM9260 SMC外接LCD的驱动
- 迅为4412开发板编写简单应用调用驱动
- fl2440开发板hello world模块驱动编写
- HDU 1212 Big Number
- jQuery取得循环列表的第一列值
- PHP入门
- 百度员工离职总结:如何做个好员工
- Thread的start()和run()区别
- AT91SAM9260开发板驱动编写
- imx51 ROM boot code 启动分析 .
- 经纬财富:郴州白银区间操作,中线可考虑做多
- 个人学习计划
- jQuery事件之鼠标事件
- jquery 提示框
- 系统上线小结
- 行链接和行迁移的秘密
- iOS tableview动态高度