树莓派4上编译grblcontrol

问题描述

近段时间一直在做雕刻机这方面,刚好买了一个树莓派4,想着将grblcontrol放到树莓派4上运行。grblcontrol本身就可以在Linux下编译运行(得益于QT的跨平台)。之后我也在Ubuntu下编译了,完美运行。于是想着在树莓派上运行也是很简单的。。。。。


首先配置树莓派4的qt开发环境,本想着使用交叉编译,但是感觉太麻烦了,于是放弃。。。。。。直接在树莓派4上编译。
1、更新树莓派

sudo apt-get update
sudo apt-get upgrade
sudo rpi-update

2、安装qt5

sudo apt-get install qt5-default
sudo apt-get install qtcreator

3、准备工作
grblcontrol使用了串口和OpenGL,树莓派本身以及有了OpenGL,但是缺少qt5的串口模块,因此需要单独安装串口模块。

sudo apt-get install libqt5serialport5-dev libudev-dev

4、开始编译
使用命令行,进入grblcontrol源码的上层目录,创建一个build文件夹,之后使用qmake读取pro文件,再执行make即可。

mkdir build
cd build
qmake ../src/candle.pro
make

。。。。。。。。。。。于是报错一大堆。
首先就是找不到GLES/gl.h文件。但是使用find命令却可以找到,说明环境变量的配置有问题,但是在摸索了一段时间之后发现搞不定。。。。。。。。,但是问题还是要解决的。既然树莓派4本身已经支持了OpenGL,那么就不需要使用OpenGL es了。于是准备绕过OpenGL es,使用OpenGL。查看了文件,发现文件中是查看是否定义了一个GLES的宏来判断的,这个宏定义的位置在pro文件中

contains(QT_CONFIG, opengles.) {
    warning("GL ES detected. VAO will be disabled.")
    #DEFINES += GLES
    INSTALLS += target
    target.path = /home/pi
}

在这里将这个宏去掉,即可。
继续编译,发现又出现问题

<command-line>: note: this is the location of the previous definition
../src/widgets/glwidget.cpp: In member function ‘virtual void GLWidget::paintEvent(QPaintEvent*)’:
../src/widgets/glwidget.cpp:433:14: error: ‘GL_PROGRAM_POINT_SIZE’ was not declared in this scope
     glEnable(GL_PROGRAM_POINT_SIZE);
              ^~~~~~~~~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:433:14: note: suggested alternative: ‘GL_PROGRAM_PIPELINE’
     glEnable(GL_PROGRAM_POINT_SIZE);
              ^~~~~~~~~~~~~~~~~~~~~
              GL_PROGRAM_PIPELINE
