友善之臂之mini22440开发环境搭建

发布时间:2022-12-16  

最近在学习嵌入式Linux驱动编程,平台是友善之臂的mini2440开发板,堪称经典古董级别的,不过在互联网上它的资料和视频教程非常多,适合初学者入门。在学习驱动的道路上走了很多弯路,十分坎坷,尤其在nfs挂载时涉及到windows, ubuntu, 开发板三者网络配置,需要设置bootloader启动参数,安装和配置 nfs。这篇文章基于以图片为主导,一步一步地介绍环境搭建过程,后面有的地方也是粗略介绍,仅作为参考;希望可以帮助一些驱动爱好者。

本篇主要介绍开发环境搭建,基于AMD A8或者intel i5和Windows10 企业版LTS。主要以下几点:

1.Windows版本的 VMWare workstation pro

2.Linux发行版 ubuntu 1604(友善之臂官方使用fedora 9)

3.编辑器vim

4.Linux版本的dnw

5.交叉编译工具arm-linux-gcc

6.编译和烧录bootloader

7.编译和烧录内核

8.制作根文件系统

9.NFS服务

10.通过NFS挂载根文件系统

11.Windows版本Jflash烧录软件

12.编写一个驱动demo


在环境搭建中,可能会遇到各种奇葩的问题,不要灰心,大部分百度哥都可以解决。

一、VMWare workstation pro

VMWare主要虚拟一台电脑硬件,可以安装Windows系列、Linux发行版操作系统,采用VMWare workstation pro 14版本,以下为安装过程:

1>打开安装向导界面,点击下一步

2>用户许可协议,接受许可协议中的条款,点击下一步

3>自定义安装,选择后点击下一步

4>用户体验设置,选择后点击下一步

5>快捷选择,根据喜好选择,点击下一步

6>安装过程

7>完成安装,点击许可证

8>输入许可证秘钥,填写后点击输入

9>点击完成

10>VMware Workstation 14 Pro 界面

在菜单栏->编辑->虚拟网络编辑器里进行网卡配置;

在菜单栏->虚拟机->设置里进行硬件、网络、共享文件夹设置;



二、ubuntu 1604

它是Linux发行版之一,属于ubuntu系列,目前最新LTS版本是1804。由于本人对ubuntu 1604比较熟悉,以此为例进行安装,之后工具安装全部基于此版本。

1>点击菜单栏->选项卡->主页,打开以下界面,点击创建新的虚拟机

2>虚拟机向导,选择自定义,点击下一步

3>兼容性,默认即可,点击下一步

4>选择稍后安装操作系统,点击下一步

5>选择Linux,ubuntu,点击下一步

6>选择安装位置,点击下一步

7>根据计算机配置,选择处理器核心,点击下一步

8>配置虚拟机内存,点击下一步

9>选择桥接网络,点击下一步

10>默认即可,点击下一步

11>默认即可,选择下一步

12>默认即可,点击下一步

13>默认即可,选择下一步

14>选择磁盘文件位置,点击下一步

15>点击自定义硬件

16> 选择新CD/DVD,使用ISO影响文件,确认文件位置,点击关闭

17>返回15,点击完成,如图界面,点击开启此虚拟机

18>选择安装时使用中文,点击安装Ubuntu

19>点击继续

20>点击现在安装

21>点击继续

22>选择时区,点击继续

23>点击继续

24>设置账户密码,点击继续

25 >正在安装

26>安装结束,点击现在重启

27>输入用户密码

28>ubuntu1604用户界面

29>Ctrl+Alt+t 打开一个终端

30>点击VMware菜单栏->虚拟机->安装VMware Tools,然后在ubuntu终端拷贝文件到家目录,然后进入VMware Tools目录解压文件

31>进入vmware-tools-distrib目录,执行脚本,输入y,一直回车点击

32>安装VMware Tools成功信息,然后可以自行在VMware菜单栏->虚拟机->设置->选项里指定共享文件夹,用于ubuntu和windows互传文件,这个文件夹会挂在ubuntu /mnt/htfs/目录下


三、vim

它是一个功能丰富的编辑器,提供了查找、替换、格式整理等功能。

打开一个终端,使用sudo apt install vim 命令安装,因为每个人使用vim习惯不同,所以自行配置。

四、dnw

它和bootloader结合使用,用于操作NandFlash,例如更新NandFlash上的bootloader、kernel、rootfs等映像。在互联网上下载dnw源码包,里面包含驱动模块源码,编译装载就可以了,具体使用的命令有:

sudo insmod *.ko

sudo rmmod *.ko

sudo ./dnw *.bin


五、arm-linux-gcc

交叉编译工具,用于编译源程序。

1>将共享文件夹中的压缩包拷贝到/tmp目录下,进行解压安装

2>将路径添加到环境变量中,在/etc/profile文件中加入

export PATH=$PATH: /opt/FriendlyARM/toolschain/4.4.3/bin

然后查看执行arm-linux-gcc -v 获得版本信息则安装成功


六、bootloader

引导加载程序,友善之臂supervivi是闭源的,因此无法获取源码。有兴趣的可以移植uboot,它功能十分强大,毫不逊色于supervivi。


七、kernel

1>安装字符终端处理库

2>将内核源码拷贝到/tmp目录下,进行解压

3>进入内核目录,选型后进行默认配置

4>内核图形化配置界面,使用默认配置,退出

5>修改kernel/timeconst.pl第373行

6>切换为root用户,生成内核镜像文件,时间比较长

7>进入arch/arm/boot目录,生成内核镜像zImage


