EDN首页   博客首页

最新日志

发表于:2008-7-18 17:10:22
标签:9260EK-YAFFS2文件系统挂载  

1

9260EK-YAFFS2文件系统挂载

YAFFS2文件系统挂载
由于RAMDISK为只读的文件系统,如果要保存用户数据就需要增加一个可写的文件系统,由于用的是NAND FLASH,所以准备选用YAFFS2。9260EK给的开发包已经支持YAFFS2,所以也不需要自己去准备文件。
首先查看NAND FLASH分区情况  #cat /proc/mtd  看到只有两个分区,在查看当前支持的文件系统 #cat /proc/filesystems  看到里面没有支持YAFFS2。
因此需要首先准备一个单独的分区用来挂载YAFFS2,然后要在内核中选上支持YAFFS2并重新编译。
先找到 
/*
* NAND flash
*/
static struct mtd_partition __initdata ek_nand_partition[] = {
{
.name = "Partition 1",
.offset = 0,
.size = 4 * 1024 * 1024,
},
{
.name = "Partition 2",
.offset = 4 * 1024 * 1024,
.size = 200 * 1024 * 1024,
},
{
.name = "Partition 3",
.offset = 200 * 1024 * 1024,
.size = MTDPART_SIZ_FULL,
},
};
然后重新配置内核,以支持YAFFS2,配置如下
 
 
重新下载后重启,会看到如下启动信息
 
 
顺利启动,进行测试
# mount -t yaffs2 /dev/mtdblock2 /tmp
挂载成功显示如下信息:
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: restored from checkpoint
# cd tmp
  可以创建文件和目录
# umount tmp
  卸载成功显示
save exit: isCheckpointed 1
 重新启动,不放心可以掉电再来,重新挂载后即可看到刚才新建的文件。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(412)
发表于:2008-7-18 17:08:59
标签:9260EK-KEY测试(中断)  

1

9260EK-KEY测试(中断)

KEY测试(中断)
前面已经用查询的方式做了一个按键的驱动,现在来看看用中断方式做的按键驱动,这个驱动没有处理按键抖动这些细节问题,主要目的是了解一下中断的相关问题,按键只是个接口而已,而好多书上在讲中断的时候虽然也是以按键为例,但过于关注按键显得很烦琐。不利于突出中断这个主题。
说到中断,一般都是讲在用以前只要申请一下用完释放就可以了,函数如下
int request_irq(unsigned int irq,
            void (*handler)(int irq, void *dev_id, 
            struct pt_regs *regs), unsigned long irqflags,
            const char * devname, void *dev_id);
void free_irq(unsigned int irq,void *dev_id);
同样的,对于9260来说也一样,由于按键是接在PIOB上,通过查看中断分配可以看出,PIOA PIOB PIOC 分别对应中断号为 2 3 4,但如果在9260EK上,在申请中断时你会发现,如果申请的中断号为2 3 4 之中的任意一个,都将返回 -22 ,但如果换成其他中断号例如5,就可以成功申请。这就意味着我们不能申请 2 3 4这3个中断,在网上也可以看到不少用9260的朋友也都碰到了这个问题。
先看返回-22,意味着这个中断已经被占用,但用CAT看的话有没有任何关于这3个中断的信息。没办法,只有先翻翻源代码看看了,在arch/arm/match-at91rm9200/at91sam9260.c中发现了这么一段
void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS])
{
if (!priority)
priority = at91sam9260_default_irq_priority;
/* Initialize the AIC interrupt controller */
at91_aic_init(priority);
/* Enable GPIO interrupts */
at91_gpio_irq_setup();
}
 
 
void __init at91_gpio_irq_setup(void)
{
unsigned pioc, pin;
for (pioc = 0, pin = PIN_BASE;
pioc < gpio_banks;
pioc++) {
void __iomem *controller;
unsigned id = gpio[pioc].id;
unsigned i;
clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */
controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
__raw_writel(~0, controller + PIO_IDR);
set_irq_data(id, (void *) pin);
set_irq_chip_data(id, controller);
for (i = 0; i < 32; i++, pin++) {
/*
 * Can use the "simple" and not "edge" handler since it's
 * shorter, and the AIC handles interupts sanely.
 */
set_irq_chip(pin, &gpio_irqchip);
set_irq_handler(pin, handle_simple_irq);
set_irq_flags(pin, IRQF_VALID);
}
set_irq_chained_handler(id, gpio_irq_handler);
}
pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
}
 
 
void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks)
{
BUG_ON(nr_banks > MAX_GPIO_BANKS);
gpio = data;
gpio_banks = nr_banks;
}
void __init at91sam9260_initialize(unsigned long main_clock)
{
/* Map peripherals */
iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
if (cpu_is_at91sam9xe())
at91sam9xe_initialize();
else
iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
at91_arch_reset = at91sam9260_reset;
at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
| (1 << AT91SAM9260_ID_IRQ2);
/* Init clock subsystem */
at91_clock_init(main_clock);
/* Register the processor-specific clocks */
at91sam9260_register_clocks();
/* Register GPIO subsystem */
at91_gpio_init(at91sam9260_gpio, 3);
}
可以看出,确实 2 3 4中断已经被初始化过了,继续看又发现了下面这段注释
/* Several AIC controller irqs are dispatched through this GPIO handler.
 * To use any AT91_PIN_* as an externally triggered IRQ, first call
 * at91_set_gpio_input() then maybe enable its glitch filter.
 * Then just request_irq() with the pin ID; it works like any ARM IRQ
 * handler, though it always triggers on rising and falling edges.
 *
 * Alternatively, certain pins may be used directly as IRQ0..IRQ6 after
 * configuring them with at91_set_a_periph() or at91_set_b_periph().
 * IRQ0..IRQ6 should be configurable, e.g. level vs edge triggering.
 */
