4ms / stm32mp1-baremetal

Baremetal framework and example projects for the STM32MP15x Cortex-A7 based MPU
Other
148 stars 28 forks source link

stm32mp157 baremetal programming (on SEGGER Embedded Studio) #1

Closed Srikanth412 closed 2 years ago

Srikanth412 commented 2 years ago

Hi, I am very new to the Cortex A7 series micro processors . I can able build the simple interfaces like UART , GPIO etc . But now i am having the trouble with interrupt handling. I can able to trigger the second A7 core . I want to interact with the second A7 core's in the stm32mp157 through the software generated interrupts(means core 0 to core 1). for this how to handle the software interrupts i am unable to understand . I had tried by enabling the GICD and GICD blocks using the registers setting. I had seen the code in the git hub to control the interrupts. if i am trying the compile with Segger embedded studio ide lot errors we are facing . I need what is registers settings we need to set for the GIC and GICD both please help us in this regards.

danngreen commented 2 years ago

The GICD and GICC registers can be set up by the functions in the CMSIS library in this file: core_ca.h. If you want to see exactly what registers are being set, it's easy to see in this file. But I'd recommend using these functions rather than setting the registers yourself (less chance for error).

Generally, to setup the GICD and GICC for both cores, first you would first call GIC_Enable() from core 0 to setup the GICD (which is common to both cores) and GICC for core 0. In the multicore_a7 example project, core 0 calls SystemInit() from within startup.s. SystemInit() is in shared/system/system_ca7.c. This function sets up the FPU and MMU and other things, and calls IRQ_Initialize() which is what calls GIC_Enable().

Once the GIC is enabled by core 0, you can use core 0 to wake-up core 1. You have to follow the "magic-number" procedure that the multicore_a7 example project uses. The SecondaryCore class here makes it easy. You just need to call SecondaryCore::start() from core 0. You also have to provide a function named aux_core_main() for core 1 to start running.

For SecondaryCore::start() to work, you need to use the startup.s file in the multicore_a7 project. The section of this file that's important for core 1 is aux_core_start. This is where core 1 will branch after you call SecondaryCore::start(). Notice that aux_core_start directs core 1 to SystemInitAuxCore() (as opposed to core 0 which callsSystemInit()). The aux core version of SystemInit is almost identical to the core 0 version except that it calls GIC_CPUInterfaceInit() instead of GIC_Enable(). This function just sets up the GICC for core 1, and doesn't setup the GICD (since core 0 already set that up).

At this point, core 1 will be running whatever code you have inaux_core_main(). If you want to continue interacting with core 1 from core 0, the easiest thing is to do something like this in aux_core_main():

extern "C" void aux_core_main() {
  while (true) {
    // go to sleep until we get an interrupt (SGI from core0)
    __DSB();
    __WFI();

    auto irqnum = GIC_AcknowledgePending();
    GIC_EndInterrupt(irqnum);

    // Do something now that we're woken up
    if (irqnum == SGI0_IRQn)
      do_something();

    if (irqnum == SGI1_IRQn)
      do_something_else();
  }
}

You can have core 1 do different things, depending on which number SGI you send from core 0. You also can pass data, by having Core 0 write to a specific address in memory, and then calling the SGI. Core 1 would then read from that address. Concurrency is an issue, you have to make sure you're not writing and reading at the same time (or writing the same address from two different cores). Concurrency is a huge topic, there are many established techniques for handling these issues.

Now, my questions for you:

Are you able to compile and run the projects in examples/basic_irq and examples/nested_irq, and they run ok (correct output from the UART)? Does the multicore_a7 project compile for you? If not, can you give me the exact error you're getting?

Srikanth412 commented 2 years ago

We are trying to integrate the source file to my project in the Segger embedded studio . While adding these drivers to my project its showing lot of error. Are you did any projects with the Segger embedded studio. if yes please help us in this regards.

danngreen commented 2 years ago

What do the errors say? That would be the first thing to look at. Which driver are you adding? I would need to know exactly what you are doing (which file, and how you are adding). Can you share the errors you're getting?

Also did you set the compile flags for these files to match what's in this project's Makefiles? You need to make sure the compilation flags are correct (c++ version, include paths, etc.).

Srikanth412 commented 2 years ago

We are using the following drivers 4ms/stm32mp1-baremetal: Baremetal framework and example projects for the STM32MP15x Cortex-A7 based MPU (github.com). In that simple Irq Handling we are using . I had changed the compiler flags to CPP compile flags are matched with the Make file . The error are as follows .

  1. 'function' in namespace std.
  2. unknown type stctic inline. etc Screenshot (133) Screenshot (134) Screenshot (135)
danngreen commented 2 years ago

Looks like your compiler thinks registers D16 to D31 are not valid. I just tried creating a SEGGER Studio project and I was able to get the irq_handler.cc file to compile in a minimal project. But I did have to play with the SEGGER project settings.

extern "C" int __aeabi_atexit( 
    void *object, 
    void (*destructor)(void *), 
    void *dso_handle) 
{ 
    static_cast<void>(object); 
    static_cast<void>(destructor); 
    static_cast<void>(dso_handle); 
    return 0; 
} 

After doing all that, I was able to compile!

All in all, I would not recommend using SEGGER studio to do modern development. The included compiler is not up to date.

Can you confirm if you can compile from the command line? That is, follow the instructions in the README:

git clone https://github.com/4ms/stm32mp1-baremetal
cd stm32mp1-baremetal
cd examples
cd nested_irq
make

Does that work if you do that? If not, you need to get that working first.

Srikanth412 commented 2 years ago

Can you please send your segger project here

danngreen commented 2 years ago

