【Orangepi Zero2 全志H616】驱动OLED屏应用-IIC协议、设备的映射(mmap)

news2024/10/1 7:31:19

一、OLED屏幕
二、Orangepi的IIC接口
三、wiringPi库示例代码
四、Source insight 初步分析wiringP源码OLED_DEMO
五、设备的映射
六、mmap函数
七、简单OLED屏幕开发及实现

一、OLED屏幕

在这里插入图片描述

二、Orangepi的IIC接口

1) 由 26pin 的原理图可知, Orange Pi Zero 2 可用的 i2c 为 i2c3

在这里插入图片描述
在这里插入图片描述

sudo vim /boot/orangepiEnv.txt

overlays=i2c3

在这里插入图片描述

ls /dev/i2c-*

在这里插入图片描述

2. 启动 linux 系统后, 先确认下 /dev下存在 i2c-3 的设备节点

从命令运行结果能观察到系统支持I2C-3和I2C-5的驱动,而H616的外设我们看到只有一个IIC接口,用的是IIC-3
Linux一切皆文件,每个硬件设备“对应”一个文件,由驱动程序提供映射

cd /dev

在这里插入图片描述

3. 开始测试 i2c, 首先安装 i2c-tools

sudo apt-get install i2c-tools

在这里插入图片描述

4. 列出连接到I2C总线的设备的地址

sudo i2cdetect -y 3

在这里插入图片描述

三、wiringPi库示例代码

在这里插入图片描述

cp wiringOP/examples/oled_demo.c orangeOP/
cd orangeOP/
./build.sh oled_demo.c
sudo ./a.out /dev/i2c-3

在这里插入图片描述

/*
 * Copyright (c) 2015, Vladimir Komendantskiy
 * MIT License
 *
 * SSD1306 demo of block and font drawing.
 */

//
// fixed for OrangePiZero by HypHop
//

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

#include "oled.h"
#include "font.h"

int oled_demo(struct display_info *disp) {
	int i;
	char buf[100];

	//putstrto(disp, 0, 0, "Spnd spd  2468 rpm");
	//	oled_putstrto(disp, 0, 9+1, "Spnd cur  0.46 A");
	oled_putstrto(disp, 0, 9+1, "Welcome       to");
	disp->font = font1;
	//	oled_putstrto(disp, 0, 18+2, "Spnd tmp    53 C");
	oled_putstrto(disp, 0, 18+2, "----OrangePi----");
	disp->font = font2;
	//	oled_putstrto(disp, 0, 27+3, "DrvX tmp    64 C");
	oled_putstrto(disp, 0, 27+3, "This is 0.96OLED");
	oled_putstrto(disp, 0, 36+4, "");
	oled_putstrto(disp, 0, 45+5, "");
	disp->font = font1;
	//	oled_putstrto(disp, 0, 54, "Total cur  2.36 A");
	oled_putstrto(disp, 0, 54, "*****************");
	oled_send_buffer(disp);

	disp->font = font3;
	for (i=0; i<100; i++) {
		sprintf(buf, "Spnd spd  %d rpm", i);
		oled_putstrto(disp, 0, 0, buf);
		oled_putstrto(disp, 135-i, 36+4, "===");
		oled_putstrto(disp, 100, 0+i/2, ".");
		oled_send_buffer(disp);
	}
	//oled_putpixel(disp, 60, 45);
	//oled_putstr(disp, 1, "hello");

return 0;
}

void show_error(int err, int add) {
	//const gchar* errmsg;
	//errmsg = g_strerror(errno);
	printf("\nERROR: %i, %i\n\n", err, add);
	//printf("\nERROR\n");
}

void show_usage(char *progname) {
	printf("\nUsage:\n%s <I2C bus device node >\n", progname);
}

int main(int argc, char **argv) {
	int e;
	char filename[32];
	struct display_info disp;

	if (argc < 2) {
		show_usage(argv[0]);
		
		return -1;
	}

	memset(&disp, 0, sizeof(disp));
	sprintf(filename, "%s", argv[1]);
	disp.address = OLED_I2C_ADDR;
	disp.font = font2;

	e = oled_open(&disp, filename);

	if (e < 0) {
		show_error(1, e);
	} else {
		e = oled_init(&disp);
	if (e < 0) {
		show_error(2, e);
	} else {
		printf("---------start--------\n");
		if (oled_demo(&disp) < 0)
			show_error(3, 777);
			printf("----------end---------\n");
		}
	}

	return 0;
}

