A dynamic loading method based on C language

By synchronously residing the old and new versions of dynamic link libraries in the main process memory space and establishing memory address mapping, the problems of long-term interruption and high memory consumption during upgrades of resource-constrained devices are solved, achieving microsecond-level business continuity and high availability.

CN122431647APending Publication Date: 2026-07-21SHANGHAI INNOVATECH INFORMATION TECH
View PDF 0 Cites 0 Cited by

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
SHANGHAI INNOVATECH INFORMATION TECH
Filing Date
2026-04-14
Publication Date
2026-07-21

AI Technical Summary

Technical Problem

When upgrading firmware or expanding functionality on existing resource-constrained devices, critical services are interrupted for extended periods due to the need for complete system erasure and reboot. Furthermore, conventional dynamic library loading solutions consume excessive memory and cannot be implemented on devices with limited RAM.

Method used

By synchronously residing the new version of the dynamic link library and the old version of the dynamic link library in the memory space of the main process, a cross-library memory address mapping relationship is established. The context state data of the old version runtime is read and converted into the data structure of the new version to realize the cross-version transfer of variable state. The memory-level instruction handover is completed by modifying the function pointer at the main process level.

Benefits of technology

It enables business interruption to be completed within microseconds, avoiding the whole-machine Flash erasure and system restart process of traditional OTA firmware upgrades, reducing memory overhead, and improving the system's fault tolerance and long-term high availability.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122431647A_ABST
    Figure CN122431647A_ABST
Patent Text Reader

Abstract

The application relates to the technical field of embedded systems, and discloses a dynamic loading method based on C language, which aims at the pain point that the traditional OTA upgrade consumes a large amount of memory and causes long-time interruption of services, and the application pre-compiles an application into a position-independent dynamic module. When loading, the system dynamically allocates physical memory and performs base address relocation, and registers module symbols to a global hash table to establish system call mapping. In the hot update stage, the system pre-allocates memory for a new version of the module in the background and constructs a shadow symbol table, then suspends underlying task scheduling in a very short time, atomically overwrites the execution pointer in the hash table, instantaneously completes routing redirection of the new and old modules, and safely unloads the old module to recycle resources after confirming that the operation is healthy. The application does not need to restart the whole machine, realizes millisecond-level non-susceptible upgrade under low RAM consumption, and ensures the continuity of key services.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention relates to the field of embedded system technology, specifically to a dynamic loading method based on the C language. Background Technology

[0002] With the rapid development of the Internet of Things (IoT) and smart wearable devices, terminal devices face increasingly frequent demands for functional iterations and algorithm upgrades throughout their lifecycle. Currently, the industry mainly uses traditional over-the-air (OTA) firmware updates to achieve system updates. This upgrade method typically requires the device to download the complete image file and perform a full or differential erase / write operation on the underlying non-volatile memory, followed by a forced device reboot for the new firmware to take effect. This physical-level reboot mechanism causes the device to completely lose responsiveness for tens of seconds or even minutes. For scenarios with stringent business continuity requirements, such as continuous heart rate monitoring and real-time industrial control, this prolonged business interruption is extremely disruptive and unacceptable.

[0003] To avoid business interruptions caused by system reboots, some advanced operating systems have introduced standard dynamic link library mechanisms (such as the dlopen mechanism in Linux) to achieve modular loading and hot replacement of applications. However, the in-depth analysis process of these standard dynamic loading schemes is cumbersome and highly dependent on complex operating system kernel functions and a large virtual memory management unit (MMU). During operation, they generate significant runtime memory (RAM) fragmentation and system overhead. For resource-constrained microcontrollers (MCUs) or lightweight real-time operating systems (RTOSs) with main control RAM often only a few hundred KB or even tens of KB, this high memory overhead solution is impractical.

[0004] Current explorations into modular operation for lightweight embedded devices generally lack fine-grained management of dynamic module lifecycles and system-level resource isolation and tracking mechanisms. During runtime, dynamic modules often call underlying system interfaces to request various public resources. When a module needs to be hot-updated or uninstalled, due to the lack of precise recording of its context state, the system cannot accurately identify and remove the old module's exclusive handles (such as active timers, file handles, and network sockets). This leads to two main problems when performing resource reclamation: either incomplete cleanup resulting in serious memory leaks and illegal dangling pointer callbacks, or a brute-force global reset strategy that could easily kill other normally running, unrelated background tasks, seriously threatening the long-term system security and high availability of resource-constrained devices. Summary of the Invention

[0005] To address the shortcomings of existing technologies, this invention provides a dynamic loading method based on the C language, which solves the problems of long-term interruption of critical services when performing firmware upgrades or function expansions on existing resource-constrained devices, which require complete machine erasure and restart, and the excessive memory consumption of conventional dynamic library loading solutions, making them unsuitable for devices with small RAM.

[0006] To achieve the above objectives, the present invention is implemented through the following methods:

[0007] This invention provides a dynamic loading method based on the C language, comprising the following steps: Obtain the update instruction for the target functional module, wherein the update instruction carries the storage path of the new version of the dynamic link library; According to the storage path, the new version of the dynamic link library is loaded into the memory space of the main process, and the function addresses of the new version of the dynamic link library are resolved. Extract the context state data of the old version of the dynamic link library when it runs in the main process, and map the context state data to the memory address of the new version of the dynamic link library; The function pointer that calls the target functional module in the main process is redirected to the function address, so that the main process calls the new version of the dynamic link library; When the main process stops calling the old version of the dynamic link library, the old version of the dynamic link library is unloaded from the memory space of the main process.

[0008] The innovative principle of this invention lies in establishing a cross-library memory address mapping relationship by synchronously residing both the new and old versions of dynamic link libraries in the main process's memory space. By reading the runtime context state data of the old version and converting it into a new version data structure for writing, cross-version transfer of variable states is achieved. Furthermore, by modifying the memory address of function pointers at the main process level, subsequent call requests from the main process are switched from the old version's physical address to the new version's physical address, completing memory-level instruction handover.

[0009] Preferably, the steps of loading the new version of the dynamic link library into the memory space of the main process and resolving the function addresses of the new version of the dynamic link library specifically include: The system calls the dynamic loading interface provided by the operating system to load the new version of the dynamic link library into the memory space of the main process according to the storage path, and obtains the handle of the new version of the dynamic link library. Based on the handle and the preset function symbol name, the symbol resolution interface is invoked to obtain the function address corresponding to the preset function symbol name, and the function address is stored in the global function routing table; wherein, the preset function symbol name is determined according to the standardized business interface protocol of the target functional module.

[0010] The technical principle of this step is as follows: by utilizing the operating system's dynamic loading and symbol resolution mechanism, the pre-agreed standardized business interface protocol is converted into an absolute function address in the current memory space, and a global function routing table is constructed, thereby providing a definite physical address basis for the pointer redirection operation of the main process.

[0011] Preferably, the step of mapping the context state data to the memory address of the new version of the dynamic link library includes: The global and static variables generated during the runtime of the old version of the dynamic link library are read through a preset state acquisition interface and used as the context state data; wherein, the preset state acquisition interface is set according to the memory layout characteristics of the old version of the dynamic link library. According to the data structure definition of the new version of the dynamic link library, the context state data is format-converted to obtain converted state data; the converted state data is written into a preset data area allocated in the memory space by the new version of the dynamic link library to complete the mapping of the context state data; wherein, the preset data area is allocated according to the capacity size of the structure used to store the context state in the new version of the dynamic link library.

[0012] The technical principle of this step is as follows: based on the memory layout characteristics, the underlying variable state is directly read, and through the structure format conversion operation, the byte alignment difference of the underlying data structure between different compilation versions is eliminated, ensuring that the state data is accurately written into the physical memory area allocated by the new version.

[0013] Preferably, the step of having the main process call the new version of the dynamic link library specifically includes: Lock the threads of the main process to suspend the main process's calls to the target functional module; The current function pointer in the main process that points to the old version of the dynamic link library is modified to the function address of the new version of the dynamic link library; the thread of the main process is unlocked, the calling task is restored, and the main process calls the new version of the dynamic link library through the modified function pointer.

