一、编写目的
根据“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 --->
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 #include #include #include #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);
上一篇:linux-at91——sama5d3.dtsi
下一篇:NAND_FLASH(K9F1208U0C)驱动分析
推荐阅读最新更新时间:2024-11-07 15:13
设计资源 培训 开发板 精华推荐
- BTS3134D智能低边功率开关典型应用电路
- STM32H753I-EVAL2,带有 STM32H753XI MCU 的评估板
- 南通大学地图
- LTC3622EDE-2 5V/3.3V Vout 突发模式操作应用同步降压稳压器的典型应用电路
- 家用电器的微处理器电源监控
- 采用 LTC1387 的 5V RS232/RS485 多协议收发器参考设计
- DEMOBCR60260VICTRLTOBO1,用于 BCR602 60V、200mA 线性 LED 控制器的演示板
- 适用于 5V 至 1.0V @ 500 mA 应用的 MCP1603 同步降压稳压器的典型应用电路
- LTC3857IGN-1 高效两相 12V/150W 降压转换器的典型应用电路
- 优化超宽带直接变频接收机的性能