Kindle --FBInk绘图与zforce2 触摸应用开发

一、FBInk帧缓冲绘图

FBInk 是 Kindle/Kobo 电子墨水屏帧缓冲绘图工具,可以直接在 eInk 屏幕输出文字、图片、进度条、局部刷屏、清屏,无需调用系统 UI。 版本:FBInk v1.24.0-161-gb7a8146

设备识别信息前置:

复制代码
[FBInk] 检测到 Kindle Basic 2 (0KA -> 0x26A => Eanab Heisenberg)
[FBInk] 系统时钟频率:100 Hz
[FBInk] 屏幕DPI:167
[FBInk] 帧缓冲:600×800,8位色深,屏幕旋转 270°(逆时针)
[FBInk] 帧缓冲设备:mxc_epdc_fb,显存大小6537216字节,行宽608字节
[FBInk] 默认字体 16×16(基础8×8 IBM点阵字库)
[FBInk] 默认文本区域:37列 × 50行
[FBInk] 默认颜色:前景黑色,背景白色

1、 文本位置控制参数

基础语法:

复制代码
fbink [参数] [文本内容...]

|----------|--------------|-------------------------------------|
| 参数 | 全称 | 说明 |
| -x NUM | --col | 起始列,默认 0;负数代表从屏幕右侧倒数;建议起始≥1 避免被边框遮挡 |
| -y NUM | --row | 起始行,默认 0;负数代表从屏幕底部倒数;建议起始≥1 |
| -X NUM | --hoffset | 水平像素偏移(叠加在行列之上,可正负) |
| -Y NUM | --voffset | 垂直像素偏移 |
| -m | --centered | 文本水平居中 |
| -M | --halfway | 垂直居中;此时 -y 的数值是相对于屏幕中线的偏移量 |
| -p | --padded | 两端填充空格,配合 -m 实现整行居中铺满 |
| -r | --rpadded | 右侧填充空格 |

2、 文本外观控制参数

|------------|----------------|----------------------------------------------------------------|
| 参数 | 全称 | 说明 |
| -h | --invert | 反转颜色:背景色写字、前景色做底色(黑底白字) |
| -f | --flash | 刷新区域启用黑屏全刷(eink 清除残影,耗电更高) |
| -c | --clear | 打印前全屏清屏 ;仅清屏建议改用 -k |
| -k | --cls | 清屏(可全屏 / 局部矩形),执行完成直接退出,优先级最高 |
| -W MODE | --waveform | 指定墨水刷新波形:A2,DU,GC16,GL16,AUTO ;Kindle 额外支持 REAGL、GC16_FAST 等 |
| -D | --dither | 硬件抖动(仅新设备支持) |
| -H | --nightmode | 硬件全局反色(和 -h 可叠加) |
| -b | --norefresh | 只写入帧缓冲,不触发屏幕刷新,适合批量绘图,最后统一刷新 |
| -w | --wait | 阻塞等待内核刷新完成再返回 |
| -S NUM | --size | 字体缩放倍数,自动 = 0,范围 1~45 |
| -F NAME | --font | 内置点阵字体:IBM、UNSCII、THIN、TEWI、ORP、TERMINUS 等 |
| -C COLOR | --color | 文字颜色:BLACK、GRAY1~GRAYE、WHITE |
| -B COLOR | --background | 文字底色 |
| -O | --bgless | 不绘制文字背景,只渲染文字轮廓 |
| -o | --overlay | 叠加模式,自动取底层像素反色(优先级高于 - O) |
| -T | --fgless | 不绘制前景文字 |

3、特殊绘图模式

  1. 进度条 -P NUM``fbink -P 35 绘制全屏宽度 35% 进度条

  2. 活动加载条 -A NUM``fbink -A 8 0~16;负数自动循环动画

  3. 局部 / 全屏刷新 -s 只触发屏幕刷新,不修改画面

    fbink -s top=20,left=10,width=500,height=600 -W GC16

  4. 图片显示 -g / -i 支持 PNG/JPG/BMP;可缩放、对齐、软件抖动

    fbink -g file=/mnt/us/test.png,halign=CENTER,valign=MIDDLE

4、TrueType/OTF 矢量字体

可以调用 ttf 自定义字体(Kindle 内置 Caecilia),支持 Markdown 粗体 / 斜体

复制代码
fbink -t regular=/usr/java/lib/fonts/Caecilia_LT_65_Medium.ttf,size=22,top=50 "自定义矢量文字"

5、输出调试与脚本参数

  • -q:静默,关闭硬件检测日志
  • -v:详细日志
  • -E:输出绘制区域坐标,方便 shell 脚本解析
  • -e:输出设备环境变量,eval $(fbink -e) 直接导入变量
  • -d NUM守护进程模式 ,启动 FIFO 管道 /tmp/fbink-fifo,持续接收文本输出,适合仪表盘常驻刷新