八、rootfs

不具体介绍根文件系统制作方法,使用友善之臂发布的根文件系统即可

九、NFS

1->安装nfs服务器

2>执行sudo gedit /etc/exports,加入最后一行,设置访问目录和权限

3>配置windows, ubuntu,开发板网络,让其处于同一个网段,如下为ubuntu网络配置


十、mount

设置开发板启动参数,启动后把服务器:192.168.1.111:/home/hhw/rootfs_qtopia_qt4 目录挂在自己根目录上

十一、JFlash

结合JLink用于更新NorFlash上的bootloader

1>Jflash用户界面

2>在options->Projects settings设置接口,选择处理器型号等

3>点击Target->connect连接芯片,点击file->open data file选择镜像文件,然后点击target->manual->Programming进行烧录

十二、driver demo


驱动例程包含driver.c、app.c和Makefile,如下图。


driver.c


#include

#include

#include

#include

#include

#include



unsigned int *gpiob_base = NULL;

#define GPBCON (*(volatile unsigned int *)(gpiob_base))

#define GPBDAT  (*(volatile unsigned int *)(gpiob_base + 1))


static int chardev_open(struct inode *node, struct file *fp)

{

printk("%s is calledn", __FUNCTION__);

GPBCON &= ~(0x03 << 2*5);

GPBCON |= 0x01 << 2*5;

GPBCON &= ~(0x03 << 2*6);

GPBCON |= 0x01 << 2*6;

GPBCON &= ~(0x03 << 2*7);

GPBCON |= 0x01 << 2*7;

GPBCON &= ~(0x03 << 2*8);

GPBCON |= 0x01 << 2*8;

GPBDAT &= ~(0x0f << 5);

return 0;

}


static int chardev_release(struct inode *node, struct file *fp)

{

printk("%s is calledn", __FUNCTION__);

GPBCON &= ~(0x03 << 2*5);

GPBCON &= ~(0x03 << 2*6);

GPBCON &= ~(0x03 << 2*7);

GPBCON &= ~(0x03 << 2*8);

GPBDAT &= ~(0x0f << 5);

return 0;

}


static ssize_t chardev_read(struct file *fp, char __user *str, size_t size, loff_t *offset)

{

unsigned char buffer;

printk("%s is calledn", __FUNCTION__);

if(copy_to_user((void __user*)str, (void *)&buffer, 1) < 0) printk("copy_to_user errorn");

return 0;

}


static ssize_t chardev_write(struct file *fp, const char __user *str, size_t size, loff_t *offset)

{

int i;

unsigned char buffer;

printk("%s is calledn", __FUNCTION__);

if(copy_from_user(&buffer, str, 1) < 0) printk("copy_to_user errorn");

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

{

if((buffer >> i)&0x01) GPBDAT &= ~(0x20 << i);

else GPBDAT |= 0x20 << i;

}

return 0;

}


static long chardev_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)

{

int i;

printk("%s is calledn", __FUNCTION__);

switch(_IOC_DIR(cmd))

{

case 0x00: 

{

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

{

if((_IOC_TYPE(cmd) >> i)&0x01)

{

if((_IOC_NR(cmd) >> i)&0x01) GPBDAT &= ~(0x20 << i);

else GPBDAT |= 0x20 << i;

}

}

}

break;

case 0x01: break;

case 0x10: break;

case 0x11: 

break;

default : break;

}

return 1234;

}



static struct file_operations chardev_fops = 

{

.owner = THIS_MODULE,

.open = chardev_open,

.release = chardev_release,

.read = chardev_read,

.write = chardev_write,

.unlocked_ioctl = chardev_ioctl,

};


#define CHARDEV_NAME "leds_dri"

static struct miscdevice chardev = 

{

.minor = 255,

.name = CHARDEV_NAME,

.fops = &chardev_fops,

};


static int __init chardev_init(void)

{

printk("%s is calledn", __FUNCTION__);

gpiob_base = (unsigned int *)ioremap(0x56000010, 8);

if(misc_register(&chardev) != 0)

{

printk("misc_register errorn");

return -EBUSY;

}

printk("misc_register successn");

return 0;

}


static void __exit chardev_exit(void)

{

printk("%s is calledn", __FUNCTION__);

iounmap(gpiob_base);

if(misc_deregister(&chardev) != 0)

{

printk("misc_deregister errorn");

}

printk("misc_deregister successn");

}


module_init(chardev_init);

module_exit(chardev_exit);

MODULE_LICENSE("GPL");

app.c


#include

#include

#include

#include

#include

#include

#include


int main(int argc, char *argv[])

{

int i;

unsigned int cmd;

unsigned char iodata = 0x01;

int fd = open(argv[1], O_RDWR);

if(fd == -1)

{

perror("open");

return -1;

}

printf("open successn");

cmd = _IO(0x0f, 0x00);

ioctl(fd, cmd);

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

{

cmd = _IO(iodata, iodata);

ioctl(fd, cmd);

sleep(1);

cmd = _IO(iodata, 0);

ioctl(fd, cmd);

iodata <<= 1;

if(iodata == 0x10) iodata = 0x01;

}

close(fd);

        return 0;

}

Makefile


KDIR:=/opt/FriendlyARM/mini2440/linux-2.6.32.2

NAME=driver

obj-m += $(NAME).o

all:

make -C $(KDIR) M=$(PWD) modules

arm-linux-gcc app.c -o app.out

clean:

rm -f  *.o *.mod.o *.mod.c *.symvers *.markers *.order


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>