AM335x+Linux移植SGX+OpenGL+Qt5

AM335X外部看门狗及LINUX系统驱动移植(二) 看门狗定时器(WDT,Watch Dog Timer)是嵌入式系统的的一个组成部分,它实际上是一个计数器,一般给看门狗设置复位时间间隔,程序开始运行后看门狗开始计数。如果程序运行正常,过一段时间CPU应发出指令让看门狗置零,重新开始计数。如果看门狗增加到设定值就认为程序没有正常工作,强制整个系统复位。 所以,当开启看门狗后,需要在看门狗超时(计数减到0)前,对其进行喂狗(复位)操作,否则看门狗会发出复位信号,当CPU接收到该信号将复位系统。 以TPL5010为例,介绍在AM335x平台上的使用,主要内容 阅读详情

这里的主机是64位的ACER 5745DG,安装了桌面发行版Fedora20,桌面环境是GNOME。
这里的目标板是 CortexA8 的 AM335x ,安装了之前编译好的 U-Boot 、 Kernel 和 Filesystem ,安装的过程见《 U-Boot for AM335x 》、《为 AM335x移植Linux内核主线代码 》系列。
 
Step 1: Install Qt for Master
 
给主机安装Qt的方法可以非常简单粗暴:
yum install qt5*
yum install qt-creator
 
当然也可以不使用这样简单粗暴的“全部的通通的安装”的方式,而是选择需要的组件来安装,比如:
yum install qt5-qtbase
yum install qt5-qttools
 
安装完成之后,文件系统会增加以下的内容:
/usr/bin/qmake-qt5
/usr/bin/qtcreator
/usr/share/qt5/
/usr/share/qtcreator/
/usr/lib64/qt5/
/usr/lib64/qtcreator/
 
执行一个示例程序试试:
[maria@localhost ~]$ cd /usr/lib64/qt5/examples/quick/demos/clocks/
[maria@localhost lighting]$ ./clocks
 
NOTE:也可以采用编译源代码的方式来安装。在解压后的源代码目录下执行:
[maria@localhost qt-x86]$ ./configure -opensource -confirm-license -debug -prefix ../../build -platform linux-g++ -v
[maria@localhost qt-x86]# gmake -j8
[maria@localhost qt-x86]# gmake -j8 install
 
编译过程大概会花两个小时,完成之后运行示例程序,和使用yum来安装的效果是一样的:
[maria@localhost qt]$ cd ../build/examples/quick/demos/clocks/
[maria@localhost lighting]$ ./clocks
 
NOTE:configure命令中-prefix的“当前目录”为源代码目录下的qtbase。
NOTE:readelf命令可以用来观察可执行文件需要的动态库和装载器,从而知道动态链接的库为什么找不到。
NOTE:ldd命令可以用来观察可执行文件的库依赖。
NOTE:rpm -qf命令可以用来观察库文件所属的软件包。
NOTE: sync将内存缓存的文件强制写入磁盘,使用tftp获取文件之后,需要先执行sync再断电。
 
Step 2: About SGX
 
在编译目标板Qt之前,先要理解什么是SGX:
The SGX subsystem is a Texas Instruments instantiation of the POWERVR SGX530 core form Imagination Technologies Ltd.
The 2D/3D graphics accelerator (SGX) subsystem accelerates 2-dimensional (2D) and 3-dimensional (3D) graphics applications. The SGX subsystem is based on the POWERVR SGX core from Imagination Technologies. SGX is a new generation of programmable POWERVR graphic cores. The POWERVR SGX530 v1.2.5 architecture is scalable and can target all market segments from mainstream mobile devices to high-end desktop graphics. Targeted applications include feature phone, PDA, and hand-held games.
 
 
TI SOCs例如AM335x,具备3D核心,它能够使用dedicated hardware进行3D加速;而这里的delicated hardware就基于SGX技术;
Graphics cores是用来加速图形的,它并没有video decode功能,视频加速神马的和它没有关系;
视频加速和OpenGL ES1.1 OpenGL ES2.0有关(不推荐使用OpenVG 1.1),它们需要调用SGX驱动;
OpenGL可以做成单独的application,也可以做成Android、Qt、Xrog等的back-end。
 
SGX core没有包含在ARM核里,但是它的Graphics drivers需要跑在ARM核上(所有的东西都需要跑在ARM核上),怎么办呢?其实Graphics drivers包含有OS specific driver ,它能够将SGX core做内存映射,因此可在ARM core上对图形引擎SGX编程。
 
到这里为止,是不是弄清楚了SGX、OpenGL、Qt之间的关系了呢?(^ - ^)
首先,移植Qt需要指定它的platform,也就是eglfs、directfb、linuxfb等等;
其次,安装eglfs需要OpenGL图形库;
最后,OpenGL会调用SGX,驱动delicated hardware;
 
Linux的mainline里面并没有SGX Driver,因为TI公司并没有将其开源。TI公司不开源的代码极少,SGX是其中之一(也许是唯一一个)。
因为SGX的驱动不开源,所以必须要使用TI公司提供的SDK包,将二进制可执行文件打包进内核。
另外,在编译SGX之前,还要先制作编译好的Kernel和目标文件系统,以及为主机安装ssh、ftp、tftp服务。
 
Step 3: Install SSH, FTP, TFTP Services
 
为了调试的方便,这里为主机安装SSH、FTP、TFTP服务:
[root@localhost maria]# yum install vsftpd
[root@localhost maria]# yum install ftp
[root@localhost maria]# yum install tftp-server
[root@localhost maria]# yum install tftp
[root@localhost maria]# service sshd start
[root@localhost maria]# service vsftpd start
[root@localhost maria]# service tftp start
 
网络功能对于嵌入式Linux的调试是非常重要的,正常工作的网络能够大大节省调试的时间。
当然,串口也是非常重要的。
 
Step 4: Make the Kernel
 