注册中断号时直接用AT91_PIN_PIOB1 一试,成功了,在用#cat /proc/initerrupts 一看,中断号为 65,再试一下AT91_PIN_PIOC1为 97,可以看出,PIOA的32个IO对应的中断号为32-63 ,PIOB和PIOC对应的依次为64-127。运行一下试试,一切正常。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(193)
发表于:2008-7-18 17:07:56
标签:9260EK-程序自启动  

1

9260EK-程序自启动

程序自启动
    前面已经通过重新制作新的文件系统将自己写的程序写到板子上的FLASH里了,但要执行还需要进入相应目录手工启动,下面来看一下让板子启动后自动运行自己写的程序。
 
如果在网上搜索的话会看到好多是这样写的:
    Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init。init根据配置文件继续引导过程,启动其它进程。通常情况下,修改放置在 /etc/rc或 /etc/rc.d 或 /etc/rc?.d 目录下的脚本文件,可以使init自动启动其它程序。例如:编辑 /etc/rc.d/rc.local 文件,在文件最末加上一行"xinit"或"startx",可以在开机启动后直接进入X-Window。
   
    但9260EK在进入etc后确找不到rc文件,这就可以看出与版本肯定有关了,但不管对于什么版本,init是所有进程的顶层init读取/etc/inittab,执行相应的脚本这个是一样的,所以进到/etc/inittab 文件,看到他调用的是 /etc/init.d/rcs.于是进入 /etc/init.d/rcs.将原来直接启动/bin/sh改为想让启动的程序名,注意要带路径。
 
修改完毕后,重新编译内核即可。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(160)
发表于:2008-7-18 17:06:43
标签:9260EK-RAMDISK制作  

1

9260EK-RAMDISK制作

RAMDISK制作
前面所有程序的调试都是通过NFS启动方式调试和运行的,要将这些程序真正保存到开发板进行脱机运行,就需要重新制作一个文件系统,将这些程序加进去。下面在现有的RAMDISK文件系统的基础上,通过修改加入上述用户程序。
RAMDISK文件系统修改步骤如下:
1 将现有的ramdisk.gz 拷贝到mnt目录
在mnt目录下新建一个loop目录
先解压已有的RAMDISK文件系统到当前目录下
# gunzip ramdisk.gz
把解压后的文件系统挂载到指定目录
# mount -o loop ramdisk  /mnt/loop
进入/mnt/loop 即可修改RAMDISK文件系统,将前面做好的程序的目标文件拷贝到loop下的任一目录。
进入/loop/dev目录,在新的文件系统里创建LED和KEY的设备文件
# mknod "/dev/led" c 60 1
# mknod "/dev/key" c 61 1
修改完毕后退出到mnt目录,卸载RAMDISK文件系统
# umount /mnt/loop
压缩RAMDISK文件系统
# gzip -9 ramdisk
新的文件系统制作完毕。重新下载或着烧录到扳子上以后,启动到UBOOT
进行环境变量设置
setenv ethaddr 00:22:33:11:44:55;
setenv ipaddr 192.168.1.10;
setenv serverip 192.168.1.196;
setenv nf_kernel nand read  22000000 100000 200000;
setenv nf_ramdisk nand read 21100000 400000 500000;
setenv bootcmd run nf_kernel\; run nf_ramdisk\; run boot;
setenv boot bootm 22000000;setenv bootdelay 3;
setenv bootargs mem=64M console=ttySAC0,115200 initrd=0x21100000,16777216 root=/dev/ram0 rw;
saveenv;
重新启动,就可看到刚才拷贝到文件系统中的用户程序。可以执行一下看看。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(211)
发表于:2008-7-18 17:05:54
标签:9260EK-KEY&LED测试  

