Using boost.asio on esp32 (lwip) - boost

I am trying to port code using boost.asio onto the esp32 (esp-idf) which in turn uses lwip, mbedtls and FreeRTOS using preemptive multitasking.
The esp-idf exposes a Linux/Posix-like interface and most stuff compiles out of the box. Lwip exposes a standard BSD socket interface including select() and blocking and non-blocking sockets etc, but it does not have poll().
So in principle I would think that everything should be there to make boost.asio happy. What I find is that boost.asio (e.g. socket_ops.ipp) contains code variants for many OSes, and it is clear to me that esp32 is not a supported platform.
My question is: What is currently the best alignment of the BOOST_ASIO_* #defines when targeting the esp32?
(I am currently drilling into this and I am modifying both boost.asio and the esp-idf to fit together, but I already made unnecessary changes, thus asking this question.)

Related

Using WinUSB within a DLL?

I'm working on a USB device that will talk to a single application. It looks like we may want to have a Windows driver that presents a nicer software interface to the application. (As opposed to having the application itself send lower-level commands to the device via WinUSB.)
Is it possible to use WinUSB from within a DLL? Choosing a driver model for developing a USB client driver doesn't address that specifically.
Are there reasons in this situation that I should instead consider writing a UMDF-based or KMDF-based driver, or a hybrid driver that calls WDM routines?
Using WinUSB is probably the right way to go. You can definitely use WinUSB within a DLL. In general, you can write a DLL that calls functions in another DLL, and there is nothing special about winusb.dll that prevents you from doing that. Also, it is already done in other projects like libusb and libusbp, which compile to a DLL that uses winusb.dll.
I would also encourage you to make your code cross-platform: don't call WinUSB directly from your DLL, but instead use a USB abstraction library such as libusb or libusbp. Even if you only want to support Windows, these libraries are lot easier to use than SetupAPI and WinUSB, so they should save development time. They will also save a lot of time if you ever want your code to work on different operating systems.
I think the only reason to write your own UMDF or KMDF driver in a situation like this is if you need advanced features of the Windows USB stack that are not supported by WinUSB. For instance, if you needed to switch your device to a different USB configuration, or do tricky stuff with power management, or allow multiple applications to use the device at once. If you just want to send some data back and forth, WinUSB is a fine choice.

Feasibility of using the same code on both embedded and Windows platforms

We have a program written in VBA that is running on Windows machines.
We have a very similar program written in ANSI C, using a Keil IDE and compiler that is running on an STR9x uP.
Our plans were to rewrite the VBA code in .NET using C#.
What is the feasibility of writing the shared code in C++ to be used on both systems? Obviously, the .NET framework would be off limits, but that isn't much of a concern. I'm wondering, specifically, about how labor intensive you think the compilation process might be.
This is kind of a theoretical question, I know, but thanks for any thoughts.
I do this a as general practice. I think a better question than "is it possible" is "how should I structure my code to be able to run on both an embedded system and also a PC".
I prefer to write the code in C and structure each file as a c++ class using static variables to make global variables private to the module. Create getter and setter functions to access the private variables. Also use function pointers which I set at initialization of the module for the methods the module need to call outside of the module.
It is also easy to refactor from the above structured c code to a class in c# or c++.
You can also use C++ directly but using it incorrectly on an embedded system can cause problems.
You will need a hardware abstraction layer if you are accessing any hardware. I separate my code into two types the first being code that has no reference to what it is running on and other code which I refer to as drivers.
I use this code for reusing modules for things like communication protocols. But more importantly I use it for testing. I like to use gtest to unit test the modules. I can also rewrite the drivers and simulate the hardware on a PC to be able to run it on the PC.
Obviously, the .NET framework would be off limits
Not necessarily true. Given sufficient ROM and RAM resources (256K/64K respectively), the .NET Micro Framework will run on your device. However that is not necessarily a good reason to use it; there are already two other commonly used portable languages available for both your embedded target and Windows: C and C++. The target resource required for both C and C++ is minimal - C/C++ runtime start-up code can be well under 1K of code, almost all available resources can be utilised by your application code rather than the run-time environment.
The trick to utilising common code on both platforms is abstraction. This will involve at least hardware abstraction and possibly OS abstraction if your target is using any sort of kernel or scheduler such as an RTOS or thread library.
I'd recommend designing your embedded target with a layer architecture, having at least a device layer and an application layer and as mentioned already, possibly a system layer that deals with IPC, synchronisation and scheduling, if used. You may have other higher layer interfaces such as networking or filesystem that would equally benefit from abstraction. Note that standard APIs such as BSD sockets or stdio already count as abstraction, so if your target uses these, you have less work to do in Windows (minor differences between BSD Sockets and Winsock may still need some work)
The application layer will have no OS or hardware dependencies other than those accessible through the device and system layers. You must then implement the device and system layers on Windows as either a simulation or remapping to services or devices available on Windows. Some RTOS's already include Windows simulators for test and development, but defining your own OS API layer that you can port between a number of native RTOS and GPOS will allow your application code to be ported to different targets for both simulation and real-time execution very quickly.
Where the platform differences are minor and localised, and may not justify an abstraction layer, then target specific conditional compilation may be appropriate. Compilers support predefined macros for architecture, OS or compiler specific code that can be used for both this localised code and to make the abstraction layer code itself common where there is significant similarity.

