stm32-hotspot / ELOOM-SDK

eLooM SDK is a collection of embedded applications based on eLooM framework and components. It demonstrates how to use the eLooM framework providing ready-to-use examples.
Other
2 stars 0 forks source link

Over Engineered #1

Closed smellit closed 3 months ago

smellit commented 10 months ago

Hi all

I try to implement the communication to a SPI device using a different protocol as your SPI chips, and is a pain. The eLooM framework is over engineered for C, why not to do it in C++?

stf12 commented 10 months ago

Hi,

indeed the framework in the past reached its evolution peak when it was ported to C++ (https://www.stf12.org/developers/FreeRTOS_EC.html), but it was a bit ahead of the times. Today the framework adopts some of the OO paradigm by design: single inheritance and multiple interfaces, virtual function (through the virtual table, code encapsulation). If in a C++ program you define a class usually in two files, MyClass.hpp and MyClass.cpp, with eLooM you define a class in three files, MyClass.h MyClass_vtbl.h and MyClass.c.

BTW, what is your blocking point?

Best regards

smellit commented 10 months ago

Hi

I would like to implement an alternative to SPIBusTaskRead and SPIBusTaskWrite to communicate over SPI with a Qorvo DWM1001 UWB location module using the external 34 Pin connector on the STWIN.box, to synchronously record vibration and location. I am an experimented Embedded SW Engineer, but the constuct is very so complex to understand and adapt, that I am stucking.

oliverisSTM commented 10 months ago

Can I assume that you are using the FreeRTOS version of eLooM framework?

Sorry in advance for all the questions, but I would like only to understand your working environment (let me call it workspace) to share with you my opinion on your issue in your context.

It should be not too much complicate to achieve your goal, but first of all it depends on what version of the framework are you using (FreeRTOS or ThreadX).

Best regards

smellit commented 10 months ago

I am using the framework from https://github.com/STMicroelectronics/fp-sns-datalog2 which is based on ThreadX.

oliverisSTM commented 10 months ago

Hi, first of all let me share a couple of UML diagram about the BUS implementation of the SensorManager component. You can find a short explanation in the section Sensors and bus in this web page

Class diagram bus_class_diagram

The functions that you want to customize (SPIBusTaskRead SPIBusTaskWrite) are the Write and Read function of the Connector object associated with the SPIBusIF used by an object (e.g. a sensor) connected to the bus . These function pointer are initialized by the SPIBusTask in its implementation of the the IBus::ConnectDevice() virtual function. So to override this virtual function my idea is to extend the SPIBusTask and implement your customization in your class. In this way when a new version of the SensorManager is released it will be easy to update your project, if you want to.

I did this exercise by generating a a subclass of SPIBusTask and would like to share with you the source code of this new class I called SPIBusTaskEx (not very original name) in this zip file:

SPIBusTaskEx.zip

In the file SPIBusTaskEx.c there are the definition of the methods that you can customize:

Note that in the sample code I commented (without removing) all the virtual functions that is possible to override in a similar way to customize the behavior of the SPIBusTask. I wanted to show the flexibility of this OO approach. It can be a bit complex at the beginning (I agree with you that a native C++ implementation will help and speedup the time to market, at least to a developer that know the language), but it also bring a lot of advantages.

I also added, as example the App.c file. It is the application file from the STM32WB5MMG-PROTEUS_DpuDemo_prj demo of the eLooM_TX-SDK I used to test the code. As you can see I just included the new SPI BUS implementation (SPIBusTaskEx.h) and I allocated the new object in the SysLoadApplicationContext() app entry point using the dynamic allocator SPIBusTaskEx_Alloc().

It is not clear to me why you want to override those functions. They don't do any communication over the SPI bus, but they only add a read/write request on the task queue.

eLooM_3_layer

As you can see in the above image the SPIBusTask is a gatekeeper of the shared resource, that is the hardware SPI. Its responsibility is to serialize the access to the bus. For example, in the DATALOG2 application many sensors read/write on the bus and the respective sensor task object don't care about the concurrent access problem. This is one of the advantage of this implementation, that also is the same for all the supported boards (another advantage).

In case you want to modify the way we write on the bus (we use DMA for performance) , then you should implement your own SPIMasterDriver.

I hope this information is useful. If you need more information, please, consider to open a new issue in the eLooM_TX-SDK if you are using the ThreadX version of the framework.

Best regards

smellit commented 10 months ago

Hi

Thank you for your explainations of the SensorManager and the SPIBusTask. The reason why I have to modify SPIBusTaskRead SPIBusTaskWrite is because they makes uses of the nRegAddr member of the spiIOMessage_t structure. The DWM1001 does not implement a register based protocol, but a protocol based on a list of commands (see: API documentation / chapter 2.3 TLV format).

In the meantime I have found a way to override the SPIBusTaskRead SPIBusTaskWrite functions and this part works as expected, but now in the sensor task I have created, when I call the write function of the BSP Component I have created, then the Sensor Task run into a queue overflow in the TaskTimerCallbackFunction, so it seems that the TaskSensorReadData does not complete, resp. the call to the SPIMasterDriver does not return and block task execution.

In the SPIMasterDriver I also have had to implement Read / Write Functions witout register access, but I am not sure how to deal with HAL_SPI_Transmit / HAL_SPI_Receive when based on DMA, do you have hint for me?

Thanks in advance

stf12 commented 10 months ago

Hi,

This time it is difficult. I can try to guess something.

What I understood is that you did:

The TaskTimerCallbackFunction is used, if I remember well, when the SensorTask is configured to work in polling mode. If the input queue of the SPIBusTask is full then:

I hope this chat can be helpful to solve your issue.

Best regards

smellit commented 10 months ago

Hi

Sorry but if this implementation should be a starting point for an own application as I read in the documentation it missed the goal. In more than 20 years of experience in ebedded systems I never met a so complicated construct for in fact a simple application. I give up and will made a bow around eLooM in the future.

Best regards.

stf12 commented 10 months ago

Hi, thanks for your feedback, I really appreciate it because every feedback is important. Even if it maybe hard to believe eLooM is the result of more than 15 years of embedded development on STM32 and a lot of feedback and open discussion like this. If may ask one more question to you, would a C++ implementation have made some difference in your case? Do you develop embedded app in C++?

I hope that you can find a solution that better fit your need in STM32 ecosystem.

Best regards

smellit commented 10 months ago

Hi

I understand the idea of making the framwork as it is, resp. modularity and hardware independant implementation of sensors control. In one of my previous jobs we have implemented a C++ Embedded Framework and made part of it also hardware indendent using abstract interface classes. This make much sense if the Framework must be used in lots of different Hardware modules, which was the case in this project. In my opinion, making the architecture too granular and intensive use of interfaces classes make the effort of understanding for a new user very laborious, more and more so in C.

In the aforementioned C++ project, a developer also had the impression that using templates for NVM data management was subtle... without taking into account the fact that debugging is almost impossible.

Do not take my feedback as a criticism of your work! You have extended knwoledge in the part of the SW you have implemented and great capacity to brake down a phisical system into SW componenents.

Best regards

stf12 commented 10 months ago

Hi,

your feedback is clear: we should have simple design for certain kind of (simple) projects, and C++ can help. These words already run in background in my mind. :)

