页次: 1
1.Do you have these two libraries on your board?(libOMX_Core.so libOmxCore.so)
The two libraries have different names in buildroot 2020.02.1.
2.You can refer to this person's decoding operation.
https://whycan.com/t_5398.html
3.You can also add a codec to ffmpeg, you can refer to this.
https://blog.csdn.net/ddddfang/article/details/89330895
你这不是gpios设备树参数太多咩。报错了呗, 你用的sdk应该和他们用的不同,具体gpios的配置情况可以参考已有的例子,如果没有的话可以找下
Documentation\devicetree\bindings 下面对设备树描述的txt看例子怎么使用设备树。就拿贴子上晕哥说的那个buildroot-tiny200 这个的来说,你看你这句
gpios = <&pio 5 5 GPIO_ACTIVE_LOW>; 你这个应该就是这个sdk里面设备树写法。这个&pio中的pio你可以在suniv-f1c100s.dtsi这里找到pio的配置,其中就有compatible = "allwinner,suniv-f1c100s-pinctrl"这个。然后你在Documentation\devicetree\bindings这里面搜索"allwinner,suniv-f1c100s-pinctrl"你就可以打开allwinner,sunxi-pinctrl.txt。这里面就说明了每个参数是什么,并且有一个demo示例。不同的SDK是略有不同的。我知道的tina就不同。
问题说明: 目前在f1c200s上运行的tina3.5。看了tina的播放器例子,发现要使用disp设备需要提供物理地址进行设置方可正常使用,
网上找到一段转换代码如下,实际使用的时候,似乎是计算的不对,但是有一部分好像是对的。就是设置后往虚拟地址写东西,屏幕有部分有反应。
void mem_addr(unsigned long vaddr, unsigned long *paddr)
{
int pageSize = getpagesize();//调用此函数获取系统设定的页面大小
unsigned long v_pageIndex = vaddr / pageSize;//计算此虚拟地址相对于0x0的经过的页面数
unsigned long v_offset = v_pageIndex * sizeof(uint64_t);//计算在/proc/pid/page_map文件中的偏移量
unsigned long page_offset = vaddr % pageSize;//计算虚拟地址在页面中的偏移量
uint64_t item = 0;//存储对应项的值
int fd = open("/proc/self/pagemap", O_RDONLY);
if(fd == -1)//判断是否打开失败
{
printf("open /proc/self/pagemap error\n");
return;
}
if(lseek(fd, v_offset, SEEK_SET) == -1)//将游标移动到相应位置,即对应项的起始地址且判断是否移动失败
{
printf("sleek error\n");
return;
}
if(read(fd, &item, sizeof(uint64_t)) != sizeof(uint64_t))//读取对应项的值,并存入item中,且判断读取数据位数是否正确
{
printf("read item error\n");
return;
}
if((((uint64_t)1 << 63) & item) == 0)//判断present是否为0
{
printf("page present is 0\n");
return ;
}
uint64_t phy_pageIndex = (((uint64_t)1 << 55) - 1) & item;//计算物理页号,即取item的bit0-54
*paddr = (phy_pageIndex * pageSize) + page_offset;//再加上页内偏移量就得到了物理地址
close(fd);
}
LVGL(轻便而多功能的图形库)是一个免费的开放源代码图形库,它提供创建具有易于使用的图形元素,精美的视觉效果和低内存占用的嵌入式GUI所需的一切。
1.官网https://lvgl.io
2.Gihub主页https://github.com/lvgl 在这里可以下载到lvgl的驱动和各板子上的demo。以及windows下和linux下的仿真工程
首先了解下目录构成,lvgl基本构成有lvgl库本身这个也是最核心的东西了,构建的时候也是必须要的了。然后就是lv_examples这个我们移植的时候可以加上,但实际自己的项目中是不需要存在的。lv_drivers这个目录是驱动目录,理论上来说也不是必要的,但是没有驱动的话lvgl显示的东西就不知道在哪了,不可能只显示到内存上而不刷新到LCD或者显示设备上吧。而且ui通常都还需要配备输入设备。所以这个目录包含的就是显示驱动以及输入设备的驱动等。
啰嗦完了开始移植。
1.建个目录 mkdir my_lvgl cd my_lvgl
2.从github上下载lvgl到本地 https://github.com/lvgl/lvgl 上我们选择最新的释放版本release/v7 我们只下载当前版本来使用。
git clone -b release/v7 --depth 1 https://github.com/lvgl/lvgl.git 下载lvgl核心库
git clone -b release/v7 --depth 1 https://github.com/lvgl/lv_drivers.git 下载驱动
lvgl里面都用一个模板配置拷贝出来稍微修改下就行了。
lvgl模板拷贝出来修改 cp lvgl/lv_conf_template.h ./lv_conf.h
lv_conf.h中 if 0 改为 if 1
最重要的需要配置的有一下几个可以搜索并配置:
这几个就必须要根据板子实际情况修改了
#define LV_HOR_RES_MAX (480) //屏幕水平宽度 根据实际使用修改
#define LV_VER_RES_MAX (320) //屏幕垂直高度 根据实际使用修改
#define LV_COLOR_DEPTH 16 //LCD 屏幕的像素深度。一般的可能是rgb565 也有是rgb8888的就写 32 根据实际使用修改
#define LV_USE_GPU 1 //这个记得给他置0了一般的板子应该没有gpu
下面这几个可以不动
#define LV_USE_PERF_MONITOR 0 //右下角cpu信息输出。测试可以打开看下
# define LV_MEM_SIZE (32U * 1024U) //这里默认的是32K 用作lvgl的动态内存分配。可以根据实际情况修改,但是要大于等于2KB
#define LV_DISP_DEF_REFR_PERIOD 30 //刷新周期 30ms 就是刷新速率问题,看性能设置吧。
#define LV_INDEV_DEF_READ_PERIOD 30//输入设备的扫描时间,就是轮询按键的时间。默认30ms。
#define LV_USE_FILESYSTEM 1 //文件系统不用也可以给置0了
#define LV_USE_DEBUG 1 //debug信息输出可关闭
驱动修改
将lvgl driver模板拷贝出来修改 cp lv_drivers/lv_drv_conf_template.h ./lv_drv_conf.h
修改头 if 0改为 if 1
# define USE_FBDEV 0 //把这个置位为1
# define FBDEV_PATH "/dev/fb0" //确认是否为你设备的fb
编译输出
mkdir obj 创建一个输出目录用于输出生成的.o文件
在obj目录下创建一个Makefile 毕竟编译方便输入下面语句
CC = arm-linux-gnueabihf-gcc #这里使用你板子编译的gcc最好指定有路径的更明确
LVGL_DIR ?= /home/xxx/study/my_lvgl #创建lvgl的根目录
LVGL_DIR_NAME ?= lvgl
CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/
LDFLAGS ?= -lm
BIN = lvgl_demo
MAINSRC = ../main.c
include $(LVGL_DIR)/lvgl/lvgl.mk
include $(LVGL_DIR)/lv_drivers/lv_drivers.mk
OBJEXT ?= .o
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)
all: default
%.o: %.c
@$(CC) $(CFLAGS) -c $(INCLUDES) $< -o $@
@echo "CC $<"
default: $(AOBJS) $(COBJS) $(MAINOBJ)
$(CC) -o $(BIN) $(MAINOBJ) $(AOBJS) $(COBJS) $(LDFLAGS)
cp $(BIN) ../
clean:
rm -f $(BIN) $(AOBJS) $(COBJS) $(MAINOBJ)
为了可以直接在根目录编译,所以在根目录创建一个Makefile加入如下脚本这样就可以直接在根目录进行make了
all:
make -C obj
clean:
make clean -C obj
添加测试代码
在lvgl根目录下新建main.c加入如下代码。
#include "lvgl/lvgl.h"
#include "lv_drivers/display/fbdev.h"
#define DISP_BUF_SIZE (100 * LV_HOR_RES_MAX) //lvgl用于绘制屏幕的缓冲区。这里用100行像素作为缓冲区这个可以修改。
static lv_obj_t *label;
static void refresh_ui_task(lv_task_t * task)
{
char temp[50];
static int count = 0;
sprintf(temp, "hello why can %d", count++);
lv_label_set_text(label, temp);
}
static void button_event(lv_obj_t * obj, lv_event_t event)
{
if (event == LV_EVENT_CLICKED) {
printf("button event\n");
}
}
static void video_disp_window()
{
lv_obj_t * this_win = lv_cont_create(lv_scr_act(), NULL);
lv_obj_set_size(this_win, LV_HOR_RES, LV_VER_RES);
lv_obj_t *btn = lv_btn_create(this_win, NULL);
label = lv_label_create(btn, NULL);
lv_label_set_text(label, "hello why can");
lv_obj_set_event_cb(btn, button_event);
lv_task_create(refresh_ui_task, 1000, LV_TASK_PRIO_MID, NULL);
}
int main(int argc, char **argv)
{
lv_init(); //lvgl gui初始化
fbdev_init(); //fb初始化 此函数在 lv_drivers/display/fbdev.c 中,就是打开fb设备映射显存出来使用
static lv_color_t buf[DISP_BUF_SIZE];
static lv_disp_buf_t disp_buf;
lv_disp_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.buffer = &disp_buf;
disp_drv.flush_cb = fbdev_flush; //fbdev_flush这就是输入显示驱动提供的操作函数 刷新数据到显存的函数。其他非Linux fb移植照葫芦即可。
lv_disp_drv_register(&disp_drv);
video_disp_window();
while (1)
{
lv_task_handler();
usleep(5000);
}
}
根目录make一下 拷贝到板子上试下呗。
然后你会发现任务刷新的label并没有改变。原因就是lvgl还需要提供一个计时的心跳包给他,按照官网的说明是调用lv_tick_inc这个函数来设置lvgl的时钟。官网移植给的建议是linux开个线程来调用这个函数,实际上有另外一种方式就是用用户的时钟源(这里用Linux下的gettimeofday比用usleep好使)。
在lv_conf.h中
LV_TICK_CUSTOM 0 置为1 这个就是使用用户的时钟源使能
#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" //将这个头文件改为<sys/time.h> (gettimeofday 的头文件)
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) //宏定义声明外部函数,就是提供一个能获取时间的函数给lvgl。这个我们自己写个在main中 写个my_tick() 所以这里替换掉millis()即可。
在 main.c中增加此函数 记得加<sys/time.h> 这个头文件
uint32_t my_tick(void)
{
static uint64_t start_ms = 0;
struct timeval tv_time;
if(start_ms == 0) {
gettimeofday(&tv_time, NULL);
start_ms = (tv_time.tv_sec * 1000000 + tv_time.tv_usec) / 1000;
}
gettimeofday(&tv_time, NULL);
uint64_t now_ms;
now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;
uint32_t time_ms = now_ms - start_ms;
return time_ms;
}
至此 make一下拷贝到板子运行即可count就加起来了。
最后再加入个触摸点击
触摸输入在lv_drv_conf.h
# define USE_EVDEV 0 这个 置为1
# define EVDEV_NAME "/dev/input/event0" //这个就是输入设备了看你自己的是event几了。
在main.c的main函数中加入
evdev_init();
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type =LV_INDEV_TYPE_POINTER;
indev_drv.read_cb =evdev_read;
lv_indev_drv_register(&indev_drv);
记得添加头文 #include "lv_drivers/indev/evdev.h"
make一下到板子试试。这样就可以妥妥的运行起来了。
不知道你用的是哪个的SDK是下面这个吗?
https://github.com/Lichee-Pi/linux
如果其他的话就不同了。不过这里有个教程编译的。这里5.2tf卡那个默认用的LCD好像就是800*480的。
https://whycan.com/t_3211.html
sprintf 说:1.
Qt库开源代码,我使用的是4.8.7版本;
http://mirrors.sohu.com/qt-all/archive/qt/4.8/4.8.7/
我下载的是qt-everywhere-opensource-src-4.8.7.tar.gz
Perl语言环境5.12版本以上装好之后把bin目录加入环境变量,在cmd 输入perl -v正常即可
Python语言环境 2.7 版本以上; bin加入环境变量 cmd 输入 python --version能显示版本即可
Windows平台上的MinGW开发工具集(内含本地编译器gcc、g++ 4.9以上版本);bin加入环境变量 cmd 输入mingw32-make -v正常即可
Windows平台上的交叉编译器arm-linux-gnueabihf(gcc、g++4.9以上版本)。 bin加入环境变量 cmd 输入 arm-linux-gnueabihf-g++ -v 正常即可...。
请教,不明白红字两部分的区别和用途。
g++使用用来编译在windows能运行的qmake.exe以及其他UI之类的。 arm-linux- 是用来编译QT动态库的就是跑你开发板上使用的。
想问下,跳1K写1K,是不是就表明了利用率只有50%,也就是128MByte的Flash只能用64MByte?
按照上面那个英文介绍的话,只是说BROM读取的nand 的时候是每个页的前1024BYTES (1K)[It only reads the first 1024 bytes from every page]
如果你每页不是2K估计得跳更多。但是你可以把小部分得启动放在nand的第一页1K里面。启动之后你就可以自己去读取代码到ram上了。
总的来说也就是启动部分的代码放在nand前面的利用率只有50% 启动之后的因为是你自己操作那就是100%了。比如你的启动代码只有2K那么前面2个page
每个放1K浪费2K。后面你自己的东西就可以随便写了。
1.
Qt库开源代码,我使用的是4.8.7版本;
http://mirrors.sohu.com/qt-all/archive/qt/4.8/4.8.7/
我下载的是qt-everywhere-opensource-src-4.8.7.tar.gz
Perl语言环境5.12版本以上装好之后把bin目录加入环境变量,在cmd 输入perl -v正常即可
Python语言环境 2.7 版本以上; bin加入环境变量 cmd 输入 python --version能显示版本即可
Windows平台上的MinGW开发工具集(内含本地编译器gcc、g++ 4.9以上版本);bin加入环境变量 cmd 输入mingw32-make -v正常即可
Windows平台上的交叉编译器arm-linux-gnueabihf(gcc、g++4.9以上版本)。 bin加入环境变量 cmd 输入 arm-linux-gnueabihf-g++ -v 正常即可
2.配置编译器 mkspecs\linux-arm-gnueabi-g++\ qmake.conf 这里面的编译器配置成自己下载的交叉编译器 arm-linux-gnueabihf 我这里是这个。
3.cmd 进入源代码的根目录配置需求 可以使用configure --help查看具体参数,我配置如下
configure -release -opensource -prefix "D:\Qt4.8.7_ARM_Linux" -nomake demos -nomake examples -nomake tests -no-opengl -no-webkit -platform win32-g++ -xplatform linux-arm-gnueabi-g++
4.配置好之后会提示输入 mingw32-make
5.最后 mingw32-make install
编译好了库,剩下的就是在qtcreator使用此编译的库就可以 在windows下开发ARM linux上的Qt程序了。
页次: 1