Hugo

hugo 用hugo 来构建静态网站页面 hugo 创建的网站目录结构如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 fangqing@e470c:~/blog$ ls -al 总计 64 drwxrwxr-x 13 fangqing fangqing 4096 1月 22 22:34 . drwxr-x--- 41 fangqing fangqing 4096 4月 8 21:56 .. drwxrwxr-x 2 fangqing fangqing 4096 4月 3 2025 archetypes drwxrwxr-x 2 fangqing fangqing 4096 4月 16 2025 assets drwxrwxr-x 3 fangqing fangqing 4096 4月 8 22:11 content drwxrwxr-x 2 fangqing fangqing 4096 4月 3 2025 data drwxrwxr-x 9 fangqing fangqing 4096 4月 21 2025 .git -rw-rw-r-- 1 fangqing fangqing 101 4月 17 2025 .gitmodules -rw-rw-r-- 1 fangqing fangqing 0 4月 3 2025 .hugo_build.lock -rw-rw-r-- 1 fangqing fangqing 576 1月 23 01:12 hugo.toml drwxrwxr-x 2 fangqing fangqing 4096 4月 3 2025 i18n drwxrwxr-x 4 fangqing fangqing 4096 4月 16 2025 layouts drwxr-xr-x 7 fangqing fangqing 4096 1月 23 01:15 public -rw-rw-r-- 1 fangqing fangqing 438 1月 22 23:31 readme.md drwxrwxr-x 3 fangqing fangqing 4096 4月 3 2025 resources drwxrwxr-x 2 fangqing fangqing 4096 4月 3 2025 static drwxrwxr-x 3 fangqing fangqing 4096 4月 17 2025 themes Create a new blog post ...

四月 8, 2026 · Luke Fang

Perf

一月 27, 2026 · Luke Fang

Avm_app_design

一月 27, 2026 · Luke Fang

Avm_design

一月 27, 2026 · Luke Fang

How_to_cross_compile

交叉编译是一种在一个平台上生成可在另一个平台上运行的可执行文件的技术。它通常用于嵌入式开发或跨平台开发场景,例如在 x86 架构的主机上编译适用于 ARM 架构的程序 交叉编译涉及三个关键参数:build、host 和 target。 build:表示构建交叉编译工具链的平台。 host:表示运行交叉编译器的平台。 target:表示生成的可执行文件将运行的平台。 例如,在 x86主机上构建一个能在 ARM 平台上运行的程序时,build 是 x86,host 是 x86,target 是 ARM 编译出运行在arm系统上的可执行文件 需要用到Arm GNU Toolchain 我们的实验环境: 宿主机:Ubuntu 20.04 x86_64 目标系统:aarch64 linux(aarch64-none-linux-gnu) 下载https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

一月 23, 2026 · Luke Fang

python_opengl

使用python调用opengl进行渲染 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import glfw from OpenGL.GL import * def main(): # Initialize the library if not glfw.init(): return # Create a windowed mode window and its OpenGL context window = glfw.create_window(640, 480, "Hello World", None, None) if not window: glfw.terminate() return # Make the window's context current glfw.make_context_current(window) count =0; # Loop until the user closes the window while not glfw.window_should_close(window): # Render here, e.g. using pyOpenGL glClearColor(0.2, 0.3, 0.3, 1.0) glClear(GL_COLOR_BUFFER_BIT) glColor3f(1.0, 1.0, 1.0) glBegin(GL_TRIANGLES) glVertex3f(-0.5, -0.5, 0.0) glVertex3f(0.5, -0.5, 0.0) glVertex3f(0.0, 0.5, 0.0) glEnd() # Swap front and back buffers glfw.swap_buffers(window) # Poll for and process events glfw.poll_events() glfw.terminate() if __name__ == "__main__": main()

四月 26, 2025 · Luke Fang

DDS

Data Distribution Service To be continue… fast-dds: https://fast-dds.docs.eprosima.com/en/latest/fastdds/getting_started/definitions.html

四月 23, 2025 · (updated 四月 27, 2025) · Luke Fang

CarPowerManager