1

9260EK-KEY&LED测试

KEY&LED测试
将以前做好的两个驱动同时调用,首先将LED驱动的目标文件led.ko和KEY驱动的目标文件key.ko拷贝到当前目录
程序如下:
include <unistd.h>
#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <sys/mman.h>
#include <time.h>
int devk;
int devl;
int main(void){
    int i,j;
    system("clear");
    printf("test key.\r\n");   
    system("rmmod key");
    //system("insmod /teset/key/key.ko");
    system("insmod key.ko");
    devk = open("/dev/key",O_RDWR);
    if(devk == -1){ 
         printf("cann't open key \n"); 
         return 0; 
    }
    printf("test led.\r\n");   
    system("rmmod led");
    //system("insmod /teset/led/led.ko");
    system("insmod led.ko");
    devl = open("/dev/led",O_RDWR);
    if(devl == -1){ 
         printf("cann't open led \n"); 
         return 0; 
    }
    while(1)
    {
      j=ioctl(devk,0,0); 
      if(j!=15)
      {
      if(j==7)  i=4;
         
         if(j==11) i=3;
         
         if(j==13) i=2;
         
         if(j==14) i=1;
         
         
         ioctl(devl,i,0);
         sleep(1);
         }
         else
         {
           ioctl(devl,0,1);
         }
 
    }
    close(devk);
    close(devl);
}
由于前面已经创建了LED和KEY的设备文件,所以现在编译后就可以直接运行。按下任一键则与其对应的LED就会亮一秒。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(166)
发表于:2008-7-18 17:04:35
标签:9260EK-KEY测试(查询)  

1

9260EK-KEY测试(查询)

KEY测试(查询)
作好了LED,现在做一个按键,板子的按键是接在PIOB0-3,只需要稍微改动一下就可以了,程序如下
#include <linux/mm.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/rtc.h> /* get the user-level API */
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <asm/mach/serial_at91.h>
#include "at91_pio.h"
MODULE_LICENSE("GPL");
static void __iomem *pio_base;
size_t key_read (struct file *filp, char __user *buf, size_t count, loff_t *pos){
     printk("watchdog read.\r\n");
     return 0;
}
ssize_t key_write (struct file *filp, const char __user *buf, size_t count,off_t *pos){
     printk("watchdog write.\r\n"); 
     return count;
}
int key_ioctl (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg){
     arg=readl(pio_base + PIO_PDSR)&0x0000000f;
     //printk("led ioctl cmd:%d%ld\r\n",cmd,arg);
     return arg;
}
static struct file_operations key_fops = {
     .owner = THIS_MODULE,
     .read  = key_read,
     .write = key_write,
     .ioctl = key_ioctl,
};
static int key_init(void){
     int result;
     printk(KERN_ALERT "key_test:%s,%s\r\n",__DATE__,__TIME__);
     pio_base = ioremap(0xFFFFF600,512);       
     writel(0x0000000f, pio_base + PIO_PUER);    
     writel(0x0000000f, pio_base + PIO_PER);     
     writel(0x0000000f, pio_base + PIO_IDR); 
     
     result = register_chrdev(61, "key", &key_fops);
     if (result < 0){
         printk("register device fail.\r\n");
 return result;
     }
     return 0;
}
static void key_exit(void){
printk("stop key\r\n");
     unregister_chrdev(61, "key");
     iounmap(pio_base);
     printk(KERN_ALERT "stop clear key\r\n");
}
module_init(key_init);
module_exit(key_exit);
 