[0014] The technical principle of this step is as follows: a thread lock concurrency control mechanism is used to perform a function pointer memory address overwrite operation during the instruction execution cycle of the paused task, so as to prevent concurrent calls from occurring during the non-atomic operation of pointer modification and triggering memory access violations (segmentation faults).

[0015] Preferably, the step of unloading the old version of the dynamic link library from the memory space of the main process specifically includes: A reference counting mechanism is used to monitor the main process's call status to the old version of the dynamic link library; when the reference count of the old version of the dynamic link library reaches zero, it is determined that the main process stops calling the old version of the dynamic link library. Call the dynamic unload interface to release the memory space occupied by the old version of the dynamic link library, and set the handle corresponding to the old version of the dynamic link library to null.

[0016] The technical principle of this step is as follows: a reference counter is used to track the access activity of a specific memory address range. Memory reclamation is performed when all active calling tasks are cleared (the counter is zero), to prevent unfinished calling tasks from being interrupted due to the premature release of the physical memory corresponding to the instruction.

[0017] In one specific embodiment, after obtaining the update instruction of the target functional module and before loading the new version of the dynamic link library into the memory space of the main process according to the storage path, the method further includes: Calculate the hash value of the new version of the dynamic link library; compare the hash value with a preset standard hash value; wherein the preset standard hash value is determined based on the integrity verification file generated during the compilation and packaging stage of the new version of the dynamic link library; If the hash value matches the preset standard hash value, then the step of loading the new version of the dynamic link library into the memory space of the main process is executed; if the hash value does not match the preset standard hash value, then the loading of the new version of the dynamic link library is refused, and a corresponding security alarm message is generated.

[0018] The technical principle of this step is: to perform binary file comparison based on cryptographic hash algorithm, and to block the injection of tampered or incomplete code files into the main process memory space before the operating system performs memory loading.

[0019] In one specific embodiment, after redirecting the function pointer that calls the target functional module in the main process to the function address, the method further includes: Monitor the running status of the new version dynamic link library during a preset observation period; wherein the preset observation period is determined based on the cumulative number of business processing requests received by the new version dynamic link library and a preset stable operation evaluation threshold; If a runtime crash exception is detected in the new version of the dynamic link library and the old version of the dynamic link library has not been completely uninstalled, the function pointer in the main process will be redirected to the memory address of the old version of the dynamic link library, and the execution of the old version of the dynamic link library will be restored through the context state data.

[0020] The technical principle behind this step is as follows: Establish an observation period based on business processing volume, maintaining the memory allocation and handle validity of the old version's dynamic link library until the new version is confirmed to be running stably. When an exception signal is captured, reverse the pointer redirection and state data writing operations to achieve a hardware-level rollback of the call chain to the historical version.

[0021] In one specific embodiment, the step of obtaining the update instruction of the target functional module specifically includes: creating an independent listening thread in the main process; The listening thread is bound to a preset inter-process communication port; wherein the preset inter-process communication port is determined based on the operating system's idle network port pool and the main process's secure communication policy; when a data packet sent by an external process through the inter-process communication port is received, the data packet is parsed to extract the update instruction and the storage path of the new version dynamic link library.

[0022] The technical principle of this step is to establish an out-of-band communication channel independent of the main process's business logic through the inter-process communication port (IPC), thereby isolating the dynamically loaded control command receiving process from the regular business data processing process at the port listening level.

[0023] In one specific embodiment, after loading the new version of the dynamic link library into the memory space of the main process, and before resolving the function addresses of the new version of the dynamic link library, the method further includes: Obtain the starting address and length of the memory page occupied by the new version of the dynamic link library in the main process; call the operating system's memory protection control interface to modify the access permissions of the memory page corresponding to the starting address and the length of the memory page to read and execute permissions, and cancel the write permissions of the memory page.

[0024] The technical principle of this step is as follows: based on the operating system's memory paging management mechanism, the attributes of the newly allocated code segment memory page are reset (implementing a write and execution mutual exclusion mechanism) to block runtime overwrite operations on the dynamic link library memory space.

[0025] In one specific embodiment, before extracting the context state data of the old version of the dynamic link library running in the main process, the method further includes: The system intercepts new business processing requests sent by the main process to the old version of the dynamic link library and stores the new business processing requests in the request buffer queue; it waits for the old version of the dynamic link library to finish executing the historical business requests it is currently processing and triggers a status extraction signal; after redirecting the function pointer of the target function module called in the main process to the function address, the system sends the new business processing request in the request buffer queue to the new version of the dynamic link library for processing.

[0026] The technical principle of this step is as follows: before the execution state extraction action, an execution sequence synchronization barrier is set up, and the input data in the pointer redirection cycle is isolated by using a request buffer queue; after the address switch is completed, the queue data is released to maintain the time sequence continuity of the input data stream distributed within the main process.

[0027] This invention provides a dynamic loading method based on the C language. It has the following advantages: 1. This invention pre-compiles the application into a position-independent dynamic module file. During loading, it allocates a contiguous physical memory block for the corresponding module and performs basic base address relocation. Finally, it registers exported symbols to a system-level global hash table. This feature eliminates the large and complex dynamic link library (such as dlopen) management mechanism in traditional operating systems, reducing memory overhead. This allows the solution to be implemented with lower RAM consumption in devices with extremely limited main control resources, such as smart wearables and IoT nodes.

[0028] 2. During hot updates, this invention first pre-allocates memory for the new version module and builds a shadow symbol table in the background. Then, within a very short time after suspending the underlying task scheduling, it forcibly overwrites the call pointer in the global hash table through atomic operations to complete route redirection. This feature avoids the whole-device Flash erasure and system restart process required by traditional OTA firmware upgrades, compressing the service interruption time from tens of seconds to microseconds, ensuring the continuity of critical device services (such as continuous heart rate monitoring) and a seamless user experience.

[0029] 3. This invention introduces an independent context control block for each dynamic module, accurately recording its requested dedicated system handles (such as active timers, files, and network sockets). When a module is unloaded or abnormally rolled back, the system can precisely unbind and forcibly close the dedicated handle by traversing the record array, deregister the symbol from the global hash table, and finally release the corresponding physical memory area. This feature effectively avoids global resource miskilling or memory leaks, blocks illegal out-of-bounds callbacks, and improves the system's fault tolerance and long-term high availability. Attached Figure Description

[0030] Figure 1 This is a diagram illustrating the overall architecture of the dynamic loading system according to an embodiment of the present invention. Figure 2 This is a flowchart illustrating the main steps of the dynamic loading method according to an embodiment of the present invention. Figure 3 This is a comparison chart of peak memory usage for different architecture schemes in this invention. Figure 4 This is a schematic diagram illustrating the service availability of traditional OTA firmware upgrades according to an embodiment of the present invention; Figure 5 This is a schematic diagram illustrating the service availability of the LVM zero-downtime update scheme according to an embodiment of the present invention. Detailed Implementation

[0031] The methods described below with reference to the accompanying drawings of the embodiments of the present invention will be clearly and completely described. Obviously, the described embodiments are only some embodiments of the present invention, and not all embodiments. Based on the embodiments of the present invention, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of the present invention.

[0032] See attached document Figure 1 This embodiment provides a dynamic loading method based on the C language. The overall system architecture, from bottom to top, includes a hardware layer, an operating system layer, a platform interface layer, a dynamic load manager, and a dynamic application layer. The hardware layer provides basic central processing unit and storage resources. The operating system layer is a real-time operating system or a bare-metal system, responsible for basic task scheduling. The platform interface layer encapsulates various functional components of the underlying system, including string processing, memory management, timers, multimedia control, graphical user interface drawing, file system read / write, input device event response, date and time processing, mathematical operations, network communication, and call / SMS control. The dynamic load manager is responsible for identifying external application files, performing memory allocation, address relocation, and symbol binding. The dynamic application layer consists of independently compiled C language applications, which are loaded into memory and executed on demand during system runtime.

[0033] In constrained operating environments, system main memory space is limited. Traditional methods statically link all applications with the system kernel into a single executable firmware. This approach requires recompilation and system flashing when functionality is expanded. This invention constructs a dynamic runtime environment based on position-independent code, outside of the conventional memory allocation of the operating system. The system maintains a dynamically loaded area in runtime memory. Application files are normally stored in non-volatile storage media. When a startup command is received, the system reads the program file completely or in pages into the dynamically loaded area for execution. After the application closes, the system immediately reclaims this memory, achieving memory space reuse.

