RISC-V-based executable engineering dynamic loading and debugging method

By generating the main project and executable project on the RISC-V processor, adding dynamic calls and running interface functions to the main project and establishing function pointer tables in the executable project, the inconvenience of program loading and debugging caused by the fixed function interface call method between RISC-V processor modules is solved, and flexible and efficient program dynamic loading and debugging is achieved, reducing the risk of source code leakage.

CN120066614AActive Publication Date: 2025-05-30ZHEJIANG DALI TECH
View PDF 8 Cites 0 Cited by

Patent Information

Application Number
CN202510217224.6
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-02-26
Publication Date
2025-05-30
Estimated Expiration
2045-02-26

AI Technical Summary

Technical Problem

The calling method of the existing RISC-V processor modules is relatively fixed, which leads to inconvenience in program loading and debugging, especially on CPUs without MMU, the .so dynamic library or directly runs elf format programs, and the loading and debugging of static libraries poses complexity and confidentiality risks.

Method used

By generating the main project and independent executable project based on the original project containing the static library on the RISC-V processor, dynamically call the running interface function in the main project, so that the main project can load the executable file generated by the executable project; establish a function pointer table in the executable project to realize the call to the main project function, and create an adaptive processing function during the debugging process to identify the current environment and control the output of debugging information.

Benefits of technology

It realizes the flexibility and efficiency of dynamic loading and debugging on RISC-V processors, reduces the risk of program space occupied and executable engineering source code leakage, provides a flexible and efficient way to dynamically load programs, and automatically recognizes the environment during debugging to control output.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120066614A_ABST
    Figure CN120066614A_ABST
Patent Text Reader

Abstract

The invention relates to an RISC-V-based executable project dynamic loading and debugging method. A main project and an independent executable project are generated based on an original project containing a static library; adding a dynamic call operation interface function compiled by an assembly language in the main project, so that the main project can load an executable file generated by the executable project; establishing a function pointer table for calling a main engineering function in the executable engineering to realize calling of the main engineering function; respectively carrying out dynamic debugging on the main project and the independent executable project; in a debugging project, a self-adaptive processing function for debugging printing information is created, so that a program can automatically identify a current environment, if the program is in a debugging environment, debugging information is normally output, and if the program is in a non-debugging environment, the program can skip an output debugging information interrupt instruction to continue running. A flexible inter-module function calling mode based on the RISC-V processor is realized, and an environment self-adaptive processing function for debugging printing information is realized.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the technical field of RISC-V processors, and in particular, to an executable project dynamic loading and debugging method based on RISC-V. Background Art

[0002] Due to the lack of memory address translation and protection mechanisms in CPUs without MMU, it is usually impossible to load.so dynamic libraries or programs in elf format based on the Linux environment. The.so dynamic library is a library file that is dynamically loaded and linked during program execution. It allows programs to share code and data during execution, reducing memory occupancy and program size. However, the loading and management of dynamic libraries rely on the memory mapping and protection functions provided by MMU, and CPUs without MMU cannot meet this requirement, so they cannot load.so dynamic libraries. Similarly, although programs in elf format contain rich execution information, due to their complex structure and characteristics that depend on MMU, they usually cannot be directly run on CPUs without MMU.

[0003] For the loading of static libraries, the linker will directly copy the code in the library into the final executable file. When releasing a static library program, the entire software needs to be compiled and packaged to generate the target code, and it is impossible to release the static library separately, which greatly reduces the release efficiency and flexibility.

[0004] When debugging each static library, the source code of the entire project must be carried, which not only increases the complexity of debugging but also reduces the confidentiality of the source code to a certain extent. Once the project source code is leaked, the code details of all modules will be exposed. Summary of the Invention

[0005] In view of the above analysis, embodiments of the present invention aim to provide an executable project dynamic loading and debugging method based on RISC-V to solve the problem of inconvenient program loading and debugging caused by the relatively fixed call method of function interfaces between existing RISC-V processor modules.

[0006] Embodiments of the present invention provide an executable project dynamic loading and debugging method based on RISC-V, which generates a main project and an independent executable project based on the original project containing static libraries; adds a dynamic call running interface function written in assembly language in the main project to enable the main project to load the executable file generated by the executable project;