同样编译好后,在运行之前,先要创建一个设备文件
# mknod "/dev/led" c 61 1
即创建一个主设备号为61,次设备号为1名称为KEY的字符型设备。
然后运行这个函数,按下按键,即可看见终端会有相应的显示。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(107)
发表于:2008-7-18 17:03:25
标签:9260EK-LED测试  

1

9260EK-LED测试

LED测试
由HELLO驱动模块熟悉了驱动模块的基本编写方法。下面要开始做一个真正有用的驱动—LED驱动。象普通单片机一样,先从IO控制开始。IO控制首先就要知道地址和个控制寄存器,先翻DATASHEET了。由于开发板的LED是接在PIOA上的。先找地址
再看寄存器
#1 PIO Controller PIO Enable Register
Name:PIO_PER
Access Type: Write-only
?P0-P31: PIO Enable
0 = No effect.
1 = Enables the PIO to control the corresponding pin (disables peripheral control of the pin).
#2 PIO Controller PIO Disable Register
Name: PIO_PDR
Access Type: Write-only
?P0-P31: PIO Disable
0 = No effect.
1 = Disables the PIO from controlling the corresponding pin (enables peripheral control of the pin).
#3 PIO Controller PIO Status Register
Name: PIO_PSR
Access Type: Read-only
?P0-P31: PIO Status
0 = PIO is inactive on the corresponding I/O line (peripheral is active).
1 = PIO is active on the corresponding I/O line (peripheral is inactive).
#4 PIO Controller Output Enable Register
Name: PIO_OER
Access Type: Write-only
?P0-P31: Output Enable
0 = No effect.
1 = Enables the output on the I/O line.
#5 PIO Controller Output Disable Register
Name: PIO_ODR
Access Type: Write-only
?P0-P31: Output Disable
0 = No effect.
1 = Disables the output on the I/O line.
#6 PIO Controller Output Status Register
Name: PIO_OSR
Access Type: Read-only
?P0-P31: Output Status
0 = The I/O line is a pure input.
1 = The I/O line is enabled in output.
#7 PIO Controller Input Filter Enable Register
Name: PIO_IFER
Access Type: Write-only
?P0-P31: Input Filter Enable
0 = No effect.
1 = Enables the input glitch filter on the I/O line.
#8 PIO Controller Input Filter Disable Register
Name: PIO_IFDR
Access Type: Write-only
?P0-P31: Input Filter Disable
0 = No effect.
1 = Disables the input glitch filter on the I/O line.
#9 PIO Controller Input Filter Status Register
Name: PIO_IFSR
Access Type: Read-only
?P0-P31: Input Filer Status
0 = The input glitch filter is disabled on the I/O line.
1 = The input glitch filter is enabled on the I/O line.
#10 PIO Controller Set Output Data Register
Name: PIO_SODR
Access Type: Write-only
?P0-P31: Set Output Data
0 = No effect.
1 = Sets the data to be driven on the I/O line.
#11 PIO Controller Clear Output Data Register
Name: PIO_CODR
Access Type: Write-only
?P0-P31: Set Output Data
0 = No effect.
1 = Clears the data to be driven on the I/O line.
#12 PIO Controller Output Data Status Register
Name: PIO_ODSR
Access Type: Read-only or Read/Write
?P0-P31: Output Data Status
0 = The data to be driven on the I/O line is 0.
1 = The data to be driven on the I/O line is 1.
#13 PIO Controller Pin Data Status Register
Name: PIO_PDSR
Access Type: Read-only
?P0-P31: Output Data Status
0 = The I/O line is at level 0.
1 = The I/O line is at level 1.
#14 PIO Controller Interrupt Enable Register
Name: PIO_IER
Access Type: Write-only
?P0-P31: Input Change Interrupt Enable
0 = No effect.
1 = Enables the Input Change Interrupt on the I/O line.
#15 PIO Controller Interrupt Disable Register
Name: PIO_IDR
Access Type: Write-only
?P0-P31: Input Change Interrupt Disable
0 = No effect.
1 = Disables the Input Change Interrupt on the I/O line.
#16 PIO Controller Interrupt Mask Register
Name: PIO_IMR
Access Type: Read-only
?P0-P31: Input Change Interrupt Mask
0 = Input Change Interrupt is disabled on the I/O line.
1 = Input Change Interrupt is enabled on the I/O line.
#17 PIO Controller Interrupt Status Register
Name: PIO_ISR
Access Type: Read-only
?P0-P31: Input Change Interrupt Status
0 = No Input Change has been detected on the I/O line since PIO_ISR was last read or since reset.
1 = At least one Input Change has been detected on the I/O line since PIO_ISR was last read or since reset.
#18 PIO Multi-driver Enable Register
Name: PIO_MDER
Access Type: Write-only
?P0-P31: Multi Drive Enable.
0 = No effect.
1 = Enables Multi Drive on the I/O line.
#19 PIO Multi-driver Disable Register
Name: PIO_MDDR
Access Type: Write-only
?P0-P31: Multi Drive Disable.
0 = No effect.
1 = Disables Multi Drive on the I/O line.
#20 PIO Multi-driver Status Register
Name: PIO_MDSR
Access Type: Read-only
?P0-P31: Multi Drive Status.
0 = The Multi Drive is disabled on the I/O line. The pin is driven at high and low level.
1 = The Multi Drive is enabled on the I/O line. The pin is driven at low level only.
#21 PIO Pull Up Disable Register
Name: PIO_PUDR
Access Type: Write-only
?P0-P31: Pull Up Disable.
0 = No effect.
1 = Disables the pull up resistor on the I/O line.
#22 PIO Pull Up Enable Register
Name: PIO_PUER
Access Type: Write-only
?P0-P31: Pull Up Enable.
0 = No effect.
1 = Enables the pull up resistor on the I/O line.
#23 PIO Pull Up Status Register
Name: PIO_PUSR
Access Type: Read-only
?P0-P31: Pull Up Status.
0 = Pull Up resistor is enabled on the I/O line.
1 = Pull Up resistor is disabled on the I/O line.
#24 PIO Peripheral A Select Register
Name: PIO_ASR
Access Type: Write-only
?P0-P31: Peripheral A Select.
0 = No effect.
1 = Assigns the I/O line to the Peripheral A function.
#25 PIO Peripheral B Select Register
Name: PIO_BSR
Access Type: Write-only
?P0-P31: Peripheral B Select.
0 = No effect.
1 = Assigns the I/O line to the peripheral B function.
#26 PIO Peripheral A B Status Register
Name: PIO_ABSR
Access Type: Read-only
?P0-P31: Peripheral A B Status.
0 = The I/O line is assigned to the Peripheral A.
1 = The I/O line is assigned to the Peripheral B.
#27 PIO Output Write Enable Register
Name: PIO_OWER
Access Type: Write-only
?P0-P31: Output Write Enable.
0 = No effect.
1 = Enables writing PIO_ODSR for the I/O line.
#28 PIO Output Write Disable Register
Name: PIO_OWDR
Access Type: Write-only
?P0-P31: Output Write Disable.
0 = No effect.
1 = Disables writing PIO_ODSR for the I/O line.
#29 PIO Output Write Status Register
Name: PIO_OWSR
Access Type: Read-only
?P0-P31: Output Write Status.
0 = Writing PIO_ODSR does not affect the I/O line.
1 = Writing PIO_ODSR affects the I/O line.
 