Winsock and other network possibilities in Windows

on windows, is there any other option when programming network communication then using Winsock? There are many socket libraries for c++, are they all just winsock based?
You can consider using boost::asio. Boost is really great and well designed. Many parts of it have come already into C++0x. You will need to statically link to a lib or dll (it is not a header only template library)
Winsock are the sockets for Windows taken over from BSD (with actually exactly the same API excepting for closesocket vs close and the initialization/termination of the subsystem). Not the Win API itself has a more modern API the WSAxxx functions. C++ is socket unaware until now that means in order to do networking you MUST use the OS API, thus Winsock. There is no other low level API.
If you are trying to monitor traffic why don't you use WinPCAP?
There are other ways to program network communication, which don't use Winsock: for example, using the network file system (shared files), or using named pipes.
Software can also bypass Winsock (which is a Windows user-mode DLL) even for TCP/IP traffic, and instead interface directly with the kernel-mode drivers.

C++ equivalent to SerializeWithLengthPrefix

I built a communication library using Protocol Buffers (protobuf-net) using Sockets (TcpListener and TcpClient) and it is working fine, but now a co-worker needs to write a library to communicate with my software using C++.
Turns out that I'm using the Serializer.NonGeneric.SerializeWithLengthPrefix and Serializer.NonGeneric.TryDeserializeWithLengthPrefix.
Are there equivalent functions in the protobuf C++ libraries? If not, anyone knows how to implement it, or have it implemented to share?
I'm not hugely familiar with the C++ API; but the length prefix itself is pretty simple if you write the data to a buffer first, especially if you use the fixed-width 32-bit encoding (rather than base-128 variable-length). See also this thread on the google-groups forum.

BSD socket compatible wrapper around winsock?

I'm attempting to port a Linux application to Windows. The application isn't too complex, using all fairly standard code, with few external dependencies. The main dependencies are libelf (which compiles fine under mingw), pthreads (there appears to be a win32 version available), and sockets. The main problem is with sockets...Windows provides WinSock, but this is not 100% compatible with BSD (Berkeley) sockets as used by all *nixes. What I'm wondering is, has anybody written a wrapper on windows that exposes a BSD socket API, but calls Winsock on the backend, to ease porting?
I would recommend using cygwin.dll . It's built for bringing over *nixes to windows including sockets, file IO, etc.
For the most part, you'll just have to make sure that WSAStartup() and WSACleanup() are called at start and end, otherwise, basic BSD sockets will translate pretty well. You could create some static global variable that gets checked for each call to the socket calls, and call WSAStartup() and WSACleanup() accordingly. As for poll() ... well, it translates quite easily to select().

Resources