-- VISUAL --                                                                              100       100,2         Bot

四、Source insight 初步分析wiringP源码OLED_DEMO

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

访问前要先开打设备驱动

在这里插入图片描述

# 五、设备的映射

mmap 可以用于映射设备文件,这是一种与文件映射相似的操作,但不是映射文件的内容,而是映射设备的内存地址范围。这使得你可以在用户空间直接访问设备的内存,而无需通过标准的读写操作进行通信。

设备映射通常用于以下场景:

  1. 直接内存访问(DMA)设备:一些硬件设备(如图形卡、网络适配器)允许通过DMA将数据传输到设备的内存。mmap 可用于映射这些设备内存,以便应用程序可以直接读写设备内存,而不必通过内核交互。

  2. 共享内存:设备映射允许多个进程或线程在用户空间共享设备内存。这对于高性能计算、数据传输和共享大量数据的应用程序非常有用。

  3. 加速硬件:一些硬件设备,如GPU,可以通过 mmap 实现与应用程序的高性能通信,以加速计算和数据处理。

以下是一个示例,演示如何使用 mmap 映射设备文件:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>

int main() {
    int fd = open("/dev/my_device", O_RDWR); // 打开设备文件,这里示意性地使用了"/dev/my_device"
    if (fd == -1) {
        perror("open");
        return 1;
    }

    size_t length = 4096; // 映射的长度,根据设备的需求设置
    void *map = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    
    if (map == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 使用指针 map 来访问设备内存
    // ...

    close(fd); // 关闭设备文件
    munmap(map, length); // 取消映射

    return 0;
}

在这个示例中,我们打开了一个设备文件(/dev/my_device 是一个示例设备文件路径),将设备内存映射到用户空间,然后可以使用 map 指针来访问设备内存。请注意,这个示例是简化的,实际应用中需要根据设备的特性和需求来使用 mmap
在这里插入图片描述

六、mmap函数

mmap 是一个UNIX和类UNIX操作系统上的系统调用,用于在进程的地址空间中映射文件或设备。这个系统调用通常用于实现内存映射文件和共享内存的操作。

mmap 的原型如下:

#include <sys/mman.h>

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

参数说明:

  • addr:指定映射区域的起始地址,通常设置为 NULL,让操作系统自动选择。
  • length:指定映射的长度,以字节为单位。
  • prot:指定映射区域的保护权限,如 PROT_READ(可读)、PROT_WRITE(可写)、PROT_EXEC(可执行)等。
  • flags:指定映射区域的标志,如 MAP_SHARED(共享映射)、MAP_PRIVATE(私有映射)等。
  • fd:指定要映射的文件的文件描述符。如果不是映射文件,可以设置为 -1
  • offset:指定文件中的偏移,通常设置为 0

mmap 函数允许你将文件或设备的内容映射到进程的地址空间中,使得进程可以通过内存操作来访问文件的内容,而不必直接读写文件。这有助于提高访问速度和简化文件操作。

示例用法:

#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    int fd = open("example.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    off_t file_size = lseek(fd, 0, SEEK_END);
    void *map = mmap(NULL, file_size, PROT_READ, MAP_SHARED, fd, 0);

    if (map == MAP_FAILED) {
        perror("mmap");
        return 1;
    }

    // 现在可以通过指针 map 访问文件的内容
    printf("File content: %s\n", (char *)map);

    close(fd);
    munmap(map, file_size);

    return 0;
}

上述示例打开一个名为 “example.txt” 的文件,将其内容映射到内存中,然后通过指针 map 访问文件的内容。最后,使用 munmap 函数取消映射并关闭文件描述符。这是 mmap 的一个简单示例,它可用于更复杂的应用,如共享内存、内存映射数据库等。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、简单OLED屏幕开发及实现

#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
 
#include "oled.h"
#include "font.h"
 
int oled_show(struct display_info *disp)
{ 
	int i; 
	char buf[100];
 
	oled_putstrto(disp, 0, 9+1, "Welcome to"); 
	disp->font = font1; 
	oled_putstrto(disp, 0, 18+2, " ---OrangePi--- "); 
	disp->font = font2; 
	oled_putstrto(disp, 0, 27+3, "DALI NIANGAO"); 
	disp->font = font3; 
 
	oled_send_buffer(disp); 
	
	return 0; 
}
 