内核需要修改,是因为Graphics SDK会调用内核的公共函数地址入口,有一些函数是TI提供的内核里面存在,而mainline的内核里面没有的。看起来貌似要修改的地方很多,其实关键只有两个内容:reset_controller和register_vsync_cb。
 
A. 修改memuconfig中有关reset的内容:
使用make menuconfig命令,使能RESET_CONTROLLER:
CONFIG_RESET_CONTROLLER=y
这一步是必须的,因为PVR服务的pvrsrvkm模块用到了很多reset_control_*函数。
 
B. 为drivers/reset/core.c文件添加如下内容:
int reset_control_is_reset(struct reset_control *rstc)
{
if (rstc->rcdev->ops->is_reset)
return rstc->rcdev->ops->is_reset(rstc->rcdev, rstc->id);
return -ENOSYS;
}
EXPORT_SYMBOL_GPL(reset_control_is_reset);
 
int reset_control_clear_reset(struct reset_control *rstc)
{
if (rstc->rcdev->ops->clear_reset)
return rstc->rcdev->ops->clear_reset(rstc->rcdev, rstc->id);
return -ENOSYS;
}
EXPORT_SYMBOL_GPL(reset_control_clear_reset);
这两个函数会给Graphics SDK调用,因此需要定义它们。重新编译之后,函数名会内核源代码根目录下的System.map文件中出现。
 
C. 为include/linux/reset-controller.h文件添加如下内容:
struct reset_control_ops {
int (*reset)(struct reset_controller_dev *rcdev, unsigned long id);
int (*assert)(struct reset_controller_dev *rcdev, unsigned long id);
int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id);
int (*is_reset)(struct reset_controller_dev *rcdev, unsigned long id);
int (*clear_reset)(struct reset_controller_dev *rcdev, unsigned long id);
};
相应的为 reset_control_ops结构体增加成员变量。
 
D. 为include/linux/reset.h文件添加如下内容:
int reset_control_reset(struct reset_control *rstc);
int reset_control_assert(struct reset_control *rstc);
int reset_control_deassert(struct reset_control *rstc);
int reset_control_is_reset(struct reset_control *rstc);
int reset_control_clear_reset(struct reset_control *rstc);
相应的为头文件做声明。
 
E. 为arch/arm/boot/dts/am33xx.dtsi文件添加如下内容:
prcm: prcm@44e00000 {
compatible = "ti,am3-prcm";
reg = <0x44e00000 0x4000>;
#reset-cells = <1>;
prcm_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
prcm_clockdomains: clockdomains {
};
};
sgx@0x56000000 {
compatible = "ti,sgx";
ti,hwmods = "gfx";
reg = <0x56000000 0x1000000>;
interrupts = <37>;
resets = <&prcm 0>;
};
这是devicetree的内容。
如果看不懂dts文件的格式,可以阅读内核文档Documentation/devicetree/booting-without-of.txt 。
 
F. 添加ti_reset.c文件:
drivers/reset/core.c文件声明了一个结构体struct reset_control,它的定义则由函数of_reset_control_get返回,并且在返回之前给其成员变量struct reset_controller_dev *rcdev赋值。
of_reset_control_get函数被reset_control_get函数调用;reset_control_get函数被SGX的PVRSRVDriverProbe函数调用。
 
在继续调试之前,先来理解list_for_each:
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
        for (pos = (head)->next; pos != (head); pos = pos->next)                      \
             pos = list_next_entry(pos, member))
pos是循环变量,相当于for循环里面的i;head是链表list的表头;list_next_entry展开得到:
container_of((pos)->member.next, typeof(*(pos)), member);
container_of的原型是container_of(ptr, type, member) ,它是一个非常常见的宏定义,含义是,返回type类型的地址,type类型包含了member类型,而ptr是实际的member类型指针。所以list_next_entry的含义是,返回一个typeof(*(pos))的地址,它包含有member这个类型,且(pos)->member.next指向这个member。
 
再来理解 list_for_each_entry:
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \
pos = list_next_entry(pos, member))
pos是循环变量,相当于for循环里面的i;head是链表list的表头;member是被包含的类型定义;
首先,pos 初始化为typeof(*pos) 类型的指针,它包含有member 类型,且member 的地址为head->next ;
然后,如果没有循环返回到head ,则pos 会指向包含有(pos)->member.next 的pos 类型地址。
所以,of_reset_control_get函数中的list_for_each_entry(r, &reset_controller_list, list)含义是:
r相当与for循环里面的i,指向下一个被操作的struct reset_controller_dev;reset_controller_list是链表的表头;
首先,r初始化为struct reset_controller_dev类型的指针,它包含有list类型,且list的地址为(&reset_controller_list)->next;
但是已知 reset_controller_list在此文件头被初始化了,它是一个空链表:
static LIST_HEAD(reset_controller_list);
因此为了让list_for_each_entry 得到有效的执行,即得到可用的rcdev ,需要执行reset_controller_register 函数。
So,将TI公司提供的内核中的ti_reset.c拷贝到driver/reset目录下,它包含有关键的注册操作,即reset_controller_register函数。
另外,不要忘记修改Makefile和Kconfig。
另外,不要忘记把ti_reset.c中的.compatible值改为和am33xx.dtsi文件中相同的"ti,am3-prcm"。
 
G. 为drivers/video/fbdev/da8xx-fb.c文件添加如下内容:
static vsync_callback_t vsync_cb_handler;
static void *vsync_cb_arg;
 
int register_vsync_cb(vsync_callback_t handler, void *arg, int idx)
{
if ((vsync_cb_handler == NULL) && (vsync_cb_arg == NULL)) {
vsync_cb_arg = arg;
vsync_cb_handler = handler;
} else {
return -EEXIST;
}
return 0;
}
EXPORT_SYMBOL(register_vsync_cb);
 
int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx)
{
if ((vsync_cb_handler == handler) && (vsync_cb_arg == arg)) {
vsync_cb_handler = NULL;
vsync_cb_arg = NULL;
} else {
return -ENXIO;
}
return 0;
}
EXPORT_SYMBOL(unregister_vsync_cb);
 