下面是程序
 
#include <linux/mm.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/rtc.h> /* get the user-level API */
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <asm/mach/serial_at91.h>
#include "at91_pio.h"
MODULE_LICENSE("GPL");
static void __iomem *pio_base;
size_t led_read (struct file *filp, char __user *buf, size_t count, loff_t *pos){
     printk("watchdog read.\r\n");
     return 0;
}
ssize_t led_write (struct file *filp, const char __user *buf, size_t count,off_t *pos){
     printk("watchdog write.\r\n"); 
     return count;
}
int led_ioctl (struct inode *inode, struct file *filp,unsigned int cmd, unsigned long arg){
    // printk("led ioctl cmd:%d%d\r\n",cmd,arg);
    long  mode; 
    
    switch(cmd)
    {
     case 1:
           mode=0x00000100;
     break;
     case 2:
           mode=0x00000080;
     break;
     case 3:
           mode=0x00000040;
     break;
     case 4:
           mode=0x00000020;
     break;
       
     default:
           mode=0x000001e0;
     break;
    
    }
    
    //printk("led ioctl cmd:%d%d%ld\r\n",cmd,arg,mode);
    if(arg ==0 ) {writel(mode, pio_base + PIO_CODR);}
    else 
    {writel(mode, pio_base + PIO_SODR);}
     return 0;
}
static struct file_operations led_fops = {
     .owner = THIS_MODULE,
     .read = led_read,
     .write = led_write,
     .ioctl = led_ioctl,
};
static int led_init(void){
     int result;
     printk(KERN_ALERT "led_test:%s,%s\r\n",__DATE__,__TIME__);
     pio_base = ioremap(0xFFFFF400,512);            
     writel(0x000001e0, pio_base + PIO_PER);     
     writel(0x000001e0, pio_base + PIO_PUER);    
     
     writel(0x00000ff0, pio_base + PIO_ODSR);    
     writel(0x000001e0, pio_base + PIO_OER);     
     
     result = register_chrdev(60, "led", &led_fops);
     if (result < 0){
         printk("register device fail.\r\n");
 return result;
     }
     return 0;
}
static void led_exit(void){
printk("stop clear led\r\n");
     unregister_chrdev(60, "led");
     iounmap(pio_base);
     printk(KERN_ALERT "stop clear led\r\n");
}
module_init(led_init);
module_exit(led_exit);
 