B.T.W. I am not a kind of genius behind the DATALOG2. Yes, I designed eLooM, and yes I helped to port the SensorManager on eLooM, and I like to think that this made technically possible to have, today, the DATALOG2 running on different boards and STM32 families. But, the DATALOG2 has many other fathers, a smart team behind it.

In my opinion it is one of the most advanced eLooM based embedded application, and it is not simple. On the contrary, it is a very complex design because it is not just "read data from one sensor", it has, between the other features, to read data from all the sensors in a board and, when possible, at the maximum baud rate. It has to do it in an efficient way, that means it must be ready to go in low power when it is needed. It has also to log the data in a SD-CARD or steam it in a host PC via USB. Without loosing data. And something more. During its development we decided to separate the management of the sensors from the DATALOG2 application, so we created the SensorManager component. eLooM and the eLooM components is code that we reuse as it is (exactly the same code) in different boards and for different projects.

To give an idea of the complexity of the DATALOG2, this is eLooM:

eloom_1_fw_architecture

With eLooM we designed what is a modern embedded application for us, the basic and common behavior (system initialization, state machine, debug log, etc.). We implemented the OO concepts that we want to use in our design (Inheritance, virtual function, etc.).

But after we learned that, we wanted to do more with STM32, we want to evolve our firmware, and be able to make more complex embedded applications. For example this is FP-AI-MONMITOR2:

FP-AI-MONITOR2_V1 0 0

Do you see the difference in term of complexity? And I can tell you that the DATALOG2 is more complex than that. But both projects share the same SensorManager and, of corse the same eLoom. The same code that is used in many end products.

A simple eLooM application

When I want to start playing with a new hardware component, for example a new sensor, I don't start from the DATALOG2, I start form the HelloWorld project for my board. There I can setup the new hardware in the HelloWolrd::OnHardwareInit() and run my test code in HelloWolrd control loop. In a second step I can decide to integrate the new sensor in the SensorManager ( and may be also in the DATALOG2) with all the advantage for the community.

The STM32 ecosystem

Last thing that I want to highlight again is that eLooM is only one option to make embedded application for STM32. In the STM32 ecosystem it is possible to find many answers to different applications.

Best regards

mgrella commented 3 months ago

Closing this issue, feel free to re-open it in case you need to carry on the discussion.

BR, Marco