[0007] Establish a function pointer table for calling functions in the main project in the executable project to achieve the call of functions in the main project;

[0008] Perform dynamic debugging on the main project and the independent executable project respectively; during the debugging process, create an adaptive processing function for debugging print information, so that the program can automatically identify the current environment. If it is in the debugging environment, it will normally output debugging information. If it is in a non-debugging environment, the program can skip the output debugging information interruption instruction and continue to run.

[0009] Furthermore, establish a function pointer table for calling the main project functions in the executable project. When the main project calls the executable project code through the dynamic call operation interface function, the executable project passes the function pointer table to the main project. After receiving the function pointer table, the main project assigns values to the actual function addresses according to the function names in the function pointer table; the functions in the executable project obtain the actual addresses, and the call to the main project functions can be realized.

[0010] Furthermore, the dynamic debugging of the executable project includes: after opening the executable project with the IDE software, enter the debugging mode, change the file name after the load_image instruction in the python script to the main program name of the executable project, and at the same time add an instruction to define the main program entry address of the executable project in the python script, and execute the modified python script.

[0011] Furthermore, creating an adaptive processing function for debugging print information includes: adding an exception interruption function, which is called when the debugging print information interruption is triggered by the ebreak instruction; creating an initialization function for the output function bsp_printfx(), and the initialization function is used to check the current code running environment.

[0012] Furthermore, the initialization function is used to set the exception vector mtvec to the address of the exception interruption function, and at the same time save the old vector value. If it is currently in the debugging mode, enter the output function bsp_printfx(). If it is in the non-debugging mode and the CPU has an exception interruption, enter the exception interruption function. In the exception interruption function, set the code of the next instruction after the forced entry into the interruption to avoid the program being unable to continue running due to the interruption instruction.

[0013] Furthermore, the generation process of the executable project includes: modifying the link configuration file of the executable project to specify the executable project code address; modifying the code of the executable project environment initialization process to make it capable of returning to the main project, and isolating the values stored in the general registers of the executable project and the main project.

[0014] Furthermore, the generation process of the main project includes: removing the static library files from the original project containing the static library, and modifying the way of calling the static library by the original project with the static library function name to the way of dynamically calling the executable project by function pointer.

[0015] Further, the dynamic call running interface function includes: setting the ra general register to store the address for the executable project to return to the main project, the a0 general register to store the entry address of the executable project code, and the a1 general register to store the function pointer table in the executable project; saving the values stored in the general registers except x0 and a0 into a custom array, and jumping to the entry address of the executable project code through a jump instruction; after the executable project finishes execution, returning to the next instruction after the jump instruction and restoring the values stored in all the general registers and temporary registers saved in the custom array.

[0016] Further, modifying the link configuration file of the executable project to specify the executable project code address includes: modifying the executable project code address to an unoccupied space.

[0017] Further, the main project adds an interface function for initializing function pointers, including: creating a structure array, and respectively assigning the addresses of the functions in the executable project converted from the static library functions that the main project needs to call to the elements in the structure array.

[0018] Compared with the prior art, the present invention can at least achieve one of the following beneficial effects:

[0019] 1. The method for dynamically loading and debugging an executable project based on RISC-V according to the present invention generates a main project and an independent executable project based on the original project containing a static library; adding a dynamic call running interface function written in assembly language in the main project enables the main project to load the executable file generated by the executable project; reducing the program occupied space and at the same time reducing the risk of source code leakage of the executable project.

[0020] 2. The present invention realizes the call of the main project functions by establishing a function pointer table for calling the main project functions in the executable project; modifying the link configuration file of the executable project to specify the executable project code address; modifying the code of the executable project environment initialization process to enable it to return to the main project, isolating the values stored in the general registers in the executable project from those in the main project; removing the static library file from the original project containing the static library and modifying the way of calling the static library by the original project with the static library function name to the way of dynamically calling the executable project by function pointers; realizing the flexible loading of the static functions replaced by the executable project by the main project without additionally copying the functions in the executable project to the main project, and the executable project can also call the functions in the main project through function pointers, which is a flexible and efficient program dynamic loading method.