实际工作中为了fix某个issue,车载应用需要在车机andoid系统退出STR模式(Suspend to RAM)时候执行某个逻辑 解决方案参照anrdoid文档 注册一个CarPowerStateListener回调,重写onStateChanged 方法 在androidManifest.xml中增加以下权限 1 <uses-permission android:name="android.car.permission.CAR_POWER" /> 在业务逻辑中注册CarPowerStateListener 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import android.car.hardware.power.CarPowerManager; import android.car.hardware.power.CarPowerManager.CarPowerStateListener; public class MyService extends Service { private CarPowerManager mCarPowerManager = null; @override public void onCreate() { super.onCreate(); Car car = Car.CreateCar(this); mCarPowerManager = (CarPowerManager)car.getCarManager(Car.POWER_SERVICE); if(mCarPowerManager!=null) { final CarPowerManager.CarPowerStateListener powerListener = new CarPowerManager.CarPowerStateListener () { @Override public void onStateChanged(int state) { Log.i(TAG, "onStateChanged() state = " + state); if(state==SUSPEND_EXIT) //此时退出STR mode { //do my business } } }; } } @override public void onDestroy() { super.onDestroy(); if(mCarPowerManager!=null) { mCarPowerManager.clearListener(); } } }

四月 23, 2025 · (updated 四月 26, 2025) · Luke Fang

GlSurfaceView源码剖析

应用程序的渲染方式分为两种 按需渲染: 绝大多数应用程序,比如微信/钉钉/QQ,都是这种,当有数据更新才请求重新刷新绘制界面 定频渲染:比如游戏,永远按照固定的频率进行渲染(只有这样,才能模拟出逼真的动画效果) 在android 中,上述两个场景分别用以下两个类 SurfaceView(按需渲染):直接在UI线程进行渲染,效率低,适用于渲染频率低的应用场景。 GLSurfaceView(定频渲染):开启一个独立的opengl线程来进行渲染(防止UI线程被阻塞),每个GLSurfaceView的实例都有一个 GLThread mGLThread 成员 无论是java/C++, opengl绘制流程都一样: 初始化 egl 参数 在一个循环中不断进行帧绘制 类的大体定义如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback2 { private GLThread mGLThread; //独立的opengl线程进行渲染 private Renderer mRenderer; //自定义的Renderer, 这个Render定义了如何进行渲染 ........ public void setRenderer(Renderer renderer) { ......... mRenderer = renderer; mGLThread = new GLThread(mThisWeakRef); mGLThread.start(); //启动opengl线程 } public void queueEvent(Runnable r) { mGLThread.queueEvent(r); } ......... } public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCallback { SurfaceControl mSurfaceControl; // 与android系统的的surfacefinger服务进行binder通讯 public void draw(Canvas canvas){ ..... super.draw(canvas); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 static class GLThread extends Thread { @Override public void run() { setName("GLThread " + getId()); if (LOG_THREADS) { Log.i("GLThread", "starting tid=" + getId()); } try { guardedRun(); } catch (InterruptedException e) { // fall thru and exit normally } finally { sGLThreadManager.threadExiting(this); } } private void guardedRun() throws InterruptedException { ............. Runnable event = null; while(true){ synchronized (sGLThreadManager) { while (true) { if (mShouldExit) { return; } //pop 一个 event if (! mEventQueue.isEmpty()) { event = mEventQueue.remove(0); break; } if (event != null) { event.run(); // 执行event event = null; continue; } ........... // 初始化egl mEglHelper.createGL(); ........... //onSurfaceCreated mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); if(sizeChanged) //如果view大小发生了变化 { //onSurfaceChanged mRenderer.onSurfaceChanged(gl, w, h); } //绘制 mRenderer.onDrawFrame(gl); ........... } } } } } 自定义Render类 ...

四月 21, 2025 · (updated 四月 23, 2025) · Luke Fang

Graphviz语法和使用

Papermod 主题有bug,需要这个patch: https://github.com/miallo/hugo-PaperMod/commit/bdc94735006be3102ab9bfe45b360d4f0179a3e0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 digraph G { aize ="4,4"; main [shape=box]; main -> parse [weight=8]; parse -> execute; main -> init [style=dotted]; main -> cleanup; execute -> { make_string; printf} init -> make_string; edge [color=red]; main -> printf [style=bold,label="100 times"]; make_string [label="make a string"]; node [shape=box,style=filled,color=".7 .3 1.0"]; execute -> compare; } 让hugo支持mermaid https://gohugo.io/content-management/diagrams/#mermaid-diagrams mermaid 示例 https://mermaid.nodejs.cn/syntax/examples.html sequenceDiagram sequenceDiagram participant Alice participant Bob Alice->>John: Hello John, how are you? loop Healthcheck John->>John: Fight against hypochondria end Note right of John: Rational thoughts <br/>prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good! 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 gitGraph ...

四月 16, 2025 · (updated 四月 26, 2025) · Luke Fang