How to use stringstream in Xilinx SDK? - embedded

When trying to add
#include <sstream>
which is needed for stringstream, I get several errors, the following included:
expected ';' at end of input
expected '}' at end of input
macro "str" requires 2 arguments, but only 1 given
How to enable using stringstream ?

This is a bug in the Xilinx SDK.
You need to undef a macro named str.
Replace
#include <sstream>
with
#undef str
#include <sstream>
Credit:
This method was proposed by sparks333 and can be found here:
https://forums.xilinx.com/t5/Embedded-Development-Tools/Error-with-Standard-Libaries-in-Zynq/td-p/450032

I just signed up just to answer this question.
I went through this post some time ago and used the solution posed, even though I didn't like it very much. It was a mistake.
This solution can cause deadlock of the system after some time in a random way, very difficult to debug.
I propose the following solution:
create the file "compatible_sstream.h":
#pragma push_macro("str")
#undef str
#include <sstream>
#pragma pop_macro("str")
replace #include <sstream> with #include "compatible_sstream.h" in
all the other files.
wrap all calls to std::ostringstream::str in parentheses as in the example:
std::ostringstream foo()
{
// ...
}
void main()
{
// ...
std::cout << (foo().str)() << std::endl;
// ...
}
Apologies in advance if I have not followed any of the posting rules correctly.

Related

How can i use a Library for another Library ? [Arduino ESP32] [duplicate]

This question already has answers here:
C++ Global variable declaration
(5 answers)
Closed 9 months ago.
I am working on a project on Arduino ESP32 and I have a lot of Global variables (for data generation). I have decided to create a library in order to orgenise my work a little better. But I use this library into other librari's that I had to create for other usage. after compilation it I have the following error :
sketch\OX2inj_LEVEL_OX2.cpp.o:(.data.addrChipId+0x0): multiple definition of `addrChipId'
sketch\First_Useage.cpp.o:(.data.addrChipId+0x0): first defined here
sketch\OX2inj_LEVEL_OX2.cpp.o:(.bss.ChipID+0x0): multiple definition of `ChipID'
sketch\First_Useage.cpp.o:(.bss.ChipID+0x0): first defined here
here is my .ino (main) code :
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
#include "First_Useage.h"
//---------somthing
void setup()
{
Serial.begin(115200);
//---------somthing
Serial.println(ChipID.ReadStrEEPROM());
//---------somthing
}
void loop()
{
//---------somthing
}
here is my "Def_Global_Var.h" code
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
#include "Var_Str_EEPROM.h"
uint16_t addrChipId = 1;
VarStrEEPROM ChipID(addrChipId);
#endif
here is my "First_Useage.h" code
#ifndef First_Usage_H
#define First_Usage_H
void getchipid();
#endif
here is my "First_Useage.cpp" code :
#include "First_Useage.h"
#include <Arduino.h>
#include "Var_Str_EEPROM.h"
#include "Def_Global_Var.h"
void getchipid()
{
uint32_t chipId = 0;
for(int i=0; i<17; i=i+8)
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
ChipID.WriteStrEEPROM(String(chipId));
}
My understanding is that, when I use the #include "Def_Global_Var.h", the programme thinks that : "I am calling the library" and it sees that it has been called before and it does not like it.
Is it somehow correct ? and if it is(or not) correct what should I do?
EDIT : sorry I have put the wrong part of the prog. it has been corrected now
The actual cause is that the header is included into several source files, so you end up with multiple conflicting definitions of these variables in your .o files.
You shouldn't normally define global variables in header files at all; you should only declare them as extern:
#ifndef Def_Global_Var_H
#define Def_Global_Var_H
...
extern uint16_t addrChipId;
...
#endif
The second step is to define the variable in the corresponding .cpp file, this time without the extern keyword:
// Def_Global_Var.cpp
uint16_t addrChipId = 1;
Since Def_Global_Var.o gets linked only once, there should be no more conflicts.

Boost asio crashes