[0021] 3. During the debugging process of the present invention, an adaptive processing function for debugging print information is created, enabling the program to automatically identify the current environment. If it is in the debugging environment, normal debugging information is output. If it is in a non-debugging environment, the program can skip the output of debugging information and continue running by interrupting the instruction. This avoids the output function bsp_printfx() of the print information being turned on in the debugging mode and turned off in the release mode, and enables it to run adaptively in the two different modes.

[0022] In the present invention, the above technical solutions can also be combined with each other to achieve more preferred combined solutions. Other features and advantages of the present invention will be described in the subsequent specification. Moreover, some advantages can be made obvious from the specification or understood by implementing the present invention. The objectives and other advantages of the present invention can be realized and obtained from the content specifically pointed out in the specification and the drawings. BRIEF DESCRIPTION OF THE DRAWINGS

[0023] The drawings are only for the purpose of showing specific embodiments and are not considered as a limitation of the present invention. Throughout the drawings, the same reference signs represent the same components.

[0024] Figure 1 It is a flowchart of a method for dynamically loading and debugging an executable project based on RISC-V according to the present invention. DETAILED DESCRIPTION OF THE EMBODIMENTS

[0025] The following will specifically describe the preferred embodiments of the present invention with reference to the drawings. The drawings form a part of this application and are used together with the embodiments of the present invention to explain the principles of the present invention, rather than to limit the scope of the present invention.

[0026] A specific embodiment of the present invention discloses a method for dynamically loading and debugging an executable project based on RISC-V, as Figure 1 shown. The specific steps include S1 - S4.

[0027] S1. Generate a main project and an independent executable project based on the original project containing static libraries.

[0028] The process of generating the executable project includes: modifying the link configuration file of the executable project to specify the code address of the executable project; modifying the code of the executable project's environment initialization process to enable it to return to the main project and isolate the values stored in the general registers of the executable project from those of the main project.

[0029] Modifying the link configuration file of the executable project to specify the code address of the executable project includes: modifying the code address of the executable project to an unoccupied space.

[0030] Specifically, since the memory of the CPU is uniformly distributed, the address spaces of each module need to be pre-allocated. By modifying the defaul.ld table, it is defined as the entry address of the executable project code and the occupied space range.

[0031] The code for modifying the defaul.ld table in this embodiment includes:

[0032]

[0033] Modify the code for initializing the executable project environment to isolate the parameters of the executable project registers from the general registers of the main project, including: pushing the values of the general registers a0 and a1 onto the stack during the initialization process code of the executable project environment. After the executable project finishes execution, restore the values of a0 and a1 pushed onto the stack from the stack, and restore the space of the stack pointer SP.

[0034] Specifically, modify the start.S code of the executable project. This is a piece of code for initializing the C language environment before entering main. The original start.S code finally enters an infinite loop after executing call main, believing that the main function in the executable project has finished execution and the task of the start.S code is completed without performing any operations. After being changed to an independently running module, the start.S code not only still needs to complete the initialization of the C language environment of the executable project itself, but also needs to receive some parameters from the function pointer table called by the main function of the main project. After entering the main function of the main project, the executable project must assign the address of its own interface function to this function pointer table. At the same time, return the CPU execution right to the main program of the main project.

[0035] The modification of the start.S code includes, in sequence: protecting the three values ra, a0, and a1 passed in from the main project and pushing them into the stack space. ra is the address for returning to the main project, and a1 is the function pointer table in the main project. Before executing the call main instruction (returning to the main project), restore the values of ra, a0, and a1 from the stack space, so that the executable project can obtain the table through the parameter argv of the main function main of the main project, completing the transfer of the table from the main project to the executable project, and handing it over to the main project BIN_Init() for concretization.

[0036] The modified code of the start.S code in this embodiment includes:

[0037] Protect the three values ra, a0, and a1 passed in from the main project and push them into the stack space:

[0038] addi sp,sp,-16

[0039] sw ra,12(sp)

[0040] sw a0, 8(sp)

[0041] sw a1, 4(sp)

[0042] Restore the values of ra, a0, and a1 from the stack space:

[0043] lw a0, 8(sp)

[0044] lw a1, 4(sp)

[0045] lw ra, 12(sp)

[0046] addi sp, sp, 16

[0047] ret

[0048] The main project generation process includes: removing the static library files from the original project containing the static library, and modifying the original project from calling the static library in the name of the static library function to dynamically calling the executable project in the way of function pointers.