编译好后,在运行之前,先要创建一个设备文件
# mknod "/dev/led" c 60 1
 
即创建一个主设备号为60,次设备号为1名称为LED的字符型设备。
然后运行这个函数即可看见LED开始闪烁。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(155)
发表于:2008-7-18 17:01:49
标签:9260EK-Hello模块  

1

9260EK-Hello模块

Hello模块
首先按规矩,先来一个Hello模块试试。
hello.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "(%d) Hello!\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye.\n");
}
module_init(hello_init);
module_exit(hello_exit);
 
Makefile文件
 
CC=arm-linux-gcc
obj-m   := hello.o 
KDIR   := /home/at91sam9260ek/linux-2.6.20
PWD   := $(shell pwd) 
default: 
    $(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers 
 
加载和卸载画面如下
 

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(192)
发表于:2008-7-18 17:00:27
标签:以9260EK-太网测试  

1

以9260EK-太网测试

以太网测试
先测试一下简单点的UDP通讯,做一个SERVER和一个CLIENT两个程序,SERVER程序在启动后会建立并绑定SOCKET,等待接收来自CLIENT的数据.CLIENT启动后会在建立SOCKET后,打开一个文本文件,并将读到的内容发到SERVER端。最后发送字符串STOP结束,终止SERVER和CLIENT之间的连接。
* udp_client.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port = 8000;
int main()
{
  int  sockfd;
  int  i=0;
  int  z;
  char buf[80],strl[80];
  struct sockaddr_in  adr_srvr;
  FILE *fp;
  
  /*打开product.txt文本文件*/
  printf("打开文件...\n");
  fp = fopen("product.txt","r");
  if (fp == NULL)
  {
    perror("open file");
    exit(1);
  }
  
  /*建立server ipv4 地址*/
  printf("连接Server..\n");
  bzero(&adr_srvr,sizeof(adr_srvr));
  adr_srvr.sin_family = AF_INET;
  adr_srvr.sin_addr.s_addr = inet_addr("192.168.1.196");
  adr_srvr.sin_port = htons(port);
  
  /*建立Socket*/
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockfd == -1 )
  {
    perror("socket error");
    exit(1);
  }
  
  /*连续读取product.txt 中的3笔数据给server*/
  printf("传送文件内容...");
  for(i=0;i<3;i++)
  {
    fgets(strl,80,fp);
    printf("第 %d 笔: %s\n",i,strl);
    sprintf(buf,"第 %d 笔: %s\n",i,strl);
    z = sendto(sockfd, buf, sizeof(buf), 0,
        (struct sockaddr *)&adr_srvr, sizeof(adr_srvr));
    if( z < 0)
    {
      perror("sendto error");
      exit(1);
    }
  }
  
  /*传送stop给server*/
  printf("传送结束字符串...");
  sprintf(buf,"stop\n");
    z = sendto(sockfd, buf, sizeof(buf), 0,
        (struct sockaddr *)&adr_srvr, sizeof(adr_srvr));
    if( z < 0)
    {
      perror("sendto error");
      exit(1);
    }
   
  fclose(fp);
  close(sockfd);
  printf("信息传送结束.\n");
  exit(0);
}
/* udp_server.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
int port = 8000;
int main()
{
  int  sockfd;
  int  len;
  int  z;
  char buf[256];
  struct sockaddr_in  adr_inet;
  struct sockaddr_in  adr_clnt;
  
  printf("等待Clint 端传输...\n");
  
  /*建立server ipv4 地址*/
  bzero(&adr_inet,sizeof(adr_inet));
  adr_inet.sin_family = AF_INET;
  adr_inet.sin_addr.s_addr = inet_addr("192.168.1.196");
  adr_inet.sin_port = htons(port);
  
  len = sizeof(adr_clnt);
  
  /*建立Socket*/
  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (sockfd == -1 )
  {
    perror("socket error");
    exit(1);
  }
  
  /*绑定Socket*/
  z = bind(sockfd,(struct sockaddr *)&adr_inet,sizeof(adr_inet));
  if (z == -1 )
  {
    perror("bind error");
    exit(1);
  }
  
  while(1)
  {  
  /*接收CLIENT 端传来的信息*/
    z = recvfrom(sockfd, buf, sizeof(buf), 0,
        (struct sockaddr *)&adr_clnt, &len);
    if( z < 0)
    {
      perror("recvform error");
      exit(1);
    }
  
    buf[z]=0;
    /*将接收到的信息显示在显示器上*/  
    printf("接收数据:%s",buf);
  
    /*收到stop字符串则结束与client端的连接*/
    if(strncmp(buf, "stop", 4) == 0)
    {
       printf("结束连接.\n");
       break;
    }
  }
  close(sockfd);
  exit(0);
}
注意所读的文件要提前手工建好。
并且SERVER端程序用gcc直接编译,CLIENT要用arm-linu-gcc编译。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(110)
发表于:2008-7-18 16:58:59
标签:以9260EK-串口测试程序  