H. 为include/video/da8xx-fb.h文件添加如下内容:
typedef void (*vsync_callback_t)(void *arg);
int register_vsync_cb(vsync_callback_t handler, void *arg, int idx);
int unregister_vsync_cb(vsync_callback_t handler, void *arg, int idx);
 
是不是觉得内核的修改很复杂呢?其实它的主要功能,就是添加了一个reset_controller的platform设备,并且提供reset和vsync_cb函数供Graphics SDK调用。编译完内核,就可以进行文件系统的制作啦(^_^)
 
Step 5: Prepare the Filesystem
 
A. 新建目标文件系统:
[maria@localhost qt]$ mkdir /home/maria/qt/rootfs -p
它相当于目标文件系统的根目录。
 
B. 编译busybox,将输出拷贝到目标文件系统:
make ARCH=arm CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- all
make ARCH=arm CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- install
使用busybox默认配置即可,不用修改它。
之前在《为AM335x移植Linux内核主线代码》系列里,制作busybox的时候使用了静态编译,动态编译无法运行,这是因为动态编译的_install/bin/busybox找不到装载器。
 
[maria@localhost bin]$ /opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf-ldd --root ../../../rootfs.save busybox
libm.so.6 => /lib/libm.so.6 (0xdeadbeef)
ld-linux-armhf.so.3 => /lib/ld-linux-armhf.so.3 (0xdeadbeef)
libc.so.6 => /lib/libc.so.6 (0xdeadbeef)
 
解决的方法很简单,就是拷贝正确的装载器和库文件,放置在目标文件系统的正确位置即可,见接下来的步骤。
编译完成之后,将_install目录下的所有内容,拷贝到A步骤创建的rootfs下:
bin linuxrc sbin usr
 
C. 创建lib目录,拷贝库文件:
在目标文件系统的根目录下,创建lib目录;
一般这些库文件在交叉编译器安装目录下的libc里面,除了busybox需要的三个库文件之外,还有很多其他的库文件;
将这些库文件拷贝到lib目录中;
 
D. 创建etc目录,编辑需要的内容:
创建rc0.d、rc1.d、rc2.d、rc3.d、rc4.d、rc5.d、rc6.d、rcS.d八个目录;
将SDK开发包提供的文件系统中的etc/group、etc/passwd、etc/shadow三个文件拷贝过来;
将SDK开发包提供的文件系统中的etc/default/rcS文件拷贝过来;
将SDC开发包提供的文件系统中的etc/inittab文件拷贝过来;
将SDC开发包提供的文件系统中的etc/fstab文件拷贝过来;
将SDC开发包提供的文件系统中的etc/init.d/rc、/etc/init.d/rcS文件拷贝过来;
 
E. 创建dev、home、home/root、media、mnt、opt、proc、sys、var目录:
无需拷贝dev文件,因为内核会生成它们。
将目标文件系统拷贝到SD卡的rootfs分区,然后将SD插入目标板,上电运行,串口终端会出现启动信息,最终出现登陆提示符。这说明,Linux的runlevel 3已经可以正确运行了。
 
NOTE:将飞凌提供init.sysvinit拷贝到sbin目录下。
NOTE:将飞凌提供的ethtool拷贝到sbin目录下。
NOTE:将Graphics SKD编译出来的devmem2拷贝到sbin目录下。
NOTE:记得在lib下创建modules/3.18.4目录;
NOTE:这里要在rcS文件的倒数第二个非空行添加:
echo "mount -o remount,rw /dev/root"
mount -o remount,rw /dev/root
这样启动的时候就不用手动执行mount命令了。
 
Step 6: Make the SDK
 
从TI官网下载最新版的Graphics SDK:
 
编译Graphics SDK之前,需要编译一次内核,因此Graphics SDK需要调用内核符号表,最好是确保它一直是最新的。
Graphics SDK不会对内核做任何修改,它只会更改目标文件系统。
 
如果Graphics SDK编译成功,应该能够生成omaplfb.ko、pvrsrvkm.ko、bufferclass_ti.ko三个模块文件,并且它们能够被内核正确加载。omaplfs负责和framebuffer的接口,pvrsrvkm负责和用户层服务的接口, bufferclass_ti负责使用proprietary extension,它允许streaming playback through SGX。除了模块文件外,它还会生成OpenGL ES11/20/VG的二进制可执行文件,供用户的程序调用。
 
[maria@localhost graphics]$ ./Graphics_SDK_setuplinux_hardfp_5_01_01_02.bin –help
[maria@localhost graphics]$ ./Graphics_SDK_setuplinux_hardfp_5_01_01_02.bin –prefix \
/home/maria/qt/graphics/Graphics_SDK_5_01_01_02
(好像Fedora21只能使用--mode console,--mode standard没有效果,而且使用—es8.x参数会出现error。)
 
为源代码根目录下的vim Rules.make文件,添加这四个变量(换成自己的实际路径):
SDK_INSTALL_DIR=/home/maria/qt
LINUX_DEVKIT_PATH=/opt/i686-arago-linux/usr
LINUXKERNEL_INSTALL_DIR=$(HOME)/linux-3.18.4-v3
DESTDIR=$(HOME)/rootfs
 
另外,如果你使用的是Graphics_SDK_5_01_01_01,还需要将GFX_Linux_KM/services4/3rdparty/dc_ti335x_linux/Kbuild文件的EXTRA_CFLAGS修改过来,因为3.18.4的内核将omap2目录放置在了driver/video/fbdev目录下,而不是driver/video目录:
EXTRA_CFLAGS = -DLINUX \
-DCONFIG_OMAP2_DSS \
-I$(PVR_BUILD_DIR)/include4 \
-I$(PVR_BUILD_DIR)/services4/include \
-I$(PVR_BUILD_DIR)/services4/system/$(PVR_SYSTEM) \
-I$(KERNELDIR)/drivers/video/omap2 \
-I$(KERNELDIR)/drivers/video/fbdev/omap2 \
-I$(PVR_BUILD_DIR)/services4/system/include \
$(SYS_CFLAGS.1) \
 