[0049] Specifically, the number of static libraries that the original project needs to call is equal to the number of converted independent executable projects. Each static library corresponds to an independent executable project. This can enable each static library to be developed, tested, and released independently, reducing development and maintenance costs.

[0050] In this embodiment, the original project is divided into a main project and an executable project, enabling the main project to dynamically load the executable project (multiple). Additionally, the so-called dynamic loading means that originally the static library code could only be linked with the main project during the compilation stage, but now after the main project runs, the code of the executable project can be loaded into memory, and then triggered to execute by the main project code.

[0051] Modify the code of the executable project environment initialization process to enable the executable project to have the ability to return to the main project, including: pushing the value of the ra general-purpose register onto the stack during the executable project environment initialization process code, and restoring the value of the ra general-purpose register pushed onto the stack from the stack after the executable project finishes execution, enabling the executable project to have the ability to return to the main project.

[0052] Isolate the values stored in the registers of the executable project from those of the general-purpose registers of the main project, and also include: adding an option to turn off the GP global register in the compilation conditions.

[0053] S2. Add a dynamically callable runtime interface function written in assembly language in the main project to enable the main project to load the executable file generated by the executable project.

[0054] The function of the dynamic call running interface includes: setting the address returned by the executable project to the main project in the ra general-purpose register, setting the entry address of the executable project code in the a0 general-purpose register, and storing the function pointer table in the executable project in the a1 general-purpose register; saving the values stored in the general-purpose registers except x0 and a0 to a custom array, and jumping to the entry address of the executable project code through a jump instruction; after the executable project finishes execution, returning to the next instruction after the jump instruction and restoring the values stored in all general-purpose registers and temporary registers saved to a custom array.

[0055] The main project adds an interface function for initializing function pointers, including: creating a structure array, and assigning each element in the structure array to the function address in the executable project converted from the static library functions that the main project needs to call.

[0056] Specifically, in the main project, add assembly language to write the dynamic call running interface function to set the address returned by the executable project to the main project in the ra general-purpose register, set the entry address of the executable project code in the a0 general-purpose register, and store the function pointer table in the executable project in the a1 general-purpose register. The main project also enables the executable project to obtain the function pointer table of the executable project through the argv parameter of the main function of the main project through the newly added interface function, completing the transfer of the function pointer table from the main project to the executable project.

[0057] Specifically, through step S1, the main project and one or more independent executable projects have been created; since RISC V has 32 general-purpose registers, it is necessary to ensure the isolation of the values stored in the registers in the protection mechanisms of the main project and each executable project. However, x0 is a constant zero register and does not need to be backed up. a0 is the return value of the executable project, and it is not desired to restore it to the original value of a0 in the main program of the main project when the executable project returns to the main project. Therefore, a0 does not need to be backed up. The executable project runs independently (similar to the dynamic library call method), and the main project needs to dynamically find the dynamic source of the executable project through the interface function for initializing function pointers. In RISC V, since there is no MMU, the dynamic library compiler cannot find the function programming dynamically. By modifying the defaul.ld table in this embodiment and defining it as the entry address of the executable project code, the main project can dynamically find the entry address of the executable project code, and find the function addresses of each executable project through the function pointer table passed in through the a1 register to make it execute correctly.

[0058] This function uses assembly to prevent the compiler from controlling the SP stack. The static library is changed to an independent executable project, which has an independent and complete C running environment, and all registers in the CPU need to be protected and isolated.

