3.5.2.3.3. Writing Mixed C and Assembly Code

There are multiple ways to combine C code and assembly code. One option is to write a function in assembly, and to call that function from C code like any other function. The “assembly function” option is fairly straightforward as long as all the function calling conventions and register conventions are respected.

Another option is to insert single lines of assembly language directly into the C code. Be extremely careful if using inline assembly. It can be easy to disrupt the C/C++ environment since the C compiler does not check or analyze the inline assembly code.

This section shows how to create a PRU project that combines C with an external assembly function. To see how to create a PRU project with inline assembly, reference section Writing Mixed C and Inline Assembly Code.

This section assumes that you have already read through Writing C Code and Writing Assembly Code.

Start with a blank project as per the steps in Lab 1: How to Create a PRU Project. This should be a different project than the projects created for Writing C Code and Writing Assembly Code.

The steps for Writing Mixed C and Assembly Code apply to both PRU projects that were created in CCS, and PRU projects that were created in the Linux terminal.

3.5.2.3.3.1. Write the Main Function in C

  1. Add the main.c file from <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/
  2. If the project was created in the Linux terminal, delete the existing Makefile. Copy the Makefile from <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/solution/<processor>/ to the project directory.
  3. Add the linker command file.
    • If the project was created in CCS:
      1. Remove any linker command file that was automatically added to the project.
      2. Delete the include link that points to automatically generated linker files.
      3. Add the linker command file that matches the PRU core you are using from <PSSP_PATH>/Getting_Started_Labs/linker_cmd.
    • If the project was created in the Linux terminal:
      1. Verify that the project linker command file matches the PRU core.
  4. Include header files if the project uses them. The Getting Started Labs do not use header files.
  5. Configure the PRU INTC if the PRU project uses interrupts. The Getting Started Labs do not configure the PRU INTC.
  6. Add the resource table if the project is loaded by a Linux core running Linux kernel 5.4 or earlier, or if the project is loaded by a Linux core running Linux kernel 5.10 or later AND the project uses RPMsg. The Getting Started Labs do not use RPMsg.
  7. Write the main.c firmware code:
    • Section Write the External Function in Assembly will explain how to ensure that the main.c file can find the external assembly function.
    • Look for the TODO comments in the main.c code for guidance on completing the example code. The complete solution for the main.c code can be found in <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/solution.

3.5.2.3.3.2. Write the External Function in Assembly

The PRU project’s main function, linker command file, INTC configuration (optional) and resource table (optional) are all handled in the main.c file.

  1. Add the assm_add.asm file from <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/
  2. Make sure that the following conditions are met. These conditions are required in order for the main.c file to be able to use the externally defined assembly function:
    • The .sect name must match the function declaration in main.c.
    • The section must be defined as .global
  3. write the assm_add.asm firmware code:
    • Look for the TODO comments in the assm_add.asm code for guidance on completing the example code. The complete solution for the assm_add.asm code can be found in <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/solution.

3.5.2.3.3.3. More Resources for Writing Mixed C and Assembly Code

For more information about writing mixed C and assembly code, reference the PRU Optimizing C/C++ Compiler User’s Guide, section “Interfacing C and C++ With Assembly Language”.

Ready to compile the PRU firmware? Go to Lab 3: How to Compile PRU Firmware.

3.5.2.3.4. Writing Mixed C and Inline Assembly Code

There are multiple ways to combine C code and assembly code. One option is to write a function in assembly, and to call that function from C code like any other function. The “assembly function” option is fairly straightforward as long as all the function calling conventions and register conventions are respected.

Another option is to insert single lines of assembly language directly into the C code. Be extremely careful if using inline assembly. It can be easy to disrupt the C/C++ environment since the C compiler does not check or analyze the inline assembly code.

This section shows how to create a PRU project that combines C with inline assembly code. To see how to create a PRU project with an assembly function, reference section Writing Mixed C and Assembly Code.

This section assumes that you have already read through Writing C Code and Writing Assembly Code.

Start with a blank project as per the steps in Lab 1: How to Create a PRU Project. This should be a different project than the projects created for Writing C Code and Writing Assembly Code.

The steps for Writing Mixed C and Inline Assembly Code apply to both PRU projects that were created in CCS, and PRU projects that were created in the Linux terminal.

3.5.2.3.4.1. Write the Main Function in C

  1. Add the main.c file from <PSSP_PATH>/labs/Getting_Started_Labs/c_and_inline_assembly/
  2. If the project was created in the Linux terminal, delete the existing Makefile. Copy the Makefile from <PSSP_PATH>/labs/Getting_Started_Labs/c_and_inline_assembly/solution/<processor>/ to the project directory.
  3. Add the linker command file.
    • If the project was created in CCS:
      1. Remove any linker command file that was automatically added to the project.
      2. Delete the include link that points to automatically generated linker files.
      3. Add the linker command file that matches the PRU core you are using from <PSSP_PATH>/Getting_Started_Labs/linker_cmd.
    • If the project was created in the Linux terminal:
      1. Verify that the project linker command file matches the PRU core.
  4. Include header files if the project uses them. The Getting Started Labs do not use header files.
  5. Configure the PRU INTC if the PRU project uses interrupts. The Getting Started Labs do not configure the PRU INTC.
  6. Add the resource table if the project is loaded by a Linux core running Linux kernel 5.4 or earlier, or if the project is loaded by a Linux core running Linux kernel 5.10 or later AND the project uses RPMsg. The Getting Started Labs do not use RPMsg.
  7. Write the main.c firmware code:
    • Section Write the Inline Function in Assembly will explain how to ensure that the main.c file can find the external assembly function.
    • Look for the TODO comments in your main.c code for guidance on completing the example code. The complete solution for the main.c code can be found in <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/solution.

3.5.2.3.4.2. Write the Inline Function in Assembly

  1. write the assm_add.asm firmware code:
    • Look for the TODO comments in your assm_add.asm code for guidance on completing the example code. The complete solution for the assm_add.asm code can be found in <PSSP_PATH>/labs/Getting_Started_Labs/c_and_assembly/solution.

3.5.2.3.4.3. More Resources for Writing Mixed C and Inline Assembly Code

For more information about writing mixed C and assembly code, reference the PRU Optimizing C/C++ Compiler User’s Guide, section “Interfacing C and C++ With Assembly Language”. Pay special attention to the warnings about using inline assembly code in section “Using Inline Assembly Language”.

Ready to compile the PRU firmware? Go to Lab 3: How to Compile PRU Firmware.