然后在源代码根目录下执行make命令(注意ARCH必须以环境变量的形式出现):
[maria@localhost Graphics_SDK_5_01_01_02]$ export ARCH=arm
[maria@localhost Graphics_SDK_5_01_01_02]$ make help
[maria@localhost Graphics_SDK_5_01_01_02]$ make CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- BUILD=debug OMAPES=8.x FBDEV=yes SUPPORT_XORG=0 all
[maria@localhost Graphics_SDK_5_01_01_02]$ make CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- BUILD=debug OMAPES=8.x FBDEV=yes SUPPORT_XORG=0 install
 
执行完毕之后,会发现目标文件系统的opt下增加了两个目录(etc目录下也有增加的内容,暂时可不考虑它们)。
将gfxlibraries、gfxsdkdemos这两个目录拷贝到目标文件系统下,将文件系统放置进SD卡,上电启动:
~ # cd /opt/gfxsdkdemos/
/opt/gfxsdkdemos # ./335x-demo
/* 很多的打印信息 */
PVR: High Water Mark = 0 bytes
Loaded PowerVR consumer services.
/opt/gfxsdkdemos # lsmod
omaplfb 12320 0 - Live 0xbf08a000 (O)
pvrsrvkm 470425 1 omaplfb, Live 0xbf000000 (O)
 
如果lsmod命令执行的结果如上所示,说明模块被正确的加载,Graphics SDK的驱动部分就制作成功啦。
由上面的调试过程也可以知道,遇到问题的时候不要害怕找不到解决方法,因为阅读README和源代码总是能有非常大的帮助,而且由于Linux本身代码的健壮性,摸索它的脉络是相对容易的,它不会像糟糕的代码那样给人一团乱麻的感觉。
 
Step 7: Use the SDK
 
首先要修改bootargs:
修改bootargs有很多种方法,比如在编译内核的menuconfig时修改其Boot options,或者修改U-Boot里面的config文件,或者在U-Boot运行时指定,等等。由于U-Boot在autoboot的时候会读取boot分区下的uEnv.txt文件,因此将bootargs添加在这个文件中:
bootargs=console=ttyO0,115200n8 root=/dev/mmcblk0p2 rootwait init=/sbin/init.sysvinit mem=1024M vram=50M
bootcmd=mmc rescan; fatload mmc 0 0x82000000 uImage; \
fatload mmc 0 0x83000000 maria-am335x.dtb; bootm 0x82000000 - 0x83000000
uenvcmd=boot
这个uEnv.txt的内容是,设置bootargs,并且设置U-Boot自启动时从SD卡读取dts和uImage。
U-Boot是非常轻量且灵活的,它给人很多意想不到的惊喜。
 
运行gfxsdkdemos目录下的示例:
~ # cd /opt/gfxsdkdemos/ogles2/
/opt/gfxsdkdemos/ogles2 # ./OGLES2ChameleonMan
/opt/gfxsdkdemos/ogles2 # ./OGLES2MagicLantern
/opt/gfxsdkdemos/ogles2 # cd /opt/gfxsdkdemos/ogles/
/opt/gfxsdkdemos/ogles # ./OGLESEvilSkull
/opt/gfxsdkdemos/ogles # ./OGLESFilmTV
 
运行OGLES2ChameleonMan这个程序的时候,有没有觉得画面上的这个人跑得很快,图形也没有命令行界面下的拖影呢(好吧,可能只是俺的心理作用~)。
 
Step 8: Build Qt
 
(NOTE:触摸屏tslib的调试暂时不考虑。)
到目前为止的目标文件系统,具备了那些内容呢:
有etc目录和其中的启动文件,有存放在bin、sbin目录下的busybox可执行程序,lib库,其他目录如home、media、mnt、proc等,以及存放在opt目录下的Graphics SDK,包括它的库文件、驱动文件和demo文件。只有demo文件无错误的运行在目标板上了,才可以往下进行,否则,要继续修改Kernel代码或者Graphics SDK编译方式。
 