6、常用命令示例

(适配 Kindle Basic2 600×800)

1. 基础文字输出

复制代码
# 第10行、第2列输出文字
fbink -x 1 -y 10 "Hello Kindle!"

2. 居中、黑底白字

复制代码
# 水平居中+垂直居中向上偏移5行、反色高亮
fbink -pmh -y -5 "System Information"
  • -m居中 -p两端空格填充 -h反转颜色
  • -y -5 距离底部向上 5 行

3. 全屏清屏后打印文字

复制代码
fbink -c -m -M "Clear"

4. 局部矩形清屏(清空底部状态栏区域)

复制代码
fbink -k top=720,left=0,width=600,height=80

5. 快速局部 GC16 刷新(不绘图,只消残影)

复制代码
fbink -s top=700,left=0,width=600,height=100 -W GC16

6. 显示图片,屏幕居中

复制代码
fbink -g file=/mnt/us/img.png,halign=CENTER,valign=MIDDLE

7. 启动守护进程(常驻仪表盘,推荐做动态面板)

复制代码
# 最多容纳8行文本
PID=$(fbink -d 8)
# 向管道写入内容,屏幕实时更新
echo "CPU: 32%  Battery:78%" > /tmp/fbink-fifo
# 关闭
kill $PID

8. 使用更大字体、更换内置字体

复制代码
fbink -F TEWI -S 2 -m "Hello Kindle"

9. 无背景文字叠加(不覆盖原有画面)

复制代码
fbink -O -x 2 -y 2 "Test..."

重要使用提示

  1. 多次连续绘图建议搭配 -b 先写入缓冲区,最后一次不带 -b 统一刷新,减少墨水刷屏次数、减缓老化;
  2. -W A2 快速刷新(残影重),GC16/GL16 灰度高质量刷新;
  3. 大量动态刷新尽量少用 -f(flash 黑屏全刷),频繁全刷损耗屏幕;
  4. 多行文本文字直接写在同一个引号内,不要分成多个参数;多个参数配合 -c 只会显示最后一行;
  5. 坐标同时支持「绝对正数」和「负数反向计数」,很适合做自适应底部状态栏。

7、显示时间程序

复制代码
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>

static int fbink_exec(char *const argv[])
{
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        return -1;
    }
    if (pid == 0) {
        execvp(argv[0], argv);
        perror("execvp fbink");
        _exit(127);
    }
    int status;
    waitpid(pid, &status, 0);
    if(WIFEXITED(status)){
        return WEXITSTATUS(status);
    }
    return -1;
}

//局部区域白色擦除
static int fbink_local_clear(void)
{
    char * const argv[] = {
        "/usr/bin/fbink",
        "-k", "top=400,left=0,width=600,height=15",
        NULL
        };
    return fbink_exec(argv);
}

//屏幕居中输出文本
static int fbink_center_text(const char *text)
{
    char * const argv[] = {
        "/usr/bin/fbink",
        "-m", "-M",
        (char *)text,
        NULL
        };
    return fbink_exec(argv);
}

int main(void)
{
    char timestr[64];
    time_t now;
    struct tm *tm_ptr;

    for(;;)
    {
        now = time(NULL);
        tm_ptr = localtime(&now);

        snprintf(timestr, sizeof(timestr),
                 "%04d/%02d/%02d %02d:%02d",
                 tm_ptr->tm_year + 1900,
                 tm_ptr->tm_mon + 1,
                 tm_ptr->tm_mday,
                 tm_ptr->tm_hour,
                 tm_ptr->tm_min);

        printf("%s\n", timestr);

        fbink_local_clear();   //局部擦除旧内容
        fbink_center_text(timestr); //输出新时间

        sleep(1);
    }
    return 0;
}

Linux 主机交叉编译:

复制代码
arm-linux-gnueabi-gcc -march=armv7-a -mtune=cortex-a9 -msoft-float -mabi=aapcs-linux   show-time.c -o show-time

上传程序:

复制代码
scp ./show-time root@192.168.1.4:/mnt/us/gcc-test

kindle端运行:

复制代码
#cd /mnt/us/gcc-test
#./show-time

二、kindle 触摸屏开发

1、触摸屏设备

设备节点确认

复制代码
cat /proc/bus/input/devices
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="zforce2"
P: Phys=zforce2/input0
S: Sysfs=/devices/platform/zforce2.0/input/input0
U: Uniq=
H: Handlers=event0
B: PROP=2
B: EV=b
B: KEY=6420 0 0 0 0 0 0 0 0 0 0
B: ABS=2608000 0

