In the previous article , I built a self-hosted NTP server using Tinker Board and an ATGM336H GPS/BeiDou module, with GPS as the time reference. In addition to the traditional serial output of NMEA sentences, the GPS module also provides a PPS signal that changes once per second. Originally, gpsd needed to continuously parse NMEA sentences from the GPS module, which took considerable time and was prone to being preempted by other processes, causing delay and jitter. The PPS signal, however, can directly trigger a CPU interrupt to run a simple handler at high priority, unaffected by other programs. Typically, Linux kernel provides native driver support for PPS. But in the previous setup, since Armbian Linux kernel on Tinker Board lacked PPS support, we couldn't enable it directly....

Building a GPS-based NTP Server
What is NTP NTP (Network Time Protocol) is the most widely used internet time synchronization protocol. Common operating systems like Windows, macOS, and Linux come with built-in NTP clients that connect to remote servers to obtain the current time. For example, Windows' Internet time synchronization feature is based on NTP: (Image source: Internet) By default, Windows connects to time.windows.com , an NTP server maintained by Microsoft. However, this server performs poorly in mainland China. Located in the US, it suffers from high and unstable latency, making it difficult for NTP clients to obtain accurate time. Are there NTP servers in mainland China? Yes, but not many: cn.pool.ntp.org An NTP server pool project maintained by www.pool.ntp.org , with servers provided by volunteers....
Using GPP to Preprocess Dockerfile for #include, #if, and Other Features
Since I have multiple devices with different architectures running Docker (including x86_64 computers and servers, ARM32v7 Tinker Board, and ARM64v8 Raspberry Pi 3B), each of my Docker images needs to be built in multiple versions. Initially, I wrote a separate Dockerfile for each architecture , but this approach proved difficult to manage uniformly, often leading to missed updates when modifying Dockerfiles during software upgrades. Later, I adopted Docker's build argument feature , using the --build-arg parameter to select different base images and download architecture-specific files based on arguments. However, this approach still has significant limitations. First, different projects use varying naming conventions for architectures. For example, the x86 32-bit architecture (i386)...
Cyclone IV FPGA Development Log
Last semester, the school offered a digital systems course, which involves development on FPGAs. At the end of the course, we need to gather in groups and achieve some complicated functionality with the flexible architecture of FPGA, such as creating a game or running a convoluted neural network. We are free to add extra functionalities as we wish. Our group has done a game similar to Raiden, or controlling a fighter jet and attacking enemies with bullets. In addition to course requirements, we implemented these extra functionalities: A 640x480 VGA framebuffer with 16-bit color depth, stored on SRAM chip Naturally, Simplified Chinese fonts are included (full UTF-8 Chinese range, but without punctuation marks, since they are out of that range and we're kinda lazy)...
Running Anycast DNS with Docker in DN42
2020-03-16 Notes There is an updated scheme compared to this post, see Sharing Network Namespace Among Docker Containers for Bird Anycasting . It is suggested to read only the concept explanations in this post, and use the above scheme instead for deployment. What's Anycast The commonly used routing protocol on Internet, the BGP, works like this: I own an IP range, 172.22.76.104/29, on DN42. With a BGP software like BIRD, I "announce" that my server has access to IP range 172.22.76.104/29. Servers with peering to me will record this message: "Over this path, I can access 172.22.76.104/29 which is 1 step away." These servers continue to announce to others with peering to them: "This server is 1 step away from the source of 172.22.76.104/29." Similarly,...
Typecho Theme Performance Optimization and Caching
To implement features like Lightbox and code highlighting, I added post-processing code to my blog theme that performs an additional layer of processing on the HTML output after Typecho's Markdown conversion. However, due to the large number of historical articles on my blog and my use of different editors over time (WordPress editor, Baidu UEditor, etc.), my processing logic became quite complex to ensure compatibility with older articles. Combined with the limited performance of my budget VPS, this resulted in longer webpage loading times. I added the following line to my nginx configuration to output server-side processing time in HTTP headers: add_header LT-Latency $request_time ; Initially, this value was around 0.25, meaning each page took about 250ms to process on the server....

Raspberry Pi 3B Tinkering Notes: Serial Port Dial-up Networking
Is it 9102 already? Yes, it is. Why Do This I have a Raspberry Pi 3B and an ASUS Tinker Board. Sometimes issues like Wi-Fi failures/configuration errors/ pacman -Syu system breakage might cause one board to lose network connection. By connecting the serial ports of both boards and establishing a dial-up network connection, I can SSH into the problematic board from the other one when Wi-Fi or Ethernet fails. (Also, if you buy a Raspberry Pi without tinkering with GPIO, you might as well get an x86 Atom mini PC instead) How to Set Up Hardware Setup: Connect the serial ports of both boards. The Raspberry Pi's serial port uses Pin 8 (TX) for transmission and Pin 10 (RX) for reception (check pinout.xyz ). The Tinker Board's serial port also uses Pin 8 (TX) and Pin 10 (RX)....

Bird-lg in Go (Bird Looking Glass)
What's BIRD? And What's Bird-lg? BIRD is a popular BGP routing software used on Linux. I mainly use Bird in the DN42 network , to establish connections with other users. Bird-lg is a Python 2 based program developed by GitHub user sileht. It provides a web interface to show the status of BIRD routing software on each server, as well as query routes to specified IPs. Why Rewrite in Go? Bird-lg is based on Python 2 and Flask and takes more memory (20-30MB). Bird-lgproxy also takes around 20MB and is required on every server. On the 512MB VPS where this site is hosted, there had been multiple cases where memory ran out, and the on-disk SWAP was too slow. In this case, Docker, Nginx, MySQL, PHP would crash one after one, and a reboot would be necessary....

BuyPass GO SSL Certificate Trial
BuyPass is a Norwegian Certificate Authority (CA) that provides various services including digital certificates and security authentication products. Recently, BuyPass launched an ACME-based automated certificate issuance service called BuyPass GO, similar to Let's Encrypt. The main difference from Let's Encrypt is that their certificates have a 180-day validity period per issuance—twice as long as Let's Encrypt's. Therefore, if you need to manually replace certificates for your service, BuyPass certificates are more convenient. Additionally, BuyPass currently doesn't support issuing wildcard certificates (commonly called wildcard certs?), requiring all domain names to be listed individually. (Though personally, if manual certificate replacement is needed,...

Using Docker Build Args to Share a Single Dockerfile Across Multiple Architectures
Since I have multiple architecture devices running Docker (including x86 servers, Raspberry Pi, Tinker Board), for each commonly used software, I need to build an image for each different architecture . Previously, my approach was to maintain a separate Dockerfile for each architecture, similar to this : You can see that each Dockerfile is almost identical except for the base image referenced in the FROM instruction. While this management method simplifies writing build scripts (travis.yml) by allowing direct docker build commands for each, the drawback is obvious: every time the software version updates or I decide to add/remove a feature, I have to modify multiple Dockerfiles. Two days ago while researching, I discovered a Docker feature: Build Args,...