[0034] The specific environment initialization and loading / running logic is implemented through the following steps: S101, Platform Interface Layer Initialization and Global Symbol Table Construction. After system startup, the external initialization function `extern void LVM_Manager_init(void);` is called to complete the basic settings of the dynamic loading manager. The system pre-builds a global symbol table in memory, mapping the names of all standard API functions provided by the platform interface layer to their corresponding absolute physical memory addresses in the system firmware. To improve lookup efficiency, the global symbol table preferably uses a hash table structure for storage. The specific hash function mapping principle and collision resolution mechanism of the hash table can be conventionally designed using chaining or open addressing methods by those skilled in the art; their specific implementation is well-known in the field and will not be elaborated here.

[0035] S102, Identification and Parsing of Dynamic Module Files. Dynamic applications are written in C during the development phase, with the compiler's position-independent code options configured to generate a pure binary image file that does not depend on a specific memory load address. This file consists of a custom header, code segment, read-only data segment, and the application's own symbol export table. Upon receiving the load instruction, the system reads the header data and calls the parsing interface: externBOOLLVM_FileheadParse(U16 p_filename,FileHeader p_st_filehead); Complete the extraction of application information. The application file information structure definition is as follows: typedef struct { U16 fileNameLength; U16 fileName[MAX_APP_FILENAME_LENGTH]; U16 appNameCh

[20] ; U16 appNameEn

[20] ; U32 iconSize; U32 iconAddr; AppfileInfo; The file header structure used for precise control of loading behavior is defined as follows: typedef struct { unsigned short ID; unsigned short Platform; unsigned short version; unsigned short headSize; unsigned intimageSize; unsigned short CheckType; unsigned short CheckValue; wchar_tChineseName

[20] ; wchar_tEnglishName

[20] ; unsigned intaddr; unsigned intallRAMSize; unsigned intallocationinfosize; unsigned inticonSize; FileHeader; In the above structure and various parts of the code of this invention, the data type symbols are defined as follows: U8 represents an 8-bit unsigned integer, U16 represents a 16-bit unsigned integer, and U32 represents a 32-bit unsigned integer; S8 represents an 8-bit signed integer, S16 represents a 16-bit signed integer, and S32 represents a 32-bit signed integer; wchar_t is a wide character type used to store Unicode encoded character data; MAX_APP_FILENAME_LENGTH is a system-preset maximum length constant for application file paths.

[0036] The application file information structure records the file name length, Chinese and English names, and the position and size of the desktop icon, used for UI display in the app store or on the device desktop. The file header structure provides the underlying parameters required for loading: Id identifies the file type, Platform specifies the applicable hardware platform, and version records the software version. CheckType and CheckValue checks ensure file integrity during transmission and storage. headSize and imageSize indicate the size of the header data and the actual executed code segment, respectively. The addr parameter stores the relative offset address set at compile time, and allRAMSize indicates the total memory required for code space and static variable data space, providing a baseline for subsequent memory allocation.

[0037] S103, Memory allocation and data copying are performed. The dynamic loader manager, based on the allRAMSize value parsed from the file header, requests memory from the operating system's heap or a pre-defined contiguous memory pool. If the remaining contiguous memory meets the requirements, the system returns the starting memory pointer. On hardware platforms with memory protection units, the system changes the access permission attribute of the allocated memory segment to executable permission to prevent illegal instruction execution exceptions from occurring in the regular data area. Subsequently, the system copies the file body data located in non-volatile memory, skipping the length specified by headSize, and precisely copies the code segment and data segment of size imageSize to the allocated memory space.

[0038] S104, Address Relocation and System Interface Binding. Because dynamic applications are compiled in a position-independent code format, their internal relative jumps and local data addressing do not depend on physical absolute addresses. When global variable addressing or cross-module function calls are involved, the dynamic load manager traverses the application's built-in relocation information table. Based on the currently allocated memory starting address, the system calculates the offset difference and corrects the on-premises addresses of instructions in the application code segment involving external addressing. Simultaneously, the manager parses the platform system interfaces that the application module needs to reference, searches for matching system function names in the global symbol table built in S101, obtains the corresponding underlying firmware absolute addresses, and fills them back into the application's input symbol table. At this point, the dynamic application has complete runtime conditions and establishes a connection with the underlying system environment.

[0039] S105, Program Entry Point Call and Lifecycle Management. After relocation, the dynamic loading manager locates the application's starting execution instruction pointer based on a fixed entry offset and transfers control to the dynamic application. To standardize application behavior, the system requires each loaded module to implement a set of standard lifecycle management interfaces, including: application main entry interface `void LVM_main(void)`, used to execute application initialization and main business logic after loading; application exit interface `void LVM_exit(void)`, used to release internally generated temporary resources before the application is closed by the user or forcibly reclaimed by the system; application pause interface `void LVM_pause(void)`, triggered when a high-priority interrupt event such as a phone call occurs, causing the current application to suspend execution, and resuming business state upon a second trigger; and application reset interface `void LVM_reset(void)`, used to clear the internal state and restore the application to its initial running environment. For low-level common techniques such as file reading and memory pointer operations, those skilled in the art can make corresponding calls based on the specific platform support library; these are well-known techniques in the field and will not be elaborated upon here.

[0040] See attached document Figure 2 This dynamic loading method, based on the C language, relies on position-independent code technology, a custom loader, and a symbol table registration mechanism. It is primarily used in resource-constrained real-time operating systems (RTOS) or embedded devices without standard dynamic link library support. Its complete main process includes the following steps: Step S210 involves compiling and packaging the application's C source code into a dynamic module file of a specific format. To avoid dependence on a specific runtime environment and absolute memory addresses, the source code is compiled into Position Independent Code (PIC) format during the compilation phase. In an environment without an operating system, it is directly compiled into a pure binary image file (.bin). The completed dynamic module file is logically divided into a code segment (.text), a read-only data segment (.rodata), and a custom symbol export table.

[0041] When packaging and generating dynamic module files, a custom module header structure is written to the file header. The custom module header structure consists of an application file information structure (AppfileInfo) and a file header information structure (FileHeader). The application file information structure is used to record the application's basic and display attributes. The specific structure definition includes: fileNameLength (a 16-bit unsigned integer, recording the filename length), fileName (an array of filenames with a maximum length limit), appNameCh (an array of Chinese names), appNameEn (an array of English names), iconSize (a 32-bit unsigned integer, recording the application icon size), and iconAddr (the offset address of the icon relative to the beginning of the file). The file header information structure is used to record the core attributes required for loading and memory allocation. The specific structure definition includes: Id (a 16-bit unsigned integer, recording the file type identifier and also serving as a magic number for verifying legality), Platform (platform identifier), version (version number), headSize (size of the file header in bytes), imageSize (size of the image entity data), CheckType and CheckValue (type and check value used for integrity verification), ChineseName and EnglishName (Chinese and English names defined with wide characters), addr (offset address specified at compile time), allRAMSize (the sum of code space and static variable data space, used for memory allocation reference), allocationinfosize (size of location and relocation information), and iconSize (icon size).

[0042] Step S220: Receive and parse the startup command. When the device receives the application's startup command, the custom loader reads the dynamic module file under the corresponding path into the system memory buffer through the file system interface and parses and verifies the legality of the module header structure. Specifically, it reads the FileHeader data block at the beginning of the memory buffer, extracts the Id field to verify whether the magic number matches the preset security identifier (e.g., verifying whether its value is 0x4D4F4458). If the magic number comparison fails or the version verification fails, loading is interrupted and the buffer is released; if the verification passes, the memory allocation stage begins.

[0043] Step S230: Allocate an executable memory region and perform data migration. The custom loader reads the code space size and data space size parameters from the FileHeader structure and requests a contiguous memory block of sufficient capacity from the underlying system. To ensure the normal execution of subsequent code, the read, write, and execute permissions of the newly requested memory region are set to readable, writable, and executable states through the underlying system interface. Subsequently, the actual content (including the code segment and read-only data segment, with a length equal to the sum of the code space and data space sizes indicated in the FileHeader) after skipping the custom module header structure in the memory buffer is copied as a whole to the newly allocated executable memory region. Regarding the memory page table settings and permission control operations involved in the underlying hardware, those skilled in the art can perform conventional settings based on the specific operating system and chip architecture used. The memory protection and allocation mechanisms are well-known technologies in the field and will not be elaborated upon here.

[0044] Step S240 involves address relocation and symbol table registration to establish the calling relationship between the dynamic module and the underlying system capabilities. If the dynamic module is not completely position-independent code, the addresses of the code segment instructions requiring relocation are corrected based on the location verification information contained at the end of the module file and the actual starting address of the allocated memory. Next, the symbol export table of the dynamic module is read, and its internal function entry points and variable symbols are registered in the host system's global hash table. The global hash table enables the management of the internal functional interfaces of the dynamic module.

[0045] Step S250: Calculate the module's entry point and start the application. Obtain the program handle of the dynamic module by superimposing the base address of the executable memory region with the entry offset recorded in the FileHeader structure. This program handle directly points to the module's initialization entry function (e.g., plugin_init). Call this entry function, relinquish execution control, and thus allow the dynamic module to begin running in its independent memory space.

[0046] During runtime, dynamic modules implement various complex functions through a series of standard application programming interfaces (APIs) provided by the system. The platform abstracts and exposes a multi-dimensional adaptation interface library at the underlying level, and dynamic modules call these interfaces through pre-bound symbolic references. The specific scope of these interfaces covers: Basic data and computation: String processing interfaces in both ANSI and UNICODE encoding formats; mathematical function interfaces providing arithmetic operations and trigonometric functions; date and time conversion and system clock tick acquisition interfaces. Resource and peripheral control: Interfaces for allocating and releasing system memory blocks (including fast memory management channels); timer creation and closing interfaces for non-blocking scheduling; Graphics Device Interface (GDI) for screen drawing and primitive operations; audio and video multimedia file playback and control interfaces; device vibration control interfaces; and input callback interfaces for capturing physical button and touchscreen coordinate events. Communication and storage: File system interfaces for complete lifecycle management of files and directories; Socket creation and sending / receiving interfaces based on the TCP / IP protocol suite; communication interfaces for calling the underlying baseband to implement call dialing and SMS sending; and WAP web browser connection interfaces.

[0047] To standardize the lifecycle management of dynamic modules, this scheme stipulates that dynamic modules must expose standard control interfaces in their code implementation for the host system to call back in different states. Specifically, these include: LVM_main (the main entry function for application startup), LVM_exit (the cleanup function when the application is actively closed or terminated abnormally), LVM_pause (the function for pausing and resuming operation when system focus changes), and LVM_reset (the function for resetting the state when the runtime environment is abnormal).

[0048] Step S260 involves unloading and reclaiming resources from the dynamic module. When the application finishes using it and exits, or when the system detects excessive RAM fragmentation in a resource-constrained environment and requires memory reclamation, the program handle of the module is passed to trigger the unloading mechanism. The host system first unregisters all exported symbol mappings associated with the handle using a global hash table to block subsequent illegal calls; then, it calls the system-level memory release function to release the entire executable memory region allocated in step S230 and return it to the system memory pool. By using a "load as needed, unload as finished" approach, the peak static memory usage of the overall system is reduced.

[0049] See attached document Figure 2 The dynamic loading method of this invention relies on the parsing, verification, and memory mapping of dynamic libraries. This process does not depend on the dynamic link library loader provided by the standard operating system; it directly processes the pure binary image file output from position-independent code compilation. The dynamic loading mechanism specifically includes the following steps: S310 reads the dynamic module file and performs basic information verification. The system opens the dynamic module file at the specified absolute path through the file management interface. The file header data is read into the memory buffer. To ensure security and compatibility, the beginning of the module file is defined as a custom module header structure with a fixed format. The relevant structure code is as follows: typedef struct { unsigned short ID; unsigned short Platform; unsigned short version; unsigned short headSize; unsigned intimageSize; unsigned short CheckType; unsigned short CheckValue; wchar_tChineseName

[20] ; wchar_tEnglishName

[20] ; unsigned intaddr; unsigned intallRAMSize; unsigned intallocationinfosize; unsigned inticonSize; FileHeader; In the above structure, Id represents the file type identifier; Platform indicates the type of hardware platform to which the module is applicable; version is used for version control; headSize indicates the total number of bytes occupied by the current file header structure; imageSize indicates the actual size of the executable image data after the file header; CheckType indicates the security verification algorithm type; CheckValue stores the corresponding check value; ChineseName and EnglishName are used to store the Chinese and English names of the module, respectively; addr records the base offset address specified by the module during compilation; allRAMSize indicates the total code space and data space required by the module at runtime; allocationinfosize indicates the size of the relocation information; and iconSize indicates the size of the space occupied by the application icon.

[0050] After reading the aforementioned structure, the loader verifies the built-in magic number. If the magic number matches, it further verifies whether the Platform is consistent with the current runtime environment and whether the version is within a compatible range. Subsequently, it calculates the checksum of the image data according to the verification algorithm specified by CheckType and compares it with CheckValue. If the comparison fails, it determines that the file has been tampered with or corrupted, and the system terminates the loading process and releases related resources. For the specific implementation of the verification algorithm, those skilled in the art can use cyclic redundancy check or hash algorithm; the specific calculation logic is well-known in the field and will not be elaborated here.

[0051] S320 allocates executable memory space and loads the image data. After header verification passes, the system requests a contiguous block of physical memory from the system memory manager based on the allRAMSize information in the header structure. The requested memory region must have read, write, and execute permissions. After acquiring contiguous memory, the file header is skipped based on headSize, and a binary data block of length imageSize is completely copied into that memory region. For memory allocation and copy operations, the system directly calls the underlying API_Malloc and API_Memcpy interfaces to complete the process.

[0052] S330 performs base address relocation processing for position-independent code. Since the starting physical address of memory allocated each time a dynamic module is loaded into an embedded device cannot be fixed, the module is compiled as position-independent code. When the module image data contains absolute address references, the system needs to correct them using the location information at the end of the module file. The length of this location information is determined by `allocationinfosize`. The loader calculates the difference between the currently allocated starting memory address and the base address `addr` preset at compile time. Based on the relocation information table, it iterates through all address entries in the image memory that need correction, adding the difference to the original address value to establish its actual runtime address. If the module is compiled entirely using pure position-independent code, meaning that internal addressing relies entirely on offsets relative to the program counter, this correction process is omitted.

[0053] S340, register the dynamic module symbol table to the system-level hash table. The module image contains a symbol export table structure, which records the names of the function interfaces provided by the module and their offsets relative to the start of the image. The system traverses this export table, storing the name string of each symbol and its corresponding absolute runtime address into the global symbol hash table. Through this mechanism, the main program or other modules can retrieve the specific function pointers within the module using the symbol name string.

[0054] S350 binds external interface calls and entry function execution. During runtime, dynamic modules need to call the system's underlying hardware control interfaces, which are embedded in the system's main program as application programming interfaces (APIs). When a module is loaded, it contains an unresolved external symbol reference table. The loader queries the system-exported public function address table, replacing each null pointer recorded within the module with the actual system API address. After completing all address bindings, the loader obtains the address of the module's initialization function through the global symbol hash table, defines the following function pointer, and executes the call: typedefint( plugin_init_fn)(void); The code above defines a function pointer type named `plugin_init_fn`, which takes no parameters and returns an integer status code. The system forcibly casts the address of the found initialization function to this type and initiates the call to complete the internal state initialization and business logic startup of the dynamic module. After the loader obtains the module handle and returns it, the module enters a controlled running state.

[0055] See attached document Figure 2 In this embodiment, the lifecycle management of the dynamically loaded module is implemented through a standardized application interface. This mechanism standardizes the complete business sequence of the dynamic module from loading, running, pausing, resuming, to unloading. For the underlying task scheduler implementation, hardware interrupt response mechanism, and basic thread stack management of the RTOS, those skilled in the art can adapt and configure them according to the specific MCU architecture and RTOS kernel selected. The register push and pop operations at the context switching level are well-known technologies in the field and will not be described in detail here.

[0056] To control and transfer module states, the system allocates and maintains a module context control block in main memory for each dynamically loaded application. This control block records the module's running state, physical memory boundaries, allocated system resource handles, and state machine callback function entry points. The relevant structure definition and code implementation are as follows: typedef enum { LVM_STATE_UNINIT = 0, LVM_STATE_RUNNING, LVM_STATE_PAUSED, LVM_STATE_EXIT } LVM_State; typedef struct { U32 module_id; void code_segment; void data_segment; LVM_State current_state; void ( lvm_main)(void); void ( lvm_pause)(void); void ( lvm_reset)(void); void ( lvm_exit)(void); U32 active_timers

[10] ; U8 timer_count; S32 active_files[5]; SOCKET active_sockets[3]; } LVM_Context; In the code above, `LVM_State` is a module state enumeration type, containing four state enumeration values: uninitialized, running, paused, and exited; `LVM_Context` is a module context control block structure; `module_id` represents the unique identifier assigned to this module by the system; `code_segment` and `data_segment` record the starting pointers of the module's code segment and data segment in RAM, respectively; `current_state` records the current business state; `lvm_main`, `lvm_pause`, `lvm_reset`, and `lvm_exit` correspond to the pointers to the lifecycle functions exported by the module; the `active_timers` array records the timer IDs requested by this module through `API_CreateTimer`, with a maximum of 10 timers allowed to be created simultaneously according to system settings; `timer_count` records the number of timers currently in use; `active_files` and `active_sockets` store the file handles and network socket handles opened by this module, respectively, for forced resource reclamation in abnormal states.

[0057] S401, Initialization and Registration of Module Context Sequence. After the loader completes file header parsing using the LVM_FileheadParse function and allocates executable memory using API_Malloc, the system resolves the exported symbol table of the module, extracts the pointers to the four core business control functions mentioned above, and mounts them to the newly created LVM_Context control block. At this time, current_state is initialized to LVM_STATE_UNINIT.

[0058] S402, Startup and Foreground State Transition. The system scheduling engine updates the state machine variable `current_state` to `LVM_STATE_RUNNING` by calling the `lvm_main` function pointer extracted from the control block. `lvm_main` serves as the global entry point for the C language dynamic application, internally executing the module's business initialization. In this sequence, the module registers one-time or periodic timers via `API_CreateTimer`, registers physical keyboard and touchscreen event callbacks via `API_SetKeyDownEvent` and `API_SetPenDownEvent`, and requests control of the screen display area via `API_GetScreenBuffer`. During this stage, the system captures all handle resources requested by the module and synchronously records them in `LVM_Context`.

[0059] S403, Context State Suspension and Resumption Transfer Mechanism. When the system detects a high-priority system event, such as an incoming cellular call, a system-level battery alarm, or a user switching applications via the system home button mapped by API_SetKeyDownEvent, the system scheduling engine intervenes in the execution flow of the current module. To ensure reasonable allocation of the wearable device's limited memory and CPU resources, the system triggers a state transition, calling the module's lvm_pause function. If the current_state is LVM_STATE_RUNNING, lvm_pause is executed to trigger a module suspension operation, and the system then switches the current_state to LVM_STATE_PAUSED. During this state transition, the underlying system iterates through the active_timers array in LVM_Context, suspending relevant timers and temporarily blocking the dispatch of button and touchscreen input callback events registered by the module. This design prevents background C modules from continuing to consume MCU computing power or triggering illegal memory overflow redraws. When the high-priority system event is processed, the user reschedules the module to the foreground, the system resumes the transfer, and the lvm_pause function is called a second time. The module performs UI redrawing and data synchronization according to its own business logic. The system synchronously restores current_state to LVM_STATE_RUNNING and removes the event masking of timers and peripheral callbacks.

[0060] S404, Module Reset and De-sequence of Abnormal States. While the module is running continuously, if the system watchdog detects consecutive logical timeouts in the timer callbacks registered by the module, or if the user triggers a partial application reset by long-pressing a specific key combination, the system scheduling engine calls the `lvm_reset` function within the control block. This operation guides the module to perform a cleanup of its internal temporary data cache and resets the module's internal business flow state machine to the initial ready stage immediately after `lvm_main` has finished executing. This mechanism neither releases nor reallocates the physical memory where `code_segment` and `data_segment` reside, thus achieving a hot restart of the application module without triggering read operations from external storage devices (such as SPIFlash), improving the system's fault tolerance and recovery speed.

[0061] S405, Exit Sequence and Safe Reclamation of Memory Space. When the user actively closes the application through the UI, or when the system-level memory allocator (API_Malloc) returns NULL triggering a memory alarm, the system forcibly initiates reclamation and transfer, calling the lvm_exit function. Inside this function, the module performs routine cleanup actions, such as calling API_FClose to release the occupied file stream handles and calling API_SocketClose to disconnect network connections. If the module has unprocessed resources, after lvm_exit returns, the system scheduling engine will iterate through the active_files and active_sockets arrays in LVM_Context to forcibly close them, and cancel any remaining timers using API_CloseTimer. After resource stripping is complete, current_state changes to LVM_STATE_EXIT, the loader calls API_Free to release code and data space, cancels the application entry in the global symbol table, and finally destroys the LVM_Context structure, completing the business sequence loop.

[0062] See attached document Figure 2 In real-time operating systems such as wearable devices, where resources are limited and long-term stable operation is required, directly unloading the old module and loading the new module when upgrading or replacing an already loaded dynamic module will render the system unusable during this period. To address the business interruption issue during module updates and the risk of system crashes due to compatibility or logical defects in new modules, this invention provides a pointer redirection and exception rollback implementation scheme based on a global symbol table.

[0063] As a preferred implementation method, the implementation process of this mechanism specifically includes the following steps: The S501 allocates independent physical memory space for new versions of dynamic modules in the system background. After receiving a new module file, the system calls a custom loader to read the module header information and performs a validity check on the file based on the checksum type in the header. If the verification passes, it allocates a contiguous address space for the new module in a free executable memory region by calling API_Malloc or API_MallocFastMem, and copies the new module's code segment and read-only data segment into that space. During allocation and copying, existing system services continue to call and execute the code of the old version module, and the current device's services are unaffected.

[0064] S502, construct a shadow symbol table and parse the exported symbols of the new module. The system traverses the symbol export table in the new module structure, extracting all exported function names and their offsets relative to the module's starting address. Combining this with the starting physical address of the memory allocated in S501, the system calculates the absolute physical address of each function in the new module and establishes a shadow symbol table corresponding to the new version in memory. The method for calculating symbol hash values ​​and the address mapping and collision handling mechanism of the hash table can be implemented using existing conventional algorithms such as CRC32 or BKDRHash by those skilled in the art. The specific calculation logic is well-known in the field and will not be elaborated here.

[0065] To support the above mapping logic, the symbol table entries and header structure maintained internally by the system are defined as follows: / / Symbol form item structure definition typedef struct _SymbolEntry { U32 symbol_hash; / / Export the hash value obtained by processing the symbol name. void func_ptr; / / The actual physical address in memory of this function or variable SymbolEntry; / / Module-level symbol table structure definition typedef struct _ModuleSymbolTable { U32 module_id; / / Unique identifier for a dynamic module U32 entry_count; / / Total number of symbol table entries contained in the current module SymbolEntry entries; / / Pointer to the array of specific symbol table entries } ModuleSymbolTable; In the code above, U32 is defined as a 32-bit unsigned integer. ModuleSymbolTable represents a module-level symbol table collection used to uniformly manage the module's external interface pointers.

[0066] S503 executes atomic-level pointer redirection logic. In an RTOS environment, the system uses a suspended task scheduler or a global interrupt-disabled mechanism to ensure that updating symbol pointers is not interrupted by other task processes. Subsequently, the system traverses the global symbol table maintained by the system's main control layer, updating function pointers from pointing to the old module's physical address in batches or individually to pointing to the corresponding new module's physical address in the shadow symbol table. After overwriting the address data, the system resumes interrupts or restarts task scheduling. From this point onward, new business calls generated by the system will be directly routed to the executable code of the new version module through the global symbol table, thus achieving seamless integration.

[0067] The specific implementation code for this redirection process is as follows: U8 LVM_RedirectSymbols(ModuleSymbolTable p_st_globalTable,ModuleSymbolTable p_st_newTable) { U32 i; U32 j; / / Suspend the underlying task scheduler or disable global interrupts to ensure the atomicity of the replacement operation. LVM_DisableTaskScheduling(); for (i = 0; i<p_st_newTable-> entry_count; i++) { for (j = 0; j<p_st_globalTable-> entry_count; j++) { if (p_st_globalTable->entries[j].symbol_hash == p_st_newTable->entries[i].symbol_hash) { / / Redirect the execution pointer in the global symbol table to the physical address of the new module. p_st_globalTable->entries[j].func_ptr = p_st_newTable->entries[i].func_ptr; break } } } / / Resume task scheduling or enable global interrupts LVM_EnableTaskScheduling(); return 1; / / Returning 1 indicates that the redirection operation was executed successfully. } In the code, LVM_DisableTaskScheduling and LVM_EnableTaskScheduling are the scheduling control interfaces adapted to the underlying RTOS of the system. U8 represents an 8-bit unsigned integer, which is used here as a status return flag.

[0068] S504 performs health checks and status monitoring. After redirection, the system triggers the new module's entry function, LVM_main, for business initialization. Simultaneously, the system creates a monitoring timer independent of the application module by calling API_CreateTimer, monitoring the new module's running status within a preset observation window. Monitored parameters include whether the module experiences memory access violations, whether a hardware watchdog reset is triggered, and whether the return values ​​of critical application APIs are within reasonable ranges.

[0069] S505 triggers a high-availability rollback mechanism or resource release command. Within the observation window, if the system detects a hardware interrupt (such as a bus error or hard error), or if the monitoring timer times out and no active heartbeat feedback is received from the new module's API_SetDateTime call, the system determines that the new module loading has failed and enters an abnormal state. At this point, the system immediately performs a rollback operation: it calls the scheduling control interface again to suspend the system, reverses the function pointers in the global symbol table and overwrites the physical addresses reserved for the old module, then calls API_Free to release the memory space allocated to the new module, and calls LVM_reset to restore the system's business flow to its state before the update. If the new module runs normally within the observation window and the timer completes normally and triggers a callback, the system determines that the dynamic update was successful. At this point, the resource cleanup process begins. The system actively calls the old module's LVM_exit function to perform connection disconnection and temporary variable cleanup logic, and finally releases the original memory space occupied by the old module, completing the dynamic loading and replacement of the entire module.

[0070] The aforementioned mechanism for monitoring and restoring addresses in abnormal states is summarized in the functional descriptions, such as the claims, as an abnormal recovery unit or a rollback control module. In actual lower-level embodiments, this functional concept is equivalent to: temporarily storing the old module entity in a memory reservation area, and coordinating read, write, and overwrite operations on the `func_ptr` variable in the global symbol table, blocking addressing to the new physical address and restoring calls to the old physical address when an abnormality is detected. This technique enables the device to achieve application-level fault tolerance and self-healing capabilities without performing a complete system reset and restart.

[0071] See attached document Figure 2 In resource-constrained environments such as RTOS-based wearable products, repeated allocation and release of memory space can easily lead to memory fragmentation or dangling pointer issues. To maximize the saving of RAM and ROM resources by enabling application modules to be loaded on demand and unloaded after use, this embodiment provides a safe unloading mechanism based on forced resource reclamation and state isolation. This mechanism cuts off the module's occupation of underlying hardware and memory through unified scheduling at the system level.

[0072] S601, Perform application-level state cleanup. Upon receiving a module unload instruction, the dynamic loader obtains the control handle of the corresponding module and locates the pre-registered exit entry point within the module. Specifically, the loader calls the LVM_exit function implemented within the module. By calling this function, the application module is instructed to close file system handles opened during its runtime (e.g., closing an S32 type file handle obtained by API_FOpen via API_FClose) and release the business heap memory allocated using API_Malloc within the application logic, completing application-level data persistence and routine cleanup.

[0073] S602 performs system-level resource unbinding and forced reclamation. Considering the possibility of abnormal application exits in an RTOS environment, the system manager maintains a global resource allocation mapping table. When a module enters the unloading process, the system manager traverses this mapping table based on the module ID, forcibly blocking all asynchronous events and interrupt callbacks registered by the module with the RTOS underlying layer. Specifically, this involves setting the function pointers of the keyboard listener callback KEYBOARD_CALLBACK and the touchscreen listener callback PEN_CALLBACK to null to prevent pointers from flying around when key or touch events are triggered after unloading. Simultaneously, API_CloseAllTimer is called to destroy all active timers belonging to the module; API_AudioStopData or API_AudioStopFile is called to forcibly cut off the occupation of audio hardware paths; and API_SocketClose is called to disconnect any TCP / UDP network connections left by the module.

[0074] S603, Unregister Global Symbol Mapping. The loader operates on the global symbol hash table, removing all function and variable symbol records exported by the module during the loading phase. This step disconnects the function call association between the main system and other parallel-running modules and the module to be unloaded. For the deletion of hash table key-value pairs and the reorganization of linked lists of conflicting nodes, those skilled in the art can perform conventional memory pointer unlinking processing based on the chosen hash algorithm. The data structure maintenance methods are well-known in the field and will not be elaborated upon here.

[0075] S604, release physical memory space. The loader, based on the allRAMSize (the sum of code and data space) recorded when parsing the module header (FileHeader) and the starting address of the allocation, calls the system memory release interface API_Free. This operation completely returns the executable memory area containing the module's code segment (.text), read-only data segment (.rodata), and BSS segment allocated to static variables to the RTOS memory pool.

[0076] To further disclose the specific implementation of the lower-level features of the above functional overview, the following is the C language code implementation of the relevant control structure and unloading logic: / / Global symbol table node deregistration interface declaration extern void unregister_symbols(LVM_Context ctx); / / Implementation of the core unload function void unload_module(void handle) { LVM_Context ctx = (LVM_Context handle; U8 i; if (ctx == NULL) { return; } / / Perform application-side cleanup by calling the module's own LVM_exit. if (ctx->lvm_exit) { ctx->lvm_exit(); } / / Force system-level resource unbinding: Precisely destroy the dedicated handles belonging to this module. for (i = 0; i <ctx->timer_count; i++) { if (ctx->active_timers[i] != 0) { API_CloseTimer(ctx->active_timers[i]); } } for (i = 0; i<5; i++) { if (ctx->active_files[i]>0) { API_FClose(ctx->active_files[i]); } } for (i = 0; i<3; i++) { if (ctx->active_sockets[i]>0) { API_SocketClose(ctx->active_sockets[i]); } } / / Block foreground applications from accessing public peripherals and multimedia channels. API_SetKeyDownEvent(NULL); API_SetKeyUpEvent(NULL); API_SetPenDownEvent(NULL); API_SetPenUpEvent(NULL); API_AudioStopData(); API_AudioStopFile(); / / Unregister the exported symbols of this module from the global symbol table. unregister_symbols(ctx); / / Release the physical memory space occupied by the module if (ctx->code_segment) { API_Free(ctx->code_segment); ctx->code_segment = NULL; } / / Release the managed memory occupied by the context control block itself API_Free(ctx); } Under the above logical architecture, the unloading process restores the storage space that previously held the binary application image to a free state, allowing new modules to seamlessly reuse this physical memory. This design ensures that even under extremely limited conditions with only a few hundred KB of total RAM, the system can smoothly execute the cyclic loading and exiting of multiple applications, avoiding memory accumulation caused by traditional static compilation methods. Simultaneously, the forced resource unbinding mechanism effectively removes residual references between application modules and underlying drivers, preventing RTOS crashes or kernel failures caused by wild pointer callbacks.

[0077] See attached document Figure 1 The electronic device can be a wearable product based on a real-time operating system (RTOS), an IoT node, or other resource-constrained embedded device. The electronic device includes at least one processor and memory communicatively connected to the processor. The processor can be a microcontroller unit (MCU) or an embedded microprocessor with position-independent code (PIC) execution capabilities.

[0078] The memory is used to store computer program instructions and data generated during system operation. In this embodiment, the memory includes, but is not limited to, built-in or external flash memory, read-only memory (ROM), and random access memory (RAM). Due to the physical space and hardware limitations of the RTOS device, the memory contains the custom loader program code of this invention and a dedicated global hash table storage area. Simultaneously, the memory stores a pure binary image file (i.e., an LVM file) compiled from C language, which replaces traditional static executable files or standard dynamic link libraries (such as .so files in environments lacking libdl support).

[0079] When the processor executes computer program instructions stored in memory, it performs dynamic loading and unloading. Specifically, the processor implements the following processing steps by executing code: The S701 calls the file system interface to read the target module file into the RAM cache. The processor completes the data reading by calling low-level interfaces such as API_FOpen and API_FRead.

[0080] S702 verifies the module header structure of the data block in the cache. The processor parses the read data block header and extracts the magic value and version number from the corresponding module header structure (module_header_t or FileHeader). If the magic value matches the preset checksum (e.g., 0x4D4F4458), the file is deemed valid, and the process proceeds to the subsequent loading stage.

[0081] S703 allocates an executable memory region and loads the code. Based on the overall space parameters (allRAMSize) recorded in the module header structure, the processor allocates the corresponding physical memory block in RAM. This memory allocation involves more than just regular data space requests; the processor also needs to operate the underlying hardware's Memory Protection Unit (MPU) or Memory Management Unit (MMU) to set the access attributes of the physical memory block to a readable, writable, and executable state, ensuring that position-independent code can be legally executed. Subsequently, the processor skips the module header structure and copies the code segment and read-only data segment from the module file, with a length corresponding to the actual executable image data size (imageSize), into this physical memory region.

[0082] S704 performs symbol table resolution and global registration. The processor reads the custom symbol export table attached to the module file, extracting the entry offsets of each declared function and the relative addresses of variables. The processor calculates the hash value of the symbol name string, adds the physical base address of the allocated memory block to the extracted relative address to obtain the absolute execution address, then binds this absolute address with the symbol name hash value and inserts it into the global hash table maintained by the system. Through the above addressing and registration operations, the main control system can dynamically obtain the initialization function pointer of the external module (such as plugin_init_fn), thereby launching the external application.

[0083] The S705 listens for module unload commands and releases resources. When it receives an application exit or reset command (such as calling LVM_exit or LVM_reset), the processor unregisters all symbol nodes associated with the module from the global hash table and calls the memory management interface (such as API_Free) to release the pre-allocated executable physical memory block, restoring the system RAM space.

[0084] For the specific register settings of the MPU in the underlying hardware, the read control of the underlying cluster chain of the file system, and the open addressing or chaining method for hash table node collisions, those skilled in the art can carry out targeted development according to the specific chip model and system architecture selected. The underlying logic is a well-known technology in this field and will not be elaborated here.

[0085] This invention also provides a computer-readable storage medium storing computer programs and application module data thereon. The computer-readable storage medium can be a non-volatile storage medium, such as a Universal Serial Bus flash drive, a portable solid-state drive, a read-only memory, a magnetic disk, or an optical disk, or it can be a volatile storage medium, such as static random access memory (SRAM) or dynamic random access memory (DRAM).

[0086] When the computer program is executed by the processor of the aforementioned electronic device, it enables the processor to implement a dynamic loading mechanism based on position-independent code and symbol table registration. Furthermore, the computer-readable storage medium independently stores multiple LVM format dynamic module files compiled in C language. When the processor reads the LVM files in this medium, it can rely on detailed parameter structures contained in the file header, such as filename length (fileNameLength), Chinese name (appNameCh), icon size (iconSize), and offset address (addr) specified at compile time, to construct a module application market independent of the operating system's native dynamic linker. By storing mutually isolated master loader code and multiple dynamic LVM files, this storage medium allows the terminal device to add or remove applications and iterate on functions by sending and overwriting partial LVM files through an external interface without rewriting the entire ROM firmware layer.

[0087] To enable those skilled in the art to more clearly understand the collaborative working principle and application effect of the above-mentioned mechanisms of the present invention in actual resource-constrained devices, the dynamic loading and zero-downtime hot update process of the present invention will be further demonstrated and explained below in conjunction with a specific hardware product application scenario: Specific application example: Zero-downtime hot update of the heart rate algorithm module in a smartwatch.

[0088] This embodiment uses a smartwatch with extremely limited main control RAM resources (e.g., only 512KB of main control RAM, running the FreeRTOS operating system) as an example. This watch comes pre-installed with a V1.0 heart rate monitoring module, which, as a dynamic LVM file compiled according to the specifications of this invention, is loaded into the watch's physical memory. The entire application and update process is as follows: When the V1.0 module is running, it triggers a timer once per second through the system-provided API_CreateTimer interface to collect optical sensor data, calculate the heart rate value, and then refreshes and displays the heart rate data on the dial through a callback UI interface via the system's global hash table.

[0089] The watch's backend receives the V2.0 heart rate monitoring module image file with optimized motion artifact algorithm via Bluetooth or network and triggers the upgrade command.

[0090] The dynamic loading manager calls the memory allocation interface in the background, allocating 20KB of independent physical memory space for the V2.0 module. It then copies the V2.0 file into this memory block and performs address relocation of the position-independent code based on the newly allocated memory base address. During this parallel processing, the original V1.0 module continues to perform its heart rate acquisition function normally, without any noticeable impact on the user's end.

[0091] The loader parses the exported symbol table of the V2.0 module and constructs the corresponding shadow symbol table in memory. Then, the system calls `LVM_DisableTaskScheduling()` to suspend the underlying FreeRTOS task scheduler. Within the extremely short time (microseconds) the scheduler is suspended, the manager traverses the system-maintained global hash table, forcibly overwriting the pointer values ​​of rate-related interfaces (such as `HeartRate_Process`) from memory addresses pointing to V1.0 to the absolute physical addresses of the corresponding V2.0 modules in the shadow symbol table. After the overwriting is complete, the task scheduler is immediately resumed.

[0092] After the system resumes scheduling, the next heart rate acquisition request from the watch's UI layer will be directly routed by the global hash table to the physical address of the new version V2.0 module for execution. Simultaneously, the system starts a monitoring timer. If V2.0 runs normally within the observation window and no hardware fault is triggered, the system determines the update was successful and calls the unload logic `unload_module()`, triggering the LVM_exit cleanup function of the V1.0 module, closing the old version's dedicated timer, and releasing the physical memory occupied by V1.0.

[0093] Through the above process, under the dual constraints of hardware computing power and memory, the smartwatch completed the underlying replacement of the core algorithm without any lag or data gap in the heart rate waveform display, achieving a truly zero-downtime hot update.

[0094] Experimental verification and effect analysis: Memory resource consumption effect analysis (combined with) Figure 3 ):like Figure 3 As shown, the vertical axis represents the peak RAM usage of the system (unit: KB), and the horizontal axis corresponds to three different compilation and loading schemes.

[0095] Static compilation (traditional) approach: Requires the operating system and all applications to be pre-packaged together for execution. Figure 3 The data shows that its resident RAM peak is as high as 210KB, which significantly squeezes the remaining available memory of the system.

[0096] The standard dlopen (regular dynamic) approach: When loading dynamic libraries, the large standard system-level linker, such as ld-linux.so, needs to be loaded into memory for symbol resolution, leading to a sharp increase in memory consumption. Figure 3 The data shows that its peak RAM usage reached 240KB, which poses a risk of memory overflow (OOM) crash for a platform with only 256KB of total RAM.

[0097] LVM dynamic loading (this invention) solution: Figure 3 The data clearly shows that the peak RAM usage of this invention is only 90KB. This is because this invention does not rely on the complex linker at the operating system level, but uses a lightweight dynamic load manager and a use-and-unload strategy, keeping the system's basic resident RAM at a low level (approximately 65KB). Even with the 20KB of memory allocated during a single dynamic application load, the peak is stably controlled within 90KB. This comparison intuitively confirms the extremely excellent memory utilization of this invention.

[0098] Business continuity and downtime effect analysis (combined) Figure 4 and Figure 5 ): Figure 4 and Figure 5 This visually illustrates the step waveform of service availability over time during system updates. The vertical axis defines the two states: service availability and unavailability (interruption), while the horizontal axis represents the relative unit of time.

[0099] Traditional OTA firmware upgrade service interruption status ( Figure 4 ):like Figure 4 As shown, when the upgrade is triggered, the waveform drops from a service-available state to an unavailable (interrupted) state instantly, and remains unavailable for an extremely long time window. Based on the aforementioned embodiments, it is known that the device is currently executing the underlying Flash erase / write and system restart logic, and the interruption time at the bottom of the waveform corresponds to an average of 12.5 seconds in actual measurements. During this window of tens of seconds, the watch's heart rate waveform display will be frozen, stuttered, or completely discontinuous.

[0100] Service availability of the zero-downtime update solution of this invention ( Figure 5 ):like Figure 5 As shown, when the same upgrade operation is triggered, the service availability curve remains almost horizontally high. The figure shows only one extremely small, almost invisible, downward spike, representing the instant the system suspends the scheduler and performs atomic pointer redirection. Combined with actual measurement data from the implementation example, thanks to the background memory pre-allocation and the second-level switching mechanism of the shadow symbol table, the actual interruption time of this downward spike is only 4.5 microseconds (i.e., <5μs as indicated in the figure).

[0101] Conclusion: Through the comparison of the above-mentioned data combining text and images, it can be confirmed that the CPU time preemption during the upgrade process of this invention is at the microsecond level. For UI interfaces that refresh at the millisecond or second level (such as heart rate waveform display), users cannot perceive any lag at all. This invention successfully achieves truly zero-downtime, seamless hot updates in an environment with low RAM consumption (90KB), solving the technical pain point of existing technologies that cannot balance low memory and high availability in resource-constrained devices.

Claims

1. A dynamic loading method based on the C language, characterized in that, Includes the following steps: Receive the startup command for the dynamic module, read the binary image file corresponding to the dynamic module into the memory buffer, and parse the custom module header structure in the header of the binary image file for legality verification; If the legality verification passes, according to the memory space requirement recorded in the custom module header structure, a contiguous physical memory block is allocated, the access permissions of the physical memory block are set to readable, writable and executable, and the code segment and data segment of the binary image file are copied to the physical memory block; Based on the starting physical address of the physical memory block and the relocation information table at the end of the binary image file, the absolute execution address of the instructions that need to be relocated in the code segment is corrected. The symbol export table inside the binary image file is parsed, and the function interface names extracted from the symbol export table are bound to their corresponding actual absolute physical addresses and registered in the global symbol table maintained by the host system. The physical address of the system application programming interface exported by the host system is found in the global symbol table, the physical address is filled back into the external symbol reference table of the dynamic module, and the address of the initialization function of the dynamic module is obtained based on the global symbol table for execution.

2. The dynamic loading method based on C language according to claim 1, characterized in that, The steps for validating the legality of the custom module header structure parsing the header of the binary image file specifically include: Extract the type identifier magic number, hardware platform identifier, version number, security verification algorithm type, and corresponding security verification value from the custom module header structure; Compare whether the type identifier magic number, the hardware platform identifier, and the version number match the current host system's operating environment; If a match is found, the checksum of the executed image data in the binary image file is calculated based on the security verification algorithm type, and the checksum is compared with the security verification value for consistency. If the consistency comparison passes, the legality verification is deemed to have passed.

3. The dynamic loading method based on C language according to claim 1, characterized in that, The steps for correcting the absolute execution address of instructions that need to be relocated in the code segment specifically include: Calculate the offset difference between the starting physical address of the physical memory block and the base offset address preset by the dynamic module during the compilation phase; Iterate through all the address entries that need to be corrected recorded in the relocation information table; The offset difference is added to the original address value of the corresponding address entry to be corrected in the code segment to obtain the established actual absolute physical address.

4. The dynamic loading method based on C language according to claim 1, characterized in that, After the execution call, the method further includes lifecycle management of the dynamic module based on the module context control block, specifically including: An independent module context control block is created in the main memory for the dynamic module to record the current running state of the dynamic module, the start pointers of the code segment and data segment, and the handles of the requested system resources; Extract the standard control interface function pointers exported by the dynamic module and mount them to the module context control block. The standard control interface function pointers include at least the main entry function pointer for application startup, the function pointers for pausing and resuming operation when the system focus is switched, the function pointers for resetting the state when the operating environment is abnormal, and the function pointers for cleaning up when the application terminates abnormally.

5. The dynamic loading method based on C language according to claim 4, characterized in that, The step of performing lifecycle management of the dynamic module based on the module context control block further includes: When the host system detects a high-priority system event, it calls the function pointer for pausing and resuming the operation mounted in the module context control block to switch the current running state of the dynamic module recorded in the module context control block from running to paused. Select timer handles from the system resource handles recorded in the module context control block, and suspend the underlying timer associated with the timer handle; The peripheral input callback events registered by the dynamic module with the host system are blocked.

6. The dynamic loading method based on C language according to claim 1, characterized in that, The method also includes the step of performing zero-downtime updates to older versions of dynamic modules that are already in operation: Allocate an independent executable physical memory space for the received new version dynamic module, and copy the code segment and read-only data segment of the new version dynamic module to the independent executable physical memory space; Calculate the actual absolute physical address of each exported function in the new version of the dynamic module, and establish a shadow symbol table corresponding to the new version of the dynamic module in memory; Suspend the system's underlying task scheduler or disable global interrupts. Traverse the global symbol table maintained by the host system, and atomically replace the physical addresses of the old version dynamic modules in the global symbol table with the physical addresses of the new version dynamic modules in the shadow symbol table; Enable the system global interrupt or resume the task scheduler so that subsequent business calls are directly routed to the new version dynamic module through the global symbol table.

7. The dynamic loading method based on C language according to claim 6, characterized in that, After enabling the system global interrupt or resuming the task scheduler, the method further includes executing a high-availability rollback mechanism: Create a monitoring timer independent of the new version dynamic module to monitor the running status of the new version dynamic module within a preset observation time window; If the underlying system detects a hardware abnormal interruption within the preset observation time window, or if the monitoring timer times out and no active heartbeat feedback is received from the new version dynamic module, then the loading of the new version dynamic module is determined to have failed. The task scheduler is suspended again, and the function pointers in the global symbol table are overwritten in reverse to the physical addresses reserved by the old version of the dynamic module. This is used to restore the system business flow to the state before the update, and the system memory release interface is called to release the independent executable physical memory space.

8. The dynamic loading method based on C language according to claim 4, characterized in that, The step of managing the lifecycle of the dynamic module based on the module context control block further includes memory resource reclamation and safe unloading operations performed when an unloading instruction for the dynamic module is received, specifically including: The cleanup function pointer mounted in the module context control block is invoked to trigger the cleanup of business data within the dynamic module; By using the system resource handle recorded in the module context control block, the active timer belonging to the dynamic module is forcibly destroyed, and the asynchronous event callbacks registered by the dynamic module with the host system are blocked. Unregister the registration record that binds the function interface name to the corresponding actual absolute physical address from the global symbol table; Call the system memory release interface to release the physical memory block containing the code segment and the data segment.

9. The dynamic loading method based on C language according to claim 1, characterized in that, The steps of parsing the symbol export table inside the binary image file, binding the extracted function interface names with their corresponding actual absolute physical addresses, and registering them in the global symbol table maintained by the host system specifically include: Parse the symbol export table inside the binary image file; Calculate the hash value of the extracted function interface name to obtain the corresponding symbol name hash value; The symbol name hash value is mapped and bound to the corresponding actual absolute physical address to construct the corresponding symbol node; Insert the symbol node into the global symbol table configured with a hash data structure; When a hash collision occurs when inserting the symbol node into the global symbol table, the storage address of the symbol node is reallocated using either chaining or open addressing.

10. A dynamic loading method based on C language according to claim 4, characterized in that, The step of managing the lifecycle of the dynamic module based on the module context control block, the method further includes a hot restart operation performed when an abnormality in the runtime environment is detected, specifically including: Invoke the state reset function pointer mounted in the module context control block; The state reset function pointer guides the dynamic module to clear its internal cache data and resets the dynamic module to the initial running stage based on the completion of the main entry function pointer; Throughout the hot reboot operation, the physical memory block containing the code segment and the data segment is maintained in its occupied state, and the dynamic module is restored to operation without rereading the binary image file.