Kindle 8 (PW3),触摸驱动是 zforce2 (不是 mtk‑tpd),触摸设备节点:/dev/input/event0。 zforce2 是多点触摸 MT protocol B ,使用 ABS_MT_POSITION_X / ABS_MT_POSITION_Y

坐标说明(zforce2 PW3)

屏幕分辨率 600 × 800

  • ABS_MT_POSITION_X:0 ~ 600
  • ABS_MT_POSITION_Y:0 ~ 800

和 FBInk 绘图坐标完全兼容,可以直接传给 fbink 的 -x``-y 参数。

⚠️ zforce2 的关键特性

  1. 没有 BTN_TOUCH 事件 ,依靠 ABS_MT_TRACKING_ID 判断按下抬起:
    • tracking_id != -1 → 手指按下
    • tracking_id == -1 → 手指抬起
  1. 设备节点固定 /dev/input/event0,来自你 /proc/bus/input/devicesHandlers=event0
  2. 程序打开 event0 后,系统原生触摸会失效(事件抢占),程序退出后恢复。
  3. 必须 root 权限打开 /dev/input/event0

2、zforce2 触摸读取程序

逻辑:解析 Linux MT‑B 多点触摸协议,读取手指按下、抬起、X/Y 坐标。

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>

#define TOUCH_DEV "/dev/input/event0"

int main(void)
{
    int fd;
    struct input_event ev;

    int x = -1, y = -1;
    int touch_active = 0;

    fd = open(TOUCH_DEV, O_RDONLY);
    if (fd < 0) {
        perror("open /dev/input/event0 failed (need root!)");
        return EXIT_FAILURE;
    }

    printf("zforce2 touch reader. Tap screen, Ctrl+C exit.\n");

    for (;;)
    {
        ssize_t n = read(fd, &ev, sizeof(struct input_event));
        if (n != sizeof(struct input_event)) {
            perror("read event");
            continue;
        }

        switch (ev.type)
        {
            case EV_ABS:
                // MT多点触摸坐标
                if (ev.code == ABS_MT_POSITION_X) {
                    x = ev.value;
                } else if (ev.code == ABS_MT_POSITION_Y) {
                    y = ev.value;
                } else if (ev.code == ABS_MT_TRACKING_ID) {
                    /* tracking_id !=‑1:手指按下;==‑1:手指抬起 */
                    if(ev.value != -1) {
                        touch_active = 1;
                        printf("DOWN x=%d y=%d\n", x, y);
                    } else {
                        touch_active = 0;
                        printf("UP\n");
                    }
                }
                break;

            case EV_SYN:
                // SYN_REPORT 一次上报结束
                break;
            default:
                break;
        }
    }

    close(fd);
    return 0;
}

Linux 主机交叉编译:

复制代码
arm-linux-gnueabi-gcc -march=armv7-a -mtune=cortex-a9 -msoft-float -mabi=aapcs-linux   touch-read.c -o touch-read

上传程序:

复制代码
scp ./touch-read root@192.168.1.4:/mnt/us/gcc-test

kindle端运行:

复制代码
#cd /mnt/us/gcc-test
#./touch-read

DOWN x=245 y=330
UP
DOWN x=410 y=520
UP
相关推荐
宵时待雨1 小时前
linux笔记归纳13:Socket编程UDP
linux·服务器·笔记·udp
bksczm1 小时前
Linux之应用层层协议认知(TCP协议编程模块化demo) —— 兼论守护进程机制
linux·运维·服务器
MetrixAeroCore1 小时前
沙特智慧城市路灯物联网解决方案:本土网络适配与批量设备上线注册
物联网
zcmodeltech1 小时前
火电厂模型多设备时序控制系统设计:基于STM32与Modbus RTU的燃煤-燃机全流程联动方案
分布式·stm32·单片机·嵌入式硬件·物联网
爱和冰阔落1 小时前
【Linux】从匿名管道到进程池:任务派发、fd 继承 Bug 与完整实现
android·linux·运维·c++
杨云龙UP10 小时前
MySQL 数据库常用备份工具对比:mysqldump、mydumper 与 XtraBackup
linux·运维·服务器·数据库·mysql·dba·备份恢复
风曦Kisaki11 小时前
Kubernetes(K8s)笔记Day06: 持久化存储(emptyDir,hostPath,NFS),PV 和 PVC,StorageClass存储类
linux·运维·笔记·云原生·容器·kubernetes
_艾伦 耶格尔.12 小时前
基础I/O
linux
fb_1234515 小时前
Linux磁盘分区从入门到实操:MBR_GPT全解析+分区工具实战指南
java·linux·gpt