准备好文件系统,以及解压Qt源代码:
[maria@localhost qt-am335x]$ mkdir roofts.withSDK
[maria@localhost qt-am335x]$ cp ../ro otfs/* rootfs.withSDK/ -rv
[maria@localhost qt-am335x]$ tar xvf ../qt-everywhere-opensource-src-5.4.1.tar.gz -C .
 
从下面这个地址下载qmake.conf文件,并将它复制进Qt源代码目录,并根据主机的实际情况修改内容:
 
[maria@localhost qt-am335x]$ tar xvf Linux-TIarmv7-sgx-g++.tar.gz
[maria@localhost qt-am335x]$ ln -s qt-everywhere-opensource-src-5.4.1 qt-everywhere
[maria@localhost qt-am335x]$ cp linux-TIarmv7-sgx-g++ qt-everywhere/qtbase/mkspecs/device/ -r
[maria@localhost qt-am335x]$ vim qt-everywhere/qtbase/mkspecs/device/linux-TIarmv7-sgx-g++/qmake.conf
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
 
include(../../common/linux.conf)
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
 
load(device_config)
QT_QPA_DEFAULT_PLATFORM = eglfs
 
QT_INSTALL_DIR = /home/maria/qt/qt-am335x/qt-everywhere/qtbase
SGX_SDK_ROOT = /home/maria/qt/graphics/Graphics_SDK_5_01_01_02
 
COMPILER_FLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
QMAKE_CFLAGS_RELEASE = -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
QMAKE_CXXFLAGS_RELEASE = -O3 -march=armv7-a -mtune=cortex-a8 -mfpu=vfpv3 -mfloat-abi=hard
 
QMAKE_CC = arm-linux-gnueabihf-gcc
QMAKE_CXX = arm-linux-gnueabihf-g++
QMAKE_LINK = arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++
QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_STRIP = arm-linux-gnueabihf-strip
QMAKE_NM = arm-linux-gnueabihf-nm -P
 
QMAKE_INCDIR_OPENGL_ES2 = $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES2/SDKPackage/Builds/OGLES2/Include/
QMAKE_INCDIR_OPENGL_ES2 += $$SGX_SDK_ROOT/include
QMAKE_INCDIR_OPENGL_ES2 += $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/
QMAKE_LIBDIR_OPENGL_ES2 = $$SGX_SDK_ROOT/gfx_dbg_es8.x/
QMAKE_LIBS_OPENGL_ES2 = -lEGL -lGLESv2 -lGLES_CM -lIMGegl -lsrv_um -lusc
 
QMAKE_INCDIR_OPENGL += $$SGX_SDK_ROOT/GFX_Linux_SDK/OGLES/SDKPackage/Builds/OGLES/Include/
QMAKE_LIBDIR_OPENGL = $$SGX_SDK_ROOT/gfx_dbg_es8.x
QMAKE_LIBDIR_OPENGL_QT = $$SGX_SDK_ROOT/gfx_dbg_es8.x
QMAKE_LIBS_OPENGL_ES1 = -lEGL -lGLES_CM -lIMGegl -lsrv_um -lusc
 
QMAKE_INCDIR_OPENVG = $$SGX_SDK_ROOT/GFX_Linux_SDK/OVG/SDKPackage/Builds/OVG/Include/
QMAKE_LIBDIR_OPENVG = $$SGX_SDK_ROOT/gfx_dbg_es8.x/
QMAKE_LIBS_OPENVG = -lEGL -lGLESv2 -lGLES_CM -lIMGegl -lsrv_um -lOpenVG -lOpenVGU
 
QMAKE_INCDIR_EGL = $$QMAKE_INCDIR_OPENGL_ES2
QMAKE_INCDIR_EGL += $$QT_INSTALL_DIR/src/3rdparty/powervr/wsegl2
QMAKE_INCDIR_POWERVR = $$QT_INSTALL_DIR/src/3rdparty/powervr/wsegl2
QMAKE_LIBDIR_EGL = $$QMAKE_LIBDIR_OPENGL_ES2
QMAKE_LIBS_EGL = -lEGL -lIMGegl -lsrv_um -lGLESv2 -lGLES_CM -lusc
 
QMAKE_INCDIR += $$QMAKE_INCDIR_OPENGL_ES2
QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2
QMAKE_LIBS = $$QMAKE_LIBS_OPENGL_ES2 -lts -lrt -lpthread
 
deviceSanityCheckCompiler()
load(qt_config)
NOTE:修改qmake.conf文件,要特别注意它的inluce目录、交叉编译器的设置,以及INCDIR和LIBDIR是否正确;
NOTE:对比Qt的mainline里面的qmake.conf,观察它新增的内容;
NOTE:$$QT_INSTALL_DIR/src/3rdparty/powervr/wsegl2这个目录并不存在,但并不影响编译结果;
 
另外还要将交叉编译器的bin目录加入环境变量PATH,拷贝头文件和lib(为了省事可以把lib的内容全都拷贝进目标文件系统,但是这里还是暂时采取需要什么就拷贝什么的方法,你甚至先什么都不做,等到编译报错的时候再去寻找对应的lib或者头文件,这样能够更加清晰的理解Qt的编译过程),再执行configure和make步骤:
 
[maria@localhost qt-everywhere]$ export PATH=$PATH:/opt/i686-arago-linux/usr/bin
[maria@localhost qt-everywhere]$ mkdir /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/include /home/maria/qt/qt-am335x/roofts.withSDK/usr/ -r
 
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/crt* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libts* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/librt.* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libpthread* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libm.* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libc.* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libc_nonshared.a* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libz.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libjpeg.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libpng* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libnsl.* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libgthread-2.0.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libglib-2.0.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libasound.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libdl.* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libfreetype.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/glib-2.0 /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/ -r
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libfontconfig.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libexpat.so* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libdbus* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libu* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
[maria@localhost qt-everywhere]$ cp /opt/ti-sdk-am335x-evm-07.00.00.00/linux-devkit/sysroots/cortexa8hf-vfp-neon-3.8-oe-linux-gnueabi/usr/lib/libglslcompiler* /home/maria/qt/qt-am335x/roofts.withSDK/usr/lib/
 
另外,还要将目标文件系统的include/freetypes2/freetype软链接成include/freetype:
[maria@localhost qt-everywhere]$ cd /home/maria/qt/qt-am335x/roofts.withSDK/usr/include
[maria@localhost include]$ ln -s freetype2/freetype freetype
(如果freetypes报错了就做此修改,没有报错的话就不用管了~)
 
[maria@localhost qt-everywhere]$ ./configure –help
[maria@localhost qt-everywhere]$ ./configure \
-debug -opensource -confirm-license -shared \
-prefix /home/maria/qt/qt-am335x/qt-everywhere/build \
-sysroot /home/maria/qt/qt-am335x/roofts.withSDK \
-platform linux-g++-64 \
-device linux-TIarmv7-sgx-g++ \
-device-option CROSS_COMPILE=/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf- \
-D QT_NO_QWS_CURSOR -D QT_QWS_CLIENTBLIT \
-eglfs -opengl es2 -qreal float -v \
-nomake examples -nomake tests
 
NOTE:configure的编译选项,需要根据主机和目标板的实际情况慢慢摸索,有的编译选项随着新版本的发布不再支持,有的编译选项被添加在新版本中,有的编译错误即使存在也没有关系,有的编译错误则会影响结果。一般来说,提示“Just run 'gmake'”就算是成功。
NOTE:configure会生成很多.o文件,在重新configure之前可以编写脚本,来删除旧有的.o文件。
 
-prefix: 主机上Qt SDK安装的目录;
-sysroot: 目标文件系统的根目录;
-platform: 主机使用的mkspecs;
-device: 目标机使用的mkspecs,替代xplatform;
-nomake examples -nomake tests: 不编译示例和测试程序,否则得花很长的时间;
 
[maria@localhost qt-everywhere]$ gmake -j8
[maria@localhost qt-everywhere]$ gmake -j8 install
 
这里的gmake,是指GNU Make,在Fedora主机上就是make;
编译完成之后,会发现目标文件系统里面增加了build 目录:
[maria@localhost roofts.withSDK]$ find . -mmin 1
./home/maria/qt/qt-am335x/qt-everywhere/build/*
 
接下来编译示例程序(qmake为上步编译时生成,在/home/maria/qt/qt-am335x/qt-everywhere/build目录下):
[maria@localhost qt-everywhere]$ cd qtbase/examples/
[maria@localhost examples]$ ../../build/bin/qmake examples.pro
[maria@localhost examples]$ gmake -j8
[maria@localhost examples]$ gmake -j8 install
 
编译完成之后,会发现目标文件系统里面增加了build/examples目录:
[maria@localhost roofts.withSDK]$ find . -mmin 1
./home/maria/qt/qt-am335x/qt-everywhere/build/examples/*
 
将./home/maria目录拷贝到SD的目标文件系统里;
将./usr/lib和./usr/include也拷贝到SD卡的目标文件系统里;
运行Graphics SDK的335x-demo;
此外,还需要执行下面的步骤(Qt程序会试图获取/etc/machine-id的值,如果运行示例程序时报错,可以主机上的machine-id文件拷贝过来,另外还要设置屏幕的分辨率值):
~ # tftp 192.168.1.118 -g -l machine-id
~# cp machine-id /etc/
~ # export QT_QPA_EGLFS_PHYSICAL_HEIGHT=272
~ # export QT_QPA_EGLFS_PHYSICAL_WIDTH=480
 
然后执行Qt的示例程序(如果报找不到platform的错误信息,则执行第二条):
~ # /home/maria/qt/qt-am335x/qt-everywhere/build/examples/widgets/widgets/digitalclock/digitalclock
~ # /home/maria/qt/qt-am335x/qt-everywhere/build/examples/widgets/widgets/digitalclock/digitalclock -platform eglfs
 
到这里,就可以看到液晶上显示的数字时钟啦~
运行Qt程序的时候,可能会发现终端会打印出很多错误,但是不要害怕这些错误,它们提示的信息往往非常关键,比如需要设置哪些环境变量,或者缺乏哪些库文件或者头文件。另外,arm-linux-gnueabihf-ldd和readelf是非常有用的工具,通过它们来观察.so或者可执行程序,往往能够发现很多问题的答案。
 
Step 9: Build Qt Programs
 
编写Qt程序,首先要具备C++基础知识;
 
A. 打开主机上的Qt Creator:
B. 创建一个新项目:
File -> New File or Project -> Application -> Qt Widgets Application
将名字设置为serial_test,目录设置为/home/maria/qt/qt_workspace/serial_test;
然后在manage里面,添加新的Kit:
为Qt Versions添加:/home/maria/qt/qt-am335x/qt-everywhere/build/bin/qmake
为Compilers添加:/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf-gcc
为Debuggers添加:/opt/i686-arago-linux/usr/bin/arm-linux-gnueabihf-gdb
为Kits添加新的am335x-kit,并将其sysroot、Compiler、Debugger等选成实际的交叉编译类型。
选择Kits为刚刚创建的am335x-kit,然后一路点击next。
 
C. 将以前的项目mainwindow.ui替代新项目的mainwindow.ui:
D. 将以前的项目mainwindow.h替代新项目的mainwindow.h:
E. 将以前的项目mainwindow.cpp替代新项目的mainwindow.cpp:
(其实我也不想这样的偷懒,但是以前在主机上编写了一个简单的串口应用,正好可以拿来搞这个^_^)
F. 编译项目:
Build -> Build All
G. 将可执行文件拷贝到目标板运行:
生成的可执行文件,存放在serial_test/build-serial_test-am335x-Debug目录下,将它拷贝到目标板上:
~ # tftp 192.168.1.118 -g -l serial_test
~ # chmod +x serial_test
~ # ./serial_test
然后可以看见serial_test的程序界面出现在液晶上,编写基础的Qt应用真的是很简单,因为它的开发环境和跨平台特性都非常的完善^_^。
到这里,SGX+OpenGL+Qt5移植在AM335x+Linux上的基本步骤就算是完成了,虽然还有触摸屏tslib和字体的问题待解决,但还是不放在本文中啦,maybe以后调试的时候再补充进来。
 
Step 10: About Linux
 
后记:为什么要选择Linux做硬件开发?
 
如果Linux真的像很多人所认为的装x专用,毫无用户体验可言,它不会受到那么多人的喜爱。它所能提供的通透、自由和参与的感觉,是做技术的人不可抗拒的诱惑。它的结构极其健壮简洁,并没有很多内容来帮助用户,因此你需要花时间(对我来说是很长的时间)去学习它,但是随着学习的深入,你会发现一个自由的世界打开,你能用极其合理的开销实现非常强大的功能。
 
对于计算机来说,你不是用户,而是上帝。
 
使用Linux环境做硬件开发,也是同样的感受,随着开发的进行,你会发现你不仅知道怎么做可以实现硬件的功能,你还能知道为什么要这样做。Linux对它的使用者完全真诚,它只忠实于事物本身的逻辑,而不会为自身的利益为使用者做任何决定,所有的决定都是为了一个最优的最合理的最强壮的未来,它每一个透明的自由的部件,最终提供给了使用者unlimited possibility。
 
Free不是免费,free是自由,你,值得拥有。
AM335x的QT5开发环境搭建-开发板AM335x EVM 用TI官方的SDK配置Qt的交叉编译 SDK版本是ti-processor-sdk-linux-am335x-evm-02.00.02.11-Linux-x86-Install.bin QT creator版本是最新的qt-opensource-linux-x64-5.7.0.run 开发板是AM335x EVM 阅读详情

相关推荐

omap3530支持gpu模块

在操作过程中如果遇到什么问题,可以直接1157207468@qq.com 或者 留言 进行沟通,如果有什么错误,也请大家进行指出。环境: ubuntu 10.04  linux-2.6.32 omap3530芯片一共含有三个核: arm核, dsp核, gpu核。arm核是最常用的,这不是我们今天说的主题,我们现在主要是说一下gpu核,将gpu的驱动添加到arm平台上,就可在omap3530上跑o...

linux 807

内核proc文件系统与seq接口(1)---内核proc文件系统简介

/proc文件系统是一个特殊的由内核创建的文件系统,她仅存在于内存之中而不在外存(硬盘、flash)上。内核用她来向用户空间进程输出消息,可以说是内核向用户空间打开的一扇窗户。       最初开发/proc文件系统是为提供一种内核及其模块向进程 (process) 发送信息的机制 (这就是proc名字的由来)。这个虚拟文件系统让你可以和内核内部数据结构进行交互,获取对于进程的有用信息,并可

dolphin98629的专栏 907

BeagleBone Green LCD Cape开发实战:驱动配置、图形界面与性能优化

嵌入式系统的人机交互(HMI)开发是连接硬件与用户的关键环节,其核心在于通过图形界面实现信息的可视化与操作的直观化。其技术原理通常涉及显示驱动、输入设备管理和图形渲染框架。在嵌入式Linux平台上,设备树(Device Tree)是描述和配置硬件的标准机制,它定义了外设的连接与资源分配,是驱动加载的基础。图形应用开发则可根据需求选择轻量级的Framebuffer方案(如SDL、GTK+直接渲染)或功能完整的X Window方案(如Qt、PyGTK)。这些技术的价值在于能快速构建稳定、高效的交互界面,降低开发

weixin_30216561的博客 507

为AM335x+Linux移植SGX+OpenGL+Qt5之完全开发笔记

 这里的主机是64位的ACER 5745DG,安装了桌面发行版Fedora20,桌面环境是GNOME。 这里的目标板是CortexA8的AM335x,安装了之前编译好的U-Boot、Kernel和Filesystem,安装的过程见《U-Boot for AM335x》、《为AM335x移植Linux内核主线代码》系列。   Step 1: Install Qt for Mast

jzjhome的博客 9099

达梦数据库连接报错6001网络通信异常

本文主要记录客户端连接达梦数据库报错6001网络通信异常问题分析过程、问题原因以及问题解决方法。

chen_zizi2025的博客 2773

PCIe ATS介绍

主机侧使用IOMMU完成设备地址到物理memory地址的转换,以及设备访问权限的检查。但如果所有PCIe设备都在进行DMA操作,则TA(Translation Agent)和ATPT(Address Translation and Protection Table)则会成为瓶颈,从而影响系统的latency。

maxwell2ic的博客 6023

AM335X/A40I平台 QT4.8移植和QT应用开发连载(四)

中,或在编译的时候指定路径。指定路径的方法请参考:光盘linux\linux_api\CoM335x_linux_API使用手册 中附录部分:应用程序调用库函数过程演示。以EVB-335X qt界面程序为例,将光盘中:linux\test_code\qtdemo1程序源码拷贝到虚拟机linux下,定位到代码目录。本文记录了QT4.8平台在AM335X/A40I等现在流行嵌入式平台的移植过程,说明过程中可能会技术瑕疵,希望大家提供宝贵意见。支持SDIO3.0,USB2.0 HOST&OTG,

szembed的博客 313

opencv实践项目-图片拼接之缝合线算法

opencv 图片缝合线算法

wyw0000的博客 2624

Linux主线内核移植,为AM335x移植Linux内核主线代码(32)从U-Boot到内核

虽然这个系列主要是Linux内核移植的笔记,但是从第(7)到第(31)全部写的是U-Boot的内容。这些有关U-Boot的内容本来应该放在之前的《U-Boot for AM335x》系列里面,但是因为《U-Boot for AM335x》系列已经结束了,而移植Linux内核时调试硬件,U-Boot起的作用又非常大,因此还是放在了本系列中。Anyway,since现在硬件调试已经告一段落,接下来就是...

weixin_30092051的博客 484

SAP成本核算的核心逻辑

SAP成本核算采用"计划-归集-分析"闭环管理,以CO模块为核心,集成PP、MM等模块。核算前需配置标准成本控制范围、成本中心等主数据。标准成本通过BOM和工艺路线计算(CK11N),采购和生产过程记录实际成本差异。制造费用通过成本中心归集,作业成本按实际耗用量分配。完工产品按标准成本入库,月末通过KO88结算工单差异,物料分类账(CKMLCP)还原实际成本。整个流程实现FI与CO数据同步,确保账务一致。关键事务码包括CK11N(成本估算)、MIGO(物料移动)、CO11N(报工)等。

金牌架构师 539

YOLOv11改进策略【Neck】| PRCV 2023,SBA(Selective Boundary Aggregation):特征融合模块,描绘物体轮廓重新校准物体位置,解决边界模糊问题

SBA 模块在医疗图像分割中具有重要作用,其设计出发点是解决图像中物体边界模糊以及融合特征时的冗余和不一致问题。

Limiiiing的博客 1943

Android内存分析和调优(下)

最后一部分是关于native heap,.dex,/dev/other的优化。 Native Heap分析和优化 android的DDMS可以帮助查看c++ native heap的使用,但需要一定的配置,而且必须是root的手机。 在~/.android/ddms.cfg增加"native=true"。这样子ddms才会有native heap的tab。 指向下面adb命令打开mal...

weixin_30879169的博客 455

Python 实战:爬取高德地图交通数据(路况拥堵指数分析)

高德地图是由高德软件有限公司开发的一款地图导航产品,提供详细的地图浏览、路线规划、实时路况、公共交通查询等功能。高德地图拥有庞大的用户群体和海量的交通数据,这些数据对于交通管理、城市规划、出行服务等领域具有重要的价值。通过对高德地图交通数据的分析,我们可以了解城市交通的运行状况,识别拥堵路段,预测交通流量,为交通管理部门和出行者提供决策支持。

yansideyucsdn的博客 2687

Graphics SDK Quick installation and user guide

参考:http://processors.wiki.ti.com/index.php/SGXDbg#Introduction The latest Linux Graphics SDK can be downloaded from the below link. The download does not require any registration. http://s

yibulianhua的专栏 2284

基于simulink的车道保持辅助系统(LKA)的仿真与实现

本文介绍了如何利用Simulink实现车道保持辅助系统(LKA)的仿真与建模。首先对比了车道偏离预警(LDW)和LKA的功能差异,强调LKA的主动干预特性。接着详细阐述了LKA系统架构,包括环境感知、决策控制等核心组件,并基于自行车模型建立车辆横向动力学方程。 文章重点演示了Simulink建模步骤:搭建车辆动力学模型、设计LKA控制器(采用LQR算法)、实现执行器接口和驾驶员干预检测。通过四个典型场景的仿真测试,验证了系统在直道行驶、弯道跟踪等工况下的控制性能,并给出了关键评价指标。最后展望了MPC控制、

amy_mhd的博客 228

RTOS与Linux功能差异与应用场景全面对比

在嵌入式系统的开发中,操作系统的选择至关重要。和是两种广泛应用的操作系统,它们在功能、设计目标以及应用领域中各具优势。随着嵌入式系统的不断发展,已成为嵌入式行业的大趋势。那么,这两者到底有什么不同呢?

硬核科技 402

linux内核移植步骤3.14,am335x_linux-3.14.43内核移植笔记

本文主要描述在EVB335X-II以Device Tree的方式移植新TI官网AM335X系列最新的linux-3.14.43版本内核以及移植Debian文件系统的过程及遇到的一些问题。整个Device Tree牵涉面比较广,即增加了新的用于描述设备硬件信息的文本格式(即.dts文件),又增加了编译这一文本的工具,同时Bootloader也需要支持将编译后的Device Tree传递给Linux内...

weixin_30120421的博客 698

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

全志平台Android 系统调试方法(1)系统内存调试

以下技术在盈鹏飞嵌入式的A40I/T3核心板(CoM-X40I)和主控板(SBC-X40I)上经过验证,欢迎 交流! CoM-X40I核心板和SBC-X40I主板见下图: 1. 前言 总结Android调试过程中关于系统内存方面的方法 2. 内存调试 Adb shell dumpsys procstats --hours X adb remount adb push cpu_monitor /sys

szembed的博客 1148

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Linux Kbuild工作原理分析(以DVSDK生成PowerVR显卡内核模块为例)

Linux内核是一种单体内核,但是通过动态加载模块的方式,使它的开发非常灵活方便。那么,它是如何编译内核的呢?我们可以通过分析它的Makefile入手。以下是一个简单的hello内核模块的Makefile. ifneq ($(KERNELRELEASE),) obj-m:=hello.o else KERNELDIR:=/lib/modules/$(shell uname

GQB的专栏 5960

AM335x使用tslib实现QT5校准

本文使用的文件系统是Ti的ti-processor-sdk-linux-am335x-evm-06.03.00.106。官方说明,触摸校准使用weston-calibrator或使用tslib库。参照(有些链接仅自己查资料的记录): https://e2e.ti.com/support/processors/f/791/p/903802/3342761?tisearch=e2e-sitesearch&amp;keymatch=ts_calibration#3342761 I apologize for th

pingis58的博客 3004

在嵌入式linux上玩OpenGL

在我的嵌入式linux上板子资源和性能还是有限。想玩下OpenGL,倒不是板子flash或内存太小,而是底层图形接口是基于framebuffer的dev/fb0的,在标准的OpenGL下不支持。网上了解到在嵌入式linux或单片机上,可以跑OpenGL的一个子集,叫做TinyGL。OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。

猫哥 的沉淀、积累、总结。天天学习,好好向上...c/c++,嵌入式 linux,Android,HarmonyOS,AIOT) 5223

am3354 SGX移植续

am3354 SGX移植续概要问题解决方法 概要 本文接上一篇文章《am3354 SGX移植》,记录下实际开发过程中遇到的问题。 问题 具体移植步骤可以参考上篇文档,这里说下开发中遇到的问题。在运行./335x-demo时,提示omaplfb: OMAPLFBInitFBDev: Device 0: Unknown FB format错误。 # ./335x-demo 0x10205 releas...

xyxujinlong的专栏 1017

2026山东大学软件学院创新项目实训(团队——7)

本次 GPU 排查主要围绕系统图形栈完整性展开,通过从底层硬件到上层接口逐层验证,确认当前设备已经完成 GPU 软件栈集成。GPU 是否被识别;驱动是否加载;固件是否存在;用户态接口是否连接;显示链路是否正常。通过本次检查,确认 OpenHarmony 平台上的 PowerVR GPU 已经具备硬件加速能力,为后续图形性能优化、应用运行以及系统完善提供了基础。

2301_80463926的博客 374

AM335x添加QT开机自启动

本文使用的文件系统是Ti的ti-processor-sdk-linux-am335x-evm-06.03.00.106。首先开发板的文件使用的是systemd 并没有/etc/rc.local文件 所以要想修改rc.local这一简单的操作已经不存在 但是也是可以用systemd和initd两种方式解决这个问题 Systemd Systemd 是系统启动和服务器守护进程管理器,负责在系统启动或运行时,激活系统资源,服务器进程和其它进程。 systemd被设计用来改进sysvinit的...

pingis58的博客 1183
上一篇: MIPI D-PHY介绍
下一篇: linux驱动由浅入深系列:camera驱动之一(背景及基础知识篇)
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值