void show_error(int err, int add) 
{ 
	printf("\nERROR: %i, %i\n\n", err, add); 
}
 
void show_usage(char *progname) 
{ 
	printf("\nUsage:\n%s <I2C bus device node >\n", progname); 
}
 
int main(int argc, char **argv) 
{ 
	int e; 
	char filename[32]; 
	struct display_info disp; 
 
	if (argc < 2) { 
		show_usage(argv[0]); 
		return -1; 
	}
 
	memset(&disp, 0, sizeof(disp)); 
	sprintf(filename, "%s", argv[1]); 
	disp.address = OLED_I2C_ADDR; 
	disp.font = font2; 
 
	e = oled_open(&disp, filename); 
	e = oled_init(&disp); 
 
	oled_show(&disp); 
 
	return 0; 
}
vim my_oled_demo.c
./build.sh my_oled_demo.c
sudo ./a.out /dev/i2c-3

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1180653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习(CNN+RNN)笔记2

文章目录 第五课&#xff1a;序列模型(Sequence Models)第一周&#xff1a;循环神经网络&#xff08;Recurrent Neural Networks&#xff09;【序列模型、语言模型序列生成、对新序列采样。RNN、GRU、LSTM、双向RNN、深度RNN】第二周&#xff1a;自然语言处理与词嵌入&#xff…

从受众吸引到客户:提高海外社媒转化率的10个技巧!

在当今数字化时代&#xff0c;社交媒体已经成为企业与海外市场互动的关键工具。然而&#xff0c;只有吸引了足够的受众并将他们转化为客户&#xff0c;社交媒体才能实现其真正的潜力。本文Nox聚星将给大家分享提高海外社交媒体的转化率的10个实用技巧&#xff0c;将潜在受众转化…

互联网医院|湖南互联网医院|解决医疗资源不足问题

随着科技的进步和互联网的普及&#xff0c;互联网医院作为一种新型的医疗模式&#xff0c;逐渐受到人们的关注和认可。本文将详细介绍互联网医院的功能和优势&#xff0c;帮助大家全面了解这种新型的医疗服务。 一、互联网医院的功能 1、在线问诊&#xff1a;互联网医院为患者…

[黑马程序员Pandas教程]——Pandas数据结构

目录&#xff1a; 学习目标认识Pandas中的数据结构和数据类型Series对象通过numpy.ndarray数组来创建通过list列表来创建使用字典或元组创建s对象在notebook中不写printSeries对象常用API布尔值列表获取Series对象中部分数据Series对象的运算DataFrame对象创建df对象DataFrame…

漏洞复现--用友NC accept.jsp任意文件上传

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

剑指JUC原理-14.ReentrantLock原理

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…

为什么免费证书的有效期为90天

关心SSL证书的朋友们最近可能发现&#xff0c;包括阿里云&#xff0c;亚洲诚信在内的SSL证书服务商&#xff0c;都已经陆续的把之前一年期的免费证书调整为90天有效期&#xff0c;之前的一年期证书价格从免费上涨到几十到几百元不等&#xff0c;这是为什么呢&#xff1f;为什么…

阿里云双十一活动经济型e实例2核2G3M带宽配置云服务器搭建网站教程参考

阿里云2023双十一推出的优惠活动“金秋云创季”&#xff0c;轻量应用服务器2核2G3M带宽只要87元1年&#xff0c;2核4G4M带宽只要165元1年。云服务ECS下的经济型e实例2核2G 3M固定带宽&#xff0c;价格只要99元/1年&#xff0c;新老用户都可购买&#xff0c;同时在2026年3月31日…

19、Python单元测试基础:unittest模块的基本使用

文章目录 创建测试用例测试套件断言运行测试测试固件Python的unittest模块是基于Java的JUnit框架开发出来的,提供了编写和运行单元测试的工具。这篇文章将介绍unittest模块的基本使用,涵盖创建测试用例、测试套件、断言、运行测试以及测试固件的使用。 创建测试用例 在unit…

“菊风Juphoon”邀您莅临11月22-24日CNF南京应急展消防展 | 展位号:115-1