I have a program using cpprestsdk for http querying and websocketpp for subscribing a data stream. The program will crash immediately(it says Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)). But if I comment either of the http querying or subcribing data stream, the program won't crash.
#include <websocketpp/config/asio_client.hpp>
#include <websocketpp/client.hpp>
#include "json.hpp"
#include <iostream>
#include <ctime>
#include <iostream>
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
#include <vector>
#include <string>
using std::string;
using namespace web;
using std::cout, std::endl;
using std::vector;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
typedef websocketpp::client<websocketpp::config::asio_tls_client> client;
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
void on_stream_data(websocketpp::connection_hdl hdl, message_ptr msg) {
}
class OrderBook {
public:
void initialize() {
web::http::client::http_client_config cfg;
std::string uri = string("https://fapi.binance.com/fapi/v1/depth?symbol=btcusdt&limit=1000");
web::http::client::http_client client(U(uri), cfg);
web::http::http_request request(web::http::methods::GET);
request.headers().add("Content-Type", "application/x-www-form-urlencoded");
web::http::http_response response = client.request(request).get();
}
int start_stream() {
client c;
std::string uri = string("wss://fstream.binance.com/ws/btcusdt#depth#100ms");
try {
c.set_access_channels(websocketpp::log::alevel::all);
c.clear_access_channels(websocketpp::log::alevel::frame_payload);
c.init_asio();
c.set_message_handler(bind(on_stream_data, ::_1, ::_2));
websocketpp::lib::error_code ec;
client::connection_ptr con = c.get_connection(uri, ec);
if (ec) {
std::cout << "could not create connection because: " << ec.message() << std::endl;
return 0;
}
c.connect(con);
c.run();
} catch (websocketpp::exception const &e) {
std::cout << e.what() << std::endl;
}
}
};
int main(int argc, char *argv[]) {
OrderBook ob;
ob.initialize(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
std::this_thread::sleep_for(std::chrono::milliseconds(10000000));
ob.start_stream(); // comment either of these two lines, the program won't crash, otherwise the program will crash once start
}
When I run this program in Clion debug mode, Clion show that the crash comes from function in /opt/homebrew/Cellar/boost/1.76.0/include/boost/asio/ssl/detail/impl/engine.ipp
int engine::do_connect(void*, std::size_t)
{
return ::SSL_connect(ssl_);
}
It says Exception: EXC_BAD_ACCESS (code=1, address=0xf000000000)
What's wrong with it? is it because I run two pieces of code using boost::asio, and something shouldn't be initialized twice?
I can compile this and run it fine.
My best bet is that you might be mixing versions, particularly boost versions. A common mode of failure is caused when ODR violations lead to Undefined Behaviour.
Note that these header-only libraries depend on a number of boost libraries that are not header-only (e.g. Boost System, Thread and/or Chrono). You need to compile against the same version as the libraries you link.
If you use distribution packaged versions of any library (cpprestsdk, websocketpp or whatever json library that is you're using) then you'd be safest also using the distribution packaged version of Boost.
I'd personally simplify the situation by just using Boost (Beast for HTTP/websocket, Json for, you guessed it).
Running it all on a test Ubuntu 18.04 the OS Boost 1.65 version, the start_stream sequence triggers this informative error:
[2022-05-22 13:42:11] [fatal] Required tls_init handler not present.
could not create connection because: Connection creation attempt failed
While being UBSAN/ASAN clean. Perhaps that error helps you, once you figure out the configuration problems that made your program crash.

Static declaration of '__vector_1' follows non-static declaration

Im trying to create a program which will interrupt when I press the button. I have Atmega8 and I use Microchip studio for coding.
I checked the document about interrupts on atmega's website however I can't say I totally got it.
Here is my code:
#define F_CPU 1000000UL
#define IRQ1 INT0_vect
#define IRQ2 INT1_vect
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
void init()
{
DDRB=0b11111111;
PORTB=255;
_delay_ms(2000);
PORTB=0;
DDRD = 0b00000000;
GICR=0xc0;
MCUCR=0x08;
}
int main(void){
init();
volatile int mode = 0;
ISR(IRQ1){
_delay_ms(500);
if (mode<3)mode++; else mode = 0;
}
ISR(IRQ2){
_delay_ms(150);
}
}
Errors I get:
Imgur
I would be glad if any admin edits my question and add picture here, website doesn't let me add photo because I need at least 10 reputation to post image
Don't try to define functions inside of other functions unless you really know what you are doing. You should move the ISR definitions to the top level of the file, putting them outside of main.

AWSSDKCPP S3Client.GetObject

Having issues with GetObject. Intellisense in Visual Studio keeps evaluating the method as GetObjectW
...
unresolved external symbol "__declspec(dllimport) public: virtual class Aws::Utils::Outcome<class Aws::S3::Model::GetObjectResult,class Aws::Client::AWSError > __cdecl Aws::S3::S3Client::GetObjectW(class Aws::S3::Model::GetObjectRequest const &)const " (_imp?GetObjectW#S3Client#S3#Aws##UEBA?AV?$Outcome#VGetObjectResult#Model#S3#Aws##V?$AWSError#W4S3Errors#S3#Aws###Client#4##Utils#3#AEBVGetObjectRequest#Model#23##Z)
Here are my includes
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <aws/s3/model/DeleteObjectRequest.h>
#include <aws/s3/model/GetBucketLocationRequest.h>
#include <aws/s3/model/ListObjectsRequest.h>
All other methods work. Put works, Delete Works, Lists work. it all works. the projects are set to VS 2017. I am ONLY having problems with GetObject and as I said intellisense sees every other method except GetObject which it evaluates to GetObjectW
Client::ClientConfiguration config;
config.region = Region::US_EAST_2;
config.scheme = Http::Scheme::HTTPS;
config.connectTimeoutMs = 30000;
config.requestTimeoutMs = 30000;
S3Client s3Client(Auth::AWSCredentials(ACCESS_KEY, SECRET_KEY), config);
GetObjectRequest getObjectRequest;
getObjectRequest.WithBucket(bucket)
.WithKey(fileKey);
// //GetObject is Having issues here where it is not being found in referenced assembly it keeps being called GetObjectW...
// //It is perhaps the case there is a missing required reference for the method?
GetObjectOutcome getObjectOutcome = s3Client.GetObject(getObjectRequest);
resolved on https://github.com/aws/aws-sdk-cpp/issues/625
answer is:
must #undef GetObject before aws includes as follows:
#undef GetObject
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
This is a conflict with Windows.h

Separating Code To Be Organized

I'm building a zipper application, but it has a declaration that I want to separate it in another file (compress-file.m), but only when I separate the files I got an error when compiling with a variable, see it:
[ubuntu#eeepc:~/Desktop] make
This is gnustep-make 2.0.2. Type 'make print-gnustep-make-help' for help.
Making all for app LeafZip...
Creating LeafZip.app/....
Compiling file main.m ...
main.m: In function ‘main’:
main.m:7: error: ‘PATH_MAX’ undeclared (first use in this function)
main.m:7: error: (Each undeclared identifier is reported only once
main.m:7: error: for each function it appears in.)
main.m:12: warning: implicit declaration of function ‘compressFile’
main.m:7: warning: unused variable ‘outFileName’
make[1]: *** [obj/main.o] Error 1
make: *** [LeafZip.all.app.variables] Error 2
Also see the line 7 of main.m file:
char outFileName[PATH_MAX] = { 0 };
And see some lines of compress-file.m:
#include <stdio.h>
#include <zlib.h>
#include <limits.h>
/* Buffer to hold data read */
char buf[BUFSIZ] = { 0 };
size_t bytes_read = 0;
gzFile *out = gzopen(outFileName, "wb");
I know that is Objective-C extension, but it's only because when I solve this problem I will need to continue the development in Objective-C. What I need to do to correct this?
PATH_MAX is not always defined by including <limits.h>. If you want to use it, you probably need to fall back on the fragment:
#include <limits.h>
#ifndef PATH_MAX
#define PATH_MAX _POSIX_PATH_MAX /* Or possibly _XOPEN_PATH_MAX */
#endif /* PATH_MAX */
Did you even include limits.h in your main program? If not, you need to do so.
Looks like main.m needs to #include <limits.h>. It also seems like it will need to include a header describing compressFile (which I guess you moved into compress-file.m.