../src/widgets/glwidget.cpp:437:30: error: ‘GL_MULTISAMPLE’ was not declared in this scope
         if (m_msaa) glEnable(GL_MULTISAMPLE); else {
                              ^~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:437:30: note: suggested alternative: ‘GL_MULTISAMPLES_NV’
         if (m_msaa) glEnable(GL_MULTISAMPLE); else {
                              ^~~~~~~~~~~~~~
                              GL_MULTISAMPLES_NV
../src/widgets/glwidget.cpp:438:20: error: ‘GL_LINE_SMOOTH_HINT’ was not declared in this scope
             glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
                    ^~~~~~~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:438:20: note: suggested alternative: ‘GL_LINE_STRIP’
             glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
                    ^~~~~~~~~~~~~~~~~~~
                    GL_LINE_STRIP
../src/widgets/glwidget.cpp:439:22: error: ‘GL_LINE_SMOOTH’ was not declared in this scope
             glEnable(GL_LINE_SMOOTH);
                      ^~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:439:22: note: suggested alternative: ‘GL_LINE_LOOP’
             glEnable(GL_LINE_SMOOTH);
                      ^~~~~~~~~~~~~~
                      GL_LINE_LOOP
../src/widgets/glwidget.cpp:440:20: error: ‘GL_POINT_SMOOTH_HINT’ was not declared in this scope
             glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
                    ^~~~~~~~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:440:20: note: suggested alternative: ‘GL_POINT_NV’
             glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
                    ^~~~~~~~~~~~~~~~~~~~
                    GL_POINT_NV
../src/widgets/glwidget.cpp:441:22: error: ‘GL_POINT_SMOOTH’ was not declared in this scope
             glEnable(GL_POINT_SMOOTH);
                      ^~~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:441:22: note: suggested alternative: ‘GL_POINT_NV’
             glEnable(GL_POINT_SMOOTH);
                      ^~~~~~~~~~~~~~~
                      GL_POINT_NV
../src/widgets/glwidget.cpp:472:15: error: ‘GL_MULTISAMPLE’ was not declared in this scope
     glDisable(GL_MULTISAMPLE);
               ^~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:472:15: note: suggested alternative: ‘GL_MULTISAMPLES_NV’
     glDisable(GL_MULTISAMPLE);
               ^~~~~~~~~~~~~~
               GL_MULTISAMPLES_NV
../src/widgets/glwidget.cpp:473:15: error: ‘GL_LINE_SMOOTH’ was not declared in this scope
     glDisable(GL_LINE_SMOOTH);
               ^~~~~~~~~~~~~~
../src/widgets/glwidget.cpp:473:15: note: suggested alternative: ‘GL_LINE_LOOP’
     glDisable(GL_LINE_SMOOTH);
               ^~~~~~~~~~~~~~
               GL_LINE_LOOP
make: *** [Makefile:921: glwidget.o] Error 1

可能是OpenGL的版本问题(不是很清楚),按照上面的提示,将对应的错误修改即可。

最后编译,完美通过。

<think>我们正在讨论树莓派4B上编译驱动代码的方法。根据引用内容,编译驱动通常需要先编译内核,因为驱动模块需要与当前运行的内核版本匹配。 编译驱动代码的方法有两种: 1. 直接编译进内核(静态) 2. 编译成可加载模块(动态),这样可以在系统运行时动态加载和卸载。 由于用户询问的是“编译驱动代码的方法”,我们重点放在如何编译成可加载模块(.ko文件)。 步骤概述: 1. 准备交叉编译环境(在PC上,通常是x86_64架构的Linux系统)。 2. 获取树莓派官方内核源码,并切换到与目标树莓派系统内核版本匹配的分支。 3. 配置内核,使用树莓派默认的配置文件(如bcm2711_defconfig,因为树莓派4B的SoC是BCM2711)。 4. 编译内核(或者只编译模块,但通常需要整个内核树来编译模块)。 5. 编写驱动代码(例如,一个简单的hello world模块)。 6. 编写Makefile,指定内核源码路径和交叉编译工具链。 7. 使用make命令编译驱动模块。 详细步骤: 1. 准备交叉编译环境 对于32位系统,交叉编译器为:`gcc-arm-linux-gnueabihf` 对于64位系统,交叉编译器为:`gcc-aarch64-linux-gnu` 安装方法(以Ubuntu为例): ```bash # 32位 sudo apt install gcc-arm-linux-gnueabihf # 64位 sudo apt install gcc-aarch64-linux-gnu ``` 2. 获取内核源码 ```bash git clone --depth=1 https://github.com/raspberrypi/linux ``` 然后切换到对应的分支。例如,树莓派4B当前使用的内核版本是5.10,那么可以: ```bash cd linux git checkout rpi-5.10.y # 请根据实际情况选择分支,使用命令`uname -r`在树莓派上查看内核版本 ``` 3. 配置内核 根据树莓派4B的配置进行配置(注意ARCH和CROSS_COMPILE的设置): ```bash # 对于32位内核 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig # 对于64位内核 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig ``` 4. 编译内核(如果需要整个内核,可以执行,但编译模块时也会用到内核源码树,所以这一步可以跳过,因为编译模块时会自动编译依赖的部分) 但是,为了确保内核源码树已经准备好,我们可以先编译一下内核,但这一步很耗时。也可以只准备必要的内容: ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- prepare make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- scripts ``` 或者直接编译整个内核(如果需要): ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j4 # 根据CPU核心数调整j后面的数字 ``` 5. 编写驱动代码(例如hello.c) ```c #include <linux/init.h> #include <linux/module.h> static int __init hello_init(void) { printk(KERN_INFO "Hello, world!\n"); return 0; } static void __exit hello_exit(void) { printk(KERN_INFO "Goodbye, world!\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple example Linux module."); ``` 6. 编写Makefile 在驱动代码的同一目录下,创建Makefile: ```makefile KERNEL_DIR ?= /path/to/linux # 替换为内核源码的路径 ARCH ?= arm CROSS_COMPILE ?= arm-linux-gnueabihf- obj-m := hello.o all: make -C $(KERNEL_DIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules clean: make -C $(KERNEL_DIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) clean ``` 注意:对于64位,设置ARCH=arm64,CROSS_COMPILE=aarch64-linux-gnu- 7. 编译驱动 ```bash make ``` 编译成功后,会生成hello.ko文件。 8. 将hello.ko复制到树莓派上,然后加载模块: ```bash sudo insmod hello.ko ``` 使用`dmesg`查看输出信息。 注意事项: - 内核源码的版本必须和树莓派上运行的内核版本一致,否则模块无法加载(会提示版本不匹配)。 - 如果树莓派上运行的是32位系统,则编译32位模块;如果是64位系统,则编译64位模块。 另外,如果只是想编译一个驱动模块,而不需要编译整个内核,那么可以只在内核源码树外部编译模块(如上述步骤),但需要确保内核源码树已经配置好(执行过make ... defconfig和必要的prepare等)。 引用中提到的将内核拷贝到SD卡等步骤,是针对内核编译的,如果只是编译驱动模块,则不需要替换整个内核,只需要将编译好的模块复制到树莓派即可。 参考链接: [^1]: 树莓派4B内核编译。 [^2]: Linux —— 树莓派4B的内核编译。 [^3]: 树莓派4B编译以及烧录kernel的步骤记录。 §§相关问题§§ 1. 如何编写一个简单的Linux内核模块? 2. 如何解决树莓派驱动模块版本不匹配的问题? 3. 树莓派4B上如何动态加载和卸载驱动模块? </think>### 树莓派4B编译驱动代码的方法 在树莓派4B上编译驱动代码的核心是**内核级开发**,需确保驱动模块与内核版本严格匹配。以下是具体步骤(基于引用内容优化): --- ### **步骤1:准备编译环境** 1. **安装交叉编译器**(PC端操作) - **32位系统**: ```bash sudo apt install gcc-arm-linux-gnueabihf ``` - **64位系统**: ```bash sudo apt install gcc-aarch64-linux-gnu ``` > 交叉编译器需与树莓派系统架构一致[^3]。 2. **获取内核源码** ```bash git clone --depth=1 https://github.com/raspberrypi/linux cd linux ``` > 切换分支至树莓派当前内核版本(通过`uname -r`查看)[^2]。 --- ### **步骤2:配置内核** - **32位系统**: ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfig ``` - **64位系统**: ```bash make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig ``` > 使用`bcm2711_defconfig`(树莓派4B专用配置)[^3]。 --- ### **步骤3:编译驱动模块** 1. **编写驱动代码**(如`mydriver.c`) ```c #include <linux/module.h> static int __init mydriver_init(void) { printk("Driver loaded\n"); return 0; } module_init(mydriver_init); ``` 2. **创建Makefile**: ```makefile obj-m += mydriver.o KERNEL_DIR ?= /path/to/linux # 替换为内核源码路径 all: make -C $(KERNEL_DIR) M=$(PWD) modules ``` 3. **执行编译**: ```bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- # 32位 # 或 make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- # 64位 ``` > 生成`.ko`驱动模块文件(如`mydriver.ko`)[^1]。 --- ### **步骤4:部署驱动到树莓派** 1. **复制模块文件**: ```bash scp mydriver.ko pi@树莓派IP:~/ ``` 2. **树莓派端加载驱动**: ```bash sudo insmod mydriver.ko # 加载驱动 dmesg | tail # 查看驱动输出 ``` --- ### **关键注意事项** 1. **内核版本匹配** 驱动模块必须与树莓派运行的内核版本一致,否则加载失败。使用`uname -r`验证[^2]。 2. **依赖安装** 编译前安装必要依赖: ```bash sudo apt install bc build-essential flex bison libssl-dev ``` 3. **源码分支** 通过`git checkout rpi-5.15.y`切换到对应分支(以实际内核版本为准)。 > 完整流程参考:[树莓派内核编译指南](https://www.raspberrypi.com/documentation/computers/linux_kernel.html)[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值