历史上的今天
返回首页

历史上的今天

今天是:2025年12月16日(星期二)

正在发生

2022年12月16日 | 友善之臂之mini22440开发环境搭建

2022-12-16 来源:zhihu

最近在学习嵌入式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


推荐阅读

史海拾趣

CTS公司的发展小趣事

CTS公司,全称CTS Corporation,于1896年在美国印第安那州创立。在创立初期,公司主要生产和销售电器元件,凭借对技术的深入理解和市场需求的敏锐洞察,逐渐在行业中崭露头角。随着业务的扩展,CTS的产品线逐渐丰富,涵盖了汽车及电脑配件、通讯产品、精密仪器及装置等多个领域。

Advanced_Linear_Devices_Inc.公司的发展小趣事

在电子行业的快速发展中,ALD以其创新的CMOS技术崭露头角。1985年,公司创立之初,便致力于研发小功率线性集成电路,为线性工程师提供标准产品和定制方案。经过团队的不懈努力,ALD成功开发出了一系列具有高精度和低功耗特点的CMOS线性集成电路,这些产品在工业控制、电子仪器等领域得到了广泛应用,为公司的快速发展奠定了坚实基础。

Cellergy公司的发展小趣事

为了进一步扩大市场份额,Cellergy公司积极寻求与其他电子企业的战略合作。通过与一家知名电子产品制造商的合作,Cellergy公司的电容器产品得以进入更广阔的市场。双方共同研发新产品,共享技术和市场资源,实现了互利共赢。这一合作不仅提升了Cellergy公司的知名度,也为其带来了更多的商业机会。

Base Two (2) Systems公司的发展小趣事

Base Two (2) Systems公司自创立之初,便以技术创新为核心竞争力。在创始团队的带领下,公司研发团队不断攻克技术难关,成功研发出一系列具有领先水平的电子产品。这些产品不仅性能卓越,而且具有广泛的应用前景,为公司在市场上赢得了良好的口碑。

Bestar Electric公司的发展小趣事

随着电子行业的快速发展和市场竞争的加剧,Bestar Electric面临着诸多挑战。为了应对这些挑战,公司不断调整战略方向,加大研发投入,提升产品技术含量和附加值。同时,公司还注重人才培养和团队建设,吸引了一批优秀的研发、销售和管理人才,为公司的发展提供了有力保障。

Advanced Illumination Inc公司的发展小趣事

在成功开发出优质产品后,Ai公司开始积极拓展市场。公司通过参加各种行业展会、举办技术研讨会等方式,与潜在客户进行深入交流,成功将产品推广至全球范围。同时,公司还注重品牌建设,通过广告宣传、媒体报道等手段提升品牌知名度和美誉度。这些举措使得Ai公司的产品在市场上获得了广泛的认可。

问答坊 | AI 解惑

基于CAN总线的多功能汽车行驶记录仪设计

1.  概述汽车行驶记录仪,又称“汽车黑匣子”,是对车辆行驶速度、时间、里程以及有关车辆行驶的其他状态信息进行记录、存储并可通过接口实现数据输出的数字式电子记录装置[1]。多功能汽车行驶记录仪可详细记录车辆每次的起动时间、行驶里程、 ...…

查看全部问答>

51下实现汉字输入,“搞”们请出招

声明关于在51下实现汉字输入(不包括汉字库和联想汉字等)我真没干过,最多是土得掉渣的数码管,和LCD下的汉字临时型几个汉字字符提示!但对汉字的输入从没干过,最近一个汽车项目要用,我目前选用的51片子,程序空间只有12K,所以希望用简易输入法 ...…

查看全部问答>

关于ARM嵌入式集成开发环境的问题

用ADS 1.2是不是太旧了??大家都用什么开发环境的? 谢谢了!! …

查看全部问答>

mfc编程的局域网IP电话

求wince下 mfc编程的局域网IP电话 有的大侠 麻烦给个被,dedong001@163.com 着急用啊…

查看全部问答>

wince 电源电量

界面已做好 ,有一个按钮,请在按钮的响应事件里添加代码 要求得出 剩余电量的百分比。 谢谢…

查看全部问答>

摄像头

飞思卡尔摄像头…

查看全部问答>

如何將應用程序源碼放入PB中,作為PB的組件一起編譯

如何將應用程序源碼放入PB中,作為PB的組件一起編譯。就好像加入自己開發的組件一樣。然后,讓應用程序能夠正常在編譯後運\行...…

查看全部问答>

HardFaultException

                                 请教斑竹:我有一块ST32103ZE的评估板,通过realview 可以下载,也可以跑起来,但就是不能调试, 具体现象是 ...…

查看全部问答>

-stack 40

我在书上看到CMD文件里有 -stack 40 请问这是什么意思? 希望高手不吝赐教,多谢!…

查看全部问答>