Sure, it's large, but I'll send it in a minute.

Could you answer my question about getting it to compile from the command line?

Can you confirm if you can compile from the command line? That is, follow the instructions in the README:

git clone https://github.com/4ms/stm32mp1-baremetal cd stm32mp1-baremetal cd examples cd nested_irq make Does that work if you do that? If not, you need to get that working first.

danngreen commented 2 years ago

Here is the project. You will have to change the paths to your local installation of arm-none-eabi-gcc version 10.2.1, as I described in my previous comment (User Include Directories).

Do you have arm-none-eabi-gcc v 10.2.1 installed on your machine?

Executable_1.zip

Srikanth412 commented 2 years ago

Actually, we are using arm-none-eabi-gcc version 10.3.1.

Srikanth412 commented 2 years ago

Sure, it's large, but I'll send it in a minute.

Could you answer my question about getting it to compile from the command line?

Can you confirm if you can compile from the command line? That is, follow the instructions in the README: git clone https://github.com/4ms/stm32mp1-baremetal cd stm32mp1-baremetal cd examples cd nested_irq make Does that work if you do that? If not, you need to get that working first.

I downloaded from the link. we are not getting Build directory, how can we get build directory . I followed the procedure you mentioned in the read me file.

danngreen commented 2 years ago

I downloaded from the link. we are not getting Build directory, how can we get build directory .

It looks like Segger Studio creates a directory named "Output" where the files are built, instead of a directory named "build". Look inside that directory, you'll see the .elf file.

I followed the procedure you mentioned in the read me file.

Great! Since that procedure works, then that proves your machine is set up to build for the STM32MP1.

Srikanth412 commented 2 years ago

I followed the procedure you mention in the above question . cd stm32mp1-baremetal cd examples cd nested_irq make when i am trying to make its its giving an error **"arm-none-eabi-g++: error: unrecognized command line option '-std=c++20' ../shared/makefile-common.mk:96: recipe for target 'build/obj/obj/main.o' failed make: * [build/obj/obj/main.o] Error 1 "

danngreen commented 2 years ago

OK, that's a useful error message. It means your version of arm-none-eabi-g++ is too old and doesn't support C++20. ​

What does it say when you run:

arm-none-eabi-g++ --version

It should say this: (or some later version)

arm-none-eabi-g++ (GNU Arm Embedded Toolchain 10-2020-q4-major) 10.2.1 20201103 (release)

You mentioned you have version 10.3.1 installed. You may need to update your PATH variable to point to this installation. Alternatively, you could edit examples/shared/makefile-common.mk and change line 63 to be the full path to the version of gcc you want to use. Like this, for example:

ARCH    = /Full/Path/To/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-

Notice that the path must end in arm-none-eabi- because the makefile adds gcc or g++ and other suffices.

Srikanth412 commented 2 years ago

Hi, We are trying Software interrupt handling. I am able to generate the software interrupt to both the A7 core's , generation i confirmed by checking the interrupt pending status register in each core . But I have a problem. It's not going to the ISR handler for this what may be the problem. To generate the software interrupt we used the GICD_SGIR , enable register  to enable the interrupt.How to catch the Software interrupt in ISR routine. 

danngreen commented 2 years ago

Can you compile and load the muticore_a7 example project? That one illustrates using an SGI sent from core0 to core1. After that is working, you'll need to setup an ISR handler on core1, but first I would recommend getting that project working as-is.

Srikanth412 commented 2 years ago

Hi, We have Added path to 63 line in examples/shared/makefile-common but when we add the path we got an error " /home/sigma/gcc-arm-none-eabi-10.3-2021.07/arm-none-eabi--g++: Command not found" Screenshot from 2021-08-25 16-52-36

danngreen commented 2 years ago

Oh, sorry, on the line 63 there should not be a dash ("-") at the end. So it should be this:

ARCH    = /Full/Path/To/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi

not this:

ARCH    = /Full/Path/To/gcc-arm-none-eabi-10-2020-q4-major/bin/arm-none-eabi-
Srikanth412 commented 2 years ago

Hi, I have tried above 2 cases but getting the same error.

danngreen commented 2 years ago

If you're still getting that error, then that means you still don't have the correct path to the arm-none-eabi-g++ program. The path must be valid, which means that there must be an actual program at that location on your hard drive. I would suggest you watch some tutorial videos online about file paths, bash, and Makefiles. That will help you solve issues like this. They are quite simple to solve, but you do need to understand how file paths work and basic Makefile usage such as how variables work in a Makefile.

I can try to help a bit, though. But I hope you do take some time to learn about how paths and Makefiles work on a linux system.

If you look around with your file explorer, you can find the arm-none-eabi-g++ program in a few seconds.

If you take out the extra dash, your error is probably saying: /home/sigma/gcc-arm-none-eabi-10.3-2021.07/arm-none-eabi-g++: Command not found

I'm guessing the g++ program lives in a bin directory inside that gcc-arm-none-eabi-10.3-2021.07 directory. So it will be something like this: /home/sigma/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi-g++

Notice that there is a /bin in there. That's an important part of the file path. But for you, it might be different. There might more than just a /bin added. It depends on how you installed it. You need to look through the files in your arm gcc installation and find where the arm-none-eabi-g++ program actually lives.

After you find where it is, change the Makefile on line 63 like you've tried already.

In the case that the path is actually this: /home/sigma/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi-g++, then you would set line 63 to this:

ARCH = /home/sigma/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi

Notice all I did was remove the -g++ at the end. But, this is just an example. Don't just copy/paste this in. You will have to find out for yourself where the file is actually located and then set the ARCH variable to point to that path (minus the -g++).

Hope that makes sense. Good luck