[0059] The dynamic call run interface function needs to be written in assembly code to manage the protection of the SP stack (the stack pointer SP is an 8-bit register whose value is the address of the stack top, i.e., it points to the stack top, and SP is an indirect register for accessing the stack). A 124-byte array is established to store 30 general-purpose registers of RISC-V (except for the RISC-V general-purpose register x0, which is a constant zero register and does not need to be backed up, and the a0 register is not backed up as the return value) and a temporary register (t0). When the main project calls the executable project, the two projects share a single SP register, so the environments of the two projects will affect each other. To avoid being affected, the t0 register is used to store the values of all general-purpose registers into the 124-byte array (at this time, a ra register is particularly important as it stores the return address of the dynamic call run interface function. At the same time, the executable project is also responsible for protecting the values of the general-purpose registers during operation. Since the code address of the executable project is uncertain during the call, the jalr long jump instruction jalr ra,0(a0) is used to execute. The dynamic call run interface function takes two parameters, one is a pointer variable a0 pointing to the code address of the executable project, and the other is a pointer variable a1 pointing to the function pointer table. After the jalr instruction is executed, the values from the 124-byte array are restored to all the corresponding general-purpose registers (at this time, ra is also restored to the address that the main project should return to after running the executable file of the executable project), and the execution power of the CPU is returned to the main project through the ret instruction.

[0060] S3. Establish a function pointer table in the executable project to call the functions of the main project, so as to realize the call of the main project functions.

[0061] Establish a function pointer table in the executable project to call the functions of the main project. When the main project calls the executable project code through the dynamic call run interface function, the executable project passes the function pointer table to the main project. After receiving the function pointer table, the main project assigns the actual function address according to the function name in the function pointer table; the functions in the executable project obtain the actual address, and the call of the main project functions can be realized.

[0062] Specifically, when the executable project needs to output the printf function, in the traditional sense, the executable project cannot be executed independently and needs to be hooked up with the main program. The printf function in the executable project can point to the main program through a function pointer.

[0063] S4. Dynamically debug the main project and the independent executable project respectively; during the debugging process, create an adaptive processing function for debugging print information, so that the program can automatically identify the current environment. If it is in a debugging environment, it will output debugging information normally. If it is in a non-debugging environment, the program can skip the output debugging information interrupt instruction and continue to run.

[0064] Performing dynamic debugging on an executable project includes: after opening the executable project with the IDE software, entering the debugging mode, changing the file name after the load_image instruction in the Python script to the main program name of the executable project, and at the same time adding an instruction to define the entry address of the main program of the executable project in the Python script, and then executing the modified Python script.

[0065] Specifically, in the Efinity RISC-V IDE software, during general debugging, debugging is performed in project mode (static libraries cannot be run and debugged alone), and the IDE software can only automatically load the elf file of this project during debugging. Therefore, the additional elf file needs to be loaded through the load_image command of the openocd port 4444 (loading the elf file of the executable project). To facilitate use, a script is written in Python.

[0066] A specific embodiment of the present invention includes:

[0067] Define the address and port of the OpenOCD Telnet server

[0068] HOST = "localhost"

[0069] PORT = 4444

[0070] Commands to be executed:

[0071] COMMAND = "load_image MTbin.elf\n"

[0072] try:

[0073] Establish a Telnet connection:

[0074] tn = telnetlib.Telnet(HOST, PORT)

[0075] Read the initial welcome message

[0076] welcome_message = tn.read_until(b"Open On-Chip Debugger")

[0077] print(welcome_message.decode('ascii'))

[0078] Send the command

[0079] tn.write(COMMAND.encode('ascii'))

[0080] Read the execution result of the command. Here, the content to be read and the timeout can be adjusted according to the actual situation. result = tn.read_until(b"downloaded", timeout = 50)

[0081] print(result.decode('ascii'))

[0082] except Exception as e:

[0083] print(f"An error occurred: {e}")

[0084] finally: ------ Ensure that the Telnet connection is closed whether an exception occurs or not

[0085] if 'tn' in locals():

[0086] tn.close()

[0087] Specifically, when debugging the main project, after opening the main program of the main project with the IDE software and entering the DEBUG mode (debugging mode), when executing the python of the elf file containing the main project name, the load_image command of the on-chip debugger openocd will be automatically added to the corresponding memory space according to the information of the elf file. Other operations remain unchanged.

[0088] When debugging the executable project ---- Specify the entry address of the main program of the executable project.

[0089] After opening the executable project with the IDE software, enter the DEBUG mode and execute the python script.

[0090] Change the file name after the function load_image to the main program name of the executable project, and at the same time add the reg pc 0x1000 command. Declare that the program counter PC value 0x1000 of the register variable is the entry address of the main program of the executable project.

[0091] The Efinity RISC-V IDE software provides an interface bsp_printf function for semihosting to print information (redefines the output function to a specific hardware interface), which can directly display the information in the terminal window of the IDE. However, this function can only be correctly executed in the debugging environment. If not in the debugging environment, that is, during actual operation in the release mode, it will cause an exception interruption, thus affecting the normal operation of the program. This function is opened in the debugging mode and closed in the release mode, which is very inconvenient. In order not to repeatedly modify the status code during debugging and release, this embodiment optimizes this function to make it capable of adapting to running in two different modes.

[0092] Semihosting uses the ebreak instruction in RISC-V to let the OpenOCD debugger capture this exception and output the information to the IDE software terminal for display.

[0093] The adaptive processing function for creating debug print information includes: adding an exception interrupt function that is called when a debug print information interrupt is triggered by the ebreak instruction; creating an initialization function for the output function bsp_printfx(), and the initialization function is used to check the current code running environment.

[0094] The initialization function is used to set the exception vector mtvec to the address of the exception interrupt function, and at the same time save the old vector value. If currently in the debug mode, enter the output function bsp_printfx(). If in the non-debug mode and a CPU exception interrupt occurs, enter the exception interrupt function. In the exception interrupt function, set the code of the next instruction after forcing an entry into the interrupt to avoid the program from being unable to continue running due to the interrupt instruction.

[0095] A specific embodiment of the adaptive processing function of the present invention includes creating an initialization function jtag_debugmode_check() before the exception interrupt functions jtag_ebreak_trap_handler() and bsp_printfx(), and the code is as follows:

[0096]

[0097]

[0098] Specifically, the jtag_ebreak_trap_handler() function is an exception interrupt function. When there is no emulator, it will be called when the CPU triggers an interrupt caused by the ebreak instruction. The jtag_debugmode_check() function is an initialization function (initialized only once) executed before using bsp_printfx(). It is used to check the current code running environment. First, set the exception vector mtvec (which needs to be restored after use). Assign mtvec to jtag_ebreak_trap_handler(), and at the same time save the old vector value. Then, trigger an interrupt by actively calling bsp_printf(). If there is an emulator in the current environment, this exception will be captured by the emulator and will not trigger a CPU exception interrupt. If not, it will trigger a CPU exception interrupt and enter the jtag_ebreak_trap_handler() function, indicating that there is no emulator present. Therefore, assign riscv_jtagmode to 0. In this function, the mret instruction is used to return to the exception trigger point, that is, bsp_print(). And csr_read(mepc)+4 is used to point the exception mepc to the next instruction. In the RISC-V architecture, mepc defaults to pointing to the triggered instruction, and then restore the previous mtvec exception interrupt value.

[0099] The new bsp_printfx() internally identifies the current environment through the riscv_jtagmode variable. If it is in the jtag mode, it will perform normal output; otherwise, it will not execute the output of debug information.

[0100] Compared with the prior art, the RISC-V-based executable engineering dynamic loading and debugging method provided in this embodiment generates a main project and an independent executable project based on the original project containing static libraries; adds a dynamic call running interface function written in assembly language to the main project, enabling the main project to load the executable file generated by the executable project; reduces the program occupied space and at the same time reduces the risk of source code leakage of the executable project. The loading method provided in this embodiment realizes the call of the main project function by establishing a function pointer table for calling the main project function in the executable project; modifies the link configuration file of the executable project to specify the code address of the executable project; modifies the code of the executable project environment initialization process to enable it to have the ability to return to the main project, so that the values stored in the general registers of the executable project and the main project are isolated from each other; removes the static library file from the original project containing static libraries, and modifies the way of calling the static library by the static library function name in the original project to the way of dynamically calling the executable project by function pointer; realizes the flexible loading of the static functions replaced by the executable project by the main project, without additionally copying the functions in the executable project to the main project, and the executable project can also call the functions in the main project through function pointers, which is a flexible and efficient program dynamic loading method. The debugging method provided in this embodiment creates an adaptive processing function for debugging print information in the debugging project, enabling the program to automatically identify the current environment. If it is in the debugging environment, it will output debugging information normally. If it is in the non-debugging environment, the program can skip the output debugging information interrupt instruction and continue to run. It avoids the output function bsp_printfx() of the print information being turned on in the debugging mode and turned off in the release mode, and has the ability to run adaptively in two different modes.

[0101] Those skilled in the art can understand that all or part of the processes for implementing the methods of the above embodiments can be completed by instructing relevant hardware through a computer program, and the program can be stored in a computer-readable storage medium. Among them, the computer-readable storage medium is a disk, an optical disc, a read-only memory or a random access memory, etc.

[0102] The above is only a preferred specific embodiment of the present invention, but the protection scope of the present invention is not limited thereto. Any changes or substitutions that can be easily thought of by those skilled in the art within the technical scope disclosed by the present invention should be covered by the protection scope of the present invention.

Claims

1. A method for dynamic loading and debugging of executable projects based on RISC-V, characterized in that: Generate a main project and an independent executable project based on the original project containing the static library; add a dynamic call run interface function written in assembly language to the main project so that the main project can load the executable file generated by the executable project; Create a function pointer table for calling the main project function in the executable project to implement the call to the main project function; Dynamically debugging the main project and the independent executable project respectively; During the debugging process, an adaptive processing function for debugging print information is created so that the program can automatically identify the current environment. If it is in a debugging environment, the debugging information is output normally. If it is in a non-debugging environment, the program can skip the interrupt instruction for outputting debugging information and continue running.

2. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: A function pointer table for calling the main project function is established in the executable project. When the main project calls the executable project code by dynamically calling the run interface function, the executable project passes the function pointer table to the main project. After the main project receives the function pointer table, it assigns the actual function address according to the function name in the function pointer table; the function pointer in the executable project obtains the actual address and can call the main project function.

3. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: Dynamic debugging of executable projects includes: opening the executable project with IDE software, entering debugging mode, changing the file name after the load_image instruction in the python script to the main program name of the executable project, adding an instruction to define the main program entry address of the executable project in the python script, and executing the modified python script.

4. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: Creating an adaptive processing function for debugging print information includes: adding an exception interrupt function, calling the exception interrupt function when the debugging print information interrupt is triggered by the ebreak instruction; creating an initialization function of the output function bsp_printfx(), and the initialization function is used to check the current code running environment.

5. The method for dynamic loading and debugging of executable projects according to claim 4, characterized in that: The initialization function is used to set the exception vector mtvec to the address of the exception interrupt function and save the old vector value. If the current mode is debug mode, the output function bsp_printfx() is entered. In non-debug mode, the CPU has an exception interrupt and enters the exception interrupt function. The code for forcing entry into the next instruction after the interrupt is set in the exception interrupt function to avoid the program being unable to continue running due to the interrupt instruction.

6. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: The executable project generation process includes: modifying the link configuration file of the executable project to specify the executable project code address; modifying the executable project environment initialization process code to enable it to have the ability to return to the main project, so that the general registers in the executable project and the values ​​stored in the general registers of the main project are isolated from each other.

7. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: The main project generation process includes: removing the static library file from the original project containing the static library, and changing the original project from calling the static library with the static library function name to dynamically calling the executable project with a function pointer.

8. The method for dynamically loading and debugging an executable project according to claim 1, characterized in that: The dynamic call operation interface function includes: setting the ra general register to store the address of the executable project returning to the main project, the a0 general register to store the executable project code entry address, and the a1 general register to store the function pointer table in the executable project; saving the values ​​stored in the general registers except x0 and a0 to a custom array, and jumping to the executable project code entry address through a jump instruction; after the executable project is executed, returning to the next instruction of the jump instruction, and restoring the values ​​stored in all general registers and temporary registers saved in a custom array.

9. The method for dynamically loading and debugging an executable project according to claim 6, characterized in that: Modifying the link configuration file of the executable project to specify the executable project code address includes: modifying the executable project code address to an unoccupied space.

10. The method for dynamically loading and debugging an executable project according to claim 7, characterized in that: The main project adds an interface function to initialize the function pointer, including: creating a structure array, and assigning each element in the structure array to the address of each function in the executable project converted from the static library function that the main project needs to call.

Citation Information

Patent Citations

  • Embedded system debugging method

    CN115344474A

  • Remote debugging implementation method of embedded operating system

    CN117472790A

  • Development loading method and device for decoupling internal modules of embedded software

    CN117707540A

  • RISC-V architecture-oriented binary program verification method and system

    CN118916886A

  • Software and hardware debugging method, system and equipment of generative RISC-V SoC and storage medium

    CN119272674A