1

以9260EK-串口测试程序

串口测试程序
由于已经完成了第一个HELLO程序,标志着整个编译环境已经没有问题了,下来准备做一下串口测试程序。由于串口驱动开发板已经作好了,所以就作一个简单的数据收发看看。
网上常见的版本都看起来比较烦琐,呵呵,写一个简单一点的,功能是收到10个字节后会发前7个字节,如果所发的数据的第一个字节是9则退出。
/* rs232_send.c*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>  
#include <string.h>
#include <unistd.h>
#include <errno.h>    
#include <stdlib.h>
 
#define  BAUDRATE      B115200//38400
#define  MODEMDEVICE   "/dev/ttyS1"
int main()
{
   int    fd,c=0,res;
   struct termios oldtio,newtio;
   int   ch;
   static char s1[20],buf[19];
   printf("start ...\n");
   /*打开PC的COM1口*/
   fd = open(MODEMDEVICE,O_RDWR|O_NOCTTY); 
   if (fd<0)
   {
      perror(MODEMDEVICE);
      exit(1);
   }
   printf("open...\n");
   /*将旧的通讯参数存入oldtio结构*/
   tcgetattr(fd,&oldtio);
   /*初始化新的newtio */
   bzero(&newtio,sizeof(newtio));
   /*8N1*/
   newtio.c_cflag = BAUDRATE|CS8|CLOCAL|CREAD;
   newtio.c_iflag = IGNPAR;
   newtio.c_oflag = 0;
   
   /*正常模式*/
   /*newtio.c_lflag = ICANON;*/
      
   /*非正常模式*/
   newtio.c_lflag = 0;
   newtio.c_cc[VTIME] = 0; 
   newtio.c_cc[VMIN] = 10; 
       
   tcflush(fd,TCIFLUSH);
   /*新的temios作为通讯端口参数*/
   tcsetattr(fd,TCSANOW,&newtio);
   printf("writing...\n");
   
   while(1)
   {
      res = read(fd,buf,10);
      res = write(fd,buf,7);
      if(buf[0]==9) break;
   }
   
   printf("close...\n");
   close(fd);
   /*还原旧参数*/
   tcsetattr(fd,TCSANOW,&oldtio);
   return 0;
}
还有一点要注意,就是串口有两种工作模式,即正规模式和非正规模式,如果习惯在串口调试器中用16进制发送,此时串口应该为非正规模式才行。
下面是这两种模式的说明
正规模式(CANONICAL或者COOKED)
此模式下,终端设备会处理特殊字符,并且数据传输是一次一行的方式,既按回车后才开始发送和接收数据。例如LINUX的SHELL。
非正规模式(NON-CANONICAL或者RAW)
此模式下,终端设备不会处理特殊字符,并且数据传输是一次一个字符的方式,既不用按回车换行。例如LINUX的VIM。

系统分类: ARM   |    用户分类:    |    来源: 原创

评论(0) | 阅读(113)
2下一页总共 , 当前 /