公司简介 菊风依托互联网和电信网音视频融合技术积累&#xff0c;提供智能化的音视频统一通信产品及服务。面向应急管理、消防救援、智慧城市等多个领域&#xff0c;菊风推出适用于全网通的统一通信一体机、统一通信平台。 此外&#xff0c;菊风还提供视频能力平台&#xff0…

2 创建svelte项目(应用程序)

官网方式搭建&#xff1a; npm create sveltelatest my-app cd my-app npm install npm run dev 官网中介绍&#xff1a; 如果您使用的是 VS Code&#xff0c;安装 Svelte for VS Code 就可以了&#xff0c;以便语法高亮显示。 然后&#xff0c;一旦您的项目设置好了&#…

网上书店项目

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 程序运行视频查看 管理员 图书管理 添加图书 删除图书(可批量删除) 修改图书 查看图书(分页查看) 图书上下架(可批量处理) 图书推荐&#xff08;新品推荐、精品推荐&#xff0c;可批量处理&#…

IGP高级特性简要介绍(OSPF-上篇)

OSPF高级特性 一、OSPF_提升故障收敛及网络恢复速度 1.FRR与BFD快速恢复故障 1.1 FRR 在传统转发模式下&#xff0c;当到达同一个目的网络存在多条路由时&#xff0c;路由器总是选择最优路由使用&#xff0c;并且下发到FIB表指导数据转发。 当最优路由故障时&#xff0c;需…

辐射骚扰整改思路及方法:参数选择与解决之道?|深圳比创达电子EMC

辐射骚扰整改思路及方法&#xff1a;参数选择与解决之道&#xff1f;相信不少人是有疑问的&#xff0c;今天深圳市比创达电子科技有限公司就跟大家解答一下&#xff01; 某产品首次EMC测试时&#xff0c;辐射、静电、浪涌均失败。本篇文章就“参数选择与解决之道”问题进行详细…

Go语言Gin框架前后端分离项目开发工程化实例

文章目录 基本数据配置配置文件管理数据库配置路由配置封装公共方法 数据库模型数据表内容model文件DTO文件 中间件错误异常捕获中间件跨域中间件token认证中间件JWT 控制器UserController 运行调试注册接口登录接口获取用户信息 构建发布项目前端VUE调用接口 基本数据配置 配…

持续集成交付CICD:Jenkins Pipeline与远程构建触发器

目录 一、实验 1.Jenkins Pipeline本地构建触发器 2.Jenkins Pipeline与远程构建触发器&#xff08;第一种方式&#xff09; 3.Jenkins Pipeline与远程构建触发器&#xff08;第二种方式&#xff09; 4.Jenkins Pipeline与远程构建触发器&#xff08;第三种方式&#xff0…

Android 安卓 Soong构建系统——Blueprint Android.bp配置文件解析

文章目录 Android.bp起源Android.bp文件结构如何编写Android.bp文件实例详解实例1实例2 常见问题解答1. 如何确定使用哪种模块类型&#xff1f;2. 如何指定模块的依赖项&#xff1f;其他疑问可参考官方文档 参考文章&#xff1a;Android.bp 语法和使用 Android.bp起源 早期的A…

Python二级 每周练习题25

如果你感觉有收获&#xff0c;欢迎给我打赏 ———— 以激励我输出更多优质内容 练习一: 运算规则如下: (1) 若该数是偶数&#xff0c;&#xff0c;则变为原数的一半 (2) 若该数是奇数&#xff0c;则变为原数的3倍加1 (3) 重复 (1) (2)&#xff0c;直到该数变为1。 编写程序实…

Gradle笔记 二 Gradle的基础Groovy

学习Groovy的必要性 首先Gradle是由Groovy写成的&#xff0c;而且构建脚本的语法都遵循Groovy的语法&#xff0c;所以要学好Gradle的前提是要基本了解Groovy的语法。 Groovy 简介 在某种程度上&#xff0c;Groovy可以被视为Java的一种脚本化改良版,Groovy也是运行在JVM上&am…

什么是微服务?与分布式又有什么区别?

什么是微服务&#xff0c;我们先从传统的单体结构进行了解&#xff0c;对两者进行对比。 单体结构 单体结构是一种传统的软件架构模式&#xff0c;它将应用程序划分为一组相互依赖的模块和组件。这些模块和组件通常都是构建在同一个平台上的&#xff0c;并且紧密耦合在一起。…