Code is not working (C++ unions and structures) - c++

No matter how many times I reformat this, I keep getting all kinds of errors. The end result will be a program that can save functions targeting motors in a telescope and set coordinates. Any help in explaining what I am doing wrong with this setup would be greatly appreciated. here is the code:
//IDENTIFY RECEIVER OF MESSAGE / TYPE OF MESSAGE / VIEW ALL TO 1 DEVICE / VIEW SPECIFIC MESSAGE
#include "messaging.h"
#include <string.h>
#include <stdio.h>
using namespace std;
typedef struct MGR{
mess_types messagetype;
int DeviceID;
union E{
//why arte these underlined?
char INST[STRSIZE];
int codes[NBRCODES];
float coords[NBRCOORDS];
} message;
};// info;
void messager(){
MGR my_data;
my_data.messagetype = INST;
my_data.DeviceID = TECH1;
strcpy(my_data.message.INST, "GO HOME");
my_data.messagetype = CODES;
my_data.DeviceID = MOTOR1;
for (int nbr = 0; nbr < NBRCODES; nbr++){
my_data.message.codes[nbr] = nbr;
print_message(my_data);
}
}
int print_message(MGR mydata){
MGR noot;
scanf("%s", &mydata);
switch (mydata.messagetype){
case INST:
printf("Message to Device %d", noot.DeviceID);
break;
case CODES:
printf("The setup codes for device %d are: \n", noot.DeviceID);
for (int code = 0; code < NBRCODES + OFFSET; code++){
printf("%4d\t", noot.message);
}
break;
case COORDS:
printf("The setup codes for device %d are: \n", noot.DeviceID);
for (int code = 0; code < NBRCODES + OFFSET; code++){
printf("%4d\t", noot.message);
}
break;
}
printf("%c", mydata.messagetype);
return(0)
}
void Sendmessage(){
printf("This program does not work... it is under construction...");
}
Just in case: here is the header file
#include "sprint1.h"
#include <string.h>
#include <stdio.h>
#define STRSIZE 50
#define NBRCODES 200
#define NBRCOORDS 200
#define OFFSET 100
#define FACTOR 50
#define TECH1 123
#define MOTOR1 4556
void messager();
int print_message(MGR mydata);
void Sendmessage();
enum mess_types {INST, CODES, COORDS};
Error list: https://drive.google.com/file/d/0B0CXbbHDOrweQVVvOVU1M0VRaEE/view?usp=sharing

I assume the header listed is "messaging.h"
MGR is referenced in the header before it's definition in the code.
Maybe move the definition to the header before the first reference.

Related

Listing serial ports on Windows

Header
#pragma once
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <WinBase.h>
using namespace std;
class SerialPort {
public:
BOOL COM_exists(int port);
};
cpp
#include "stdafx.h"
#include <string.h>
#include "SerialPort.h"
using namespace std;
BOOL SerialPort::COM_exists(int port)
{
char buffer[7];
COMMCONFIG CommConfig;
DWORD size;
if (!(1 <= port && port <= 255))
{
return FALSE;
}
snprintf(buffer, sizeof buffer, "COM%d", port);
size = sizeof CommConfig;
// COM port exists if GetDefaultCommConfig returns TRUE
// or changes <size> to indicate COMMCONFIG buffer too small.
return (GetDefaultCommConfig(L"buffer", &CommConfig, &size)
|| size > sizeof CommConfig);
}
main
#include "stdafx.h"
#include <iostream>
#include "SerialPort.h"
using namespace std;
if(num==1)
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout <<"COM%d \n";
}
}
}
I want listing serial ports on Windows ,but I'm having a hard time.
Help me list the serial ports. error code = c3861 ,e0020
I want listing serial ports on windows.
The end of the road ,Select a serial port that can be connected to enable communication.
please help me
Main problem is here
if(num==1)
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout <<"COM%d \n";
}
}
}
In C++ code has to go in functions (a simplification but good enough for now) and the program starts with a special function called main. Also cout <<"COM%d \n"; is not the correct way to print a COM port, I've used the correct way in the code below. Also in the code above what is num supposed to be?
Anyway rewrite as follows and you're a little closer
int main() // start of program
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
cout << "COM " << i << "\n";
}
}
}
There are other problems such as the pointless SerialPort class. I would just remove that.
Replace
class SerialPort {
public:
BOOL COM_exists(int port);
};
with
BOOL COM_exists(int port);
and
BOOL SerialPort::COM_exists(int port)
with
BOOL COM_exists(int port)
The code looks like you are trying to learn C++ by cutting and pasting code from the internet. That is never going to work, C++ is a complex language and really needs formal study to be learned effectively. Here's a curated list of C++ books.

C++ compile error messages

So I have this code that I have to edit a bit but the code itself doesn't compile when I try in mobaxterm and since I don't really have much experience with C++ I hope u guys can help. This is the code:
//critical_example2.c
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "se207_sems.h"
int main(int argc, char argv[]){
//Use our source file as the "key"
int id=se207_semget("critical_example2.c",1);
int pid=fork();
if(pid){
//P1
while(1){
se207_wait(id);
printf("In critical section P1 ... \n");
rsleep();
printf("Ending critical section P1 ... \n");
se207_signal(id);
}
}else{
//P2
while(1){
se207_wait(id);
printf("In critical section P2 ... \n");
rsleep();
printf("Ending critical section P2 ... \n");
se207_signal(id);
}
}
}
This are the errors i get:
toneve#hvs-its-lnx01:~$ gcc critical_example2.c
In file included from critical_example2.c:9:0:
se207_sems.h: In function ‘se207_wait’:
se207_sems.h:91:6: warning: type of ‘id’ defaults to ‘int’ [-Wimplicit-int]
void se207_wait(id){
^
se207_sems.h: In function ‘se207_signal’:
se207_sems.h:95:6: warning: type of ‘id’ defaults to ‘int’ [-Wimplicit-int]
void se207_signal(id){
This might be the problematic code:
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h>
void rsleep(){
//Random sleep function. Comes in handy demoing stuff.
int stime=2+(rand()/(float)(RAND_MAX))*4;
printf("Sleeping for %d secs\n",stime);
sleep(stime);
}
int se207_semget(char* path, int val){
//Very simple semaphore "getting",
//always uses 1 as the project ID
//takes path to file and initial value of semaphore
int id; /* Number by which the semaphore
is known within a program */
union semun {
int val;
struct semid_ds *buf;
ushort * array;
} argument;
argument.val = val;
/* Create the semaphore with external key from
ftok if it doesn't already
exist. Give permissions to the world. */
id = semget(ftok(path,1), 1, 0666 | IPC_CREAT);
/* Always check system returns. */
if(id < 0)
{
fprintf(stderr, "Unable to obtain semaphore.\n");
exit(0);
}
/* Set the value of the number 0 semaphore in semaphore array # id
to the value "val". */
if( semctl(id, 0, SETVAL, argument) < 0)
fprintf( stderr, "Cannot set semaphore value.\n");
else
fprintf(stderr, "Semaphore %d initialized with path '%s'.\n",
ftok(path,1),path);
return id;
}
void se207_semop(int id,int val){
struct sembuf operations[1];
int retval; /* Return value from semop() */
//simple wait on semaphore
operations[0].sem_num = 0;
/* Which operation? Subtract 1 from semaphore value to wait, add to
signal */
operations[0].sem_op = val;
operations[0].sem_flg = 0;
retval = semop(id, operations, 1);
}
int void se207_wait(id){
se207_semop(id,-1);
}
int void se207_signal(id){
se207_semop(id,1);
}
Remove the int from your se207_wait and se207_signal functions, and declare id as an int in the parameter list.
void se207_wait(int id){
se207_semop(id,-1);
}
void se207_signal(int id){
se207_semop(id,1);
}

Issue getting functions from library and strange conversion error

I'm trying to write an arduino library. I've written a few classes before but nothing for arduino. I'm running into one error pretty consistently. First let me show you the code:
Code
Main.ino (The arduino project)
#include <Wire.h>
#include "Mobility.h"
Mobility mol = new Mobility();
void setup() {
Serial.begin(9600);
Wire.begin();
}
void loop() {
Serial.println("loop");
mol.move(true, 125, false, 125, 10);
delay(2000);
}
Mobility.h
#ifndef MOBILITY_H
#define MOBILITY_H
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
const int DEFAULT_MOBILITY_ADD = 4;
class Mobility
{
public:
void begin();
void begin(int address);
int i2cAdd;
int move(bool lPos, unsigned char leftPower, bool rPos, unsigned char rightPower, unsigned char msec);
private:
};
/**/
#endif
Mobility.cpp
#if (ARDUINO >= 100)
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include "Mobility.h"
#include "Wire.h"
void Mobility::begin(){
Wire.begin();
this.i2cAdd = DEFAULT_MOBILITY_ADD;
}
void Mobility::begin(int address){
Wire.begin();
this.i2cAdd = address;
}
int Mobility::move(bool lPos, unsigned char leftPower,bool rPos, unsigned char rightPower, unsigned char msec){
if (leftPower < -255 || leftPower > 255){
return -1;
}
if (rightPower < -255 || rightPower > 255){
return -2;
}
if(msec <= 0){
return -3;
}
Wire.beginTransmission(this.i2cAdd);
Wire.write(lPos);
Wire.write(leftPower);
Wire.write(rPos);
Wire.write(rightPower);
Wire.write(msec);
Wire.endTransmission();
return 0;
}
ERRORS
I've been getting two big errors while I've been trying to fix the code. The first is:
error: conversion from 'Mobility*' to non-scalar type 'Mobility' requested
Mobility mol = new Mobility();
The problem is caused by this line:
Mobility mol = new Mobility();
the first part is static memory allocation:Mobility mol - statically allocates memory for the object mol.
the second part uses dynamic memory allocation: new - dynamically allocates memory.
So you can do :
Mobility mol;// static allocation
or
Mobility *mol = new Mobility(); //dynamic allcocation
But not a mix of the two. Either way the constructor will be called when creating the object.

Sending TFTP packets in C++

I am relatively new to C++, so please forgive my lack of knowledge. I need help regarding TFTP packets. Below is the code I am using to generate a WRQ (write request package) and DATA packet which will be sent to a designated server.
bool createWRQ(char * filename) {
/* structure is the same as RRQ */
clear();
addWord(TFTP_OPCODE_WRITE);
addString(filename);
addByte(0);
addString(TFTP_DEFAULT_TRANSFER_MODE);
addByte(0);
return true;
}
bool createData(int block, char * mData, int data_size) {
/* 2 bytes 2 bytes n bytes
----------------------------------------
DATA | 03 | Block # | Data |
---------------------------------------- */
clear(); // to clean the memory location
addWord(TFTP_OPCODE_DATA);
addWord(block);
addMemory(mData, data_size);
return true;
}
I will include the declarations and required functions.
#include "stdafx.h"
#include "WebComm.h"
#include "WebCommDlg.h"
#include <stdio.h>
#include <stdlib.h>
#include "visa.h"
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <string>
#include <fstream>
#include <cstdio>
#include <cerrno>
int mCurPacketSize = 512;
char mData[512];
#define VIBUF_LEN 255
#define TFTP_OPCODE_READ 1
#define TFTP_OPCODE_WRITE 2
#define TFTP_OPCODE_DATA 3
#define TFTP_OPCODE_ACK 4
#define TFTP_OPCODE_ERROR 5
#define cTFTPPacket_MAX_SIZE 1024
#define cTFTPPacket_DATA_SIZE 512
#define TFTP_DEFAULT_TRANSFER_MODE "octet" //"netascii", "octet", or "mail"
typedef unsigned char BYTE;
typedef unsigned short WORD;
bool addByte(BYTE b) {
if(mCurPacketSize >= cTFTPPacket_MAX_SIZE)
return false;
mData[mCurPacketSize] = (unsigned char)b;
mCurPacketSize++;
return true;
}
bool addWord(WORD w) {
w = htons(w);
if(!addByte(*(((BYTE*)&w)+1)))
return false;
return !addByte(*((BYTE*)&w));
}
bool addString(char * str) {
int n = strlen(str);
for(int i=0; i<n; i++)
if(!addByte(str[i]))
return false;
return true;
}
bool addMemory(char * buffer, int len) {
bool oStatus = false;
if(mCurPacketSize + len >= cTFTPPacket_MAX_SIZE) {
AfxMessageBox("Packet max size exceeded");
return false;
} else {
memcpy(mData + mCurPacketSize), buffer, len);
mCurPacketSize += len;
return true;
}
}
void clear() {
mCurPacketSize = 0;
memset(mData, mCurPacketSize, cTFTPPacket_MAX_SIZE);
}
I am aware these function have been declared mostly as type bool, however I need to send a WRQ packet to the server and wait for an ACK response before sending a DATA packet.
Something along the lines of:
while(/* something */)
if(!sendto(socket, WRQ, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in)))){
if(!recvfrom(socket, ACK, /* ... */))
sendto(socket, DATA_Packet, 512, NULL, (sockaddr*)&Addr, sizeof(struct sockaddr_in))));
My question is: how can I modify the createWRQ() and createData() functions so that I can return them as packets to use for transmission, since bool only returns true or false as 1 or 0.
I need to be able to send them using the winsock send and receive functions. Apologies for the silly question. If anyone could point me in the right direction I would greatly appreciate it.
your whole approach has a few issues...
When you create your packets relying on functions like
bool addByte(BYTE b)
they use global variables
mCurPacketSize, mData
that's not good. You could use instead something on these lines
int addByte(char* Pkt, int PktIdx, BYTE b)
{
if (PktIdx > cTFTPPacket_MAX_SIZE)
{
return 0;
}
Pkt[PktIdx] = (unsigned char)b;
PktIdx++;
return PktIdx;
}
then you know that Pkt is always the head of your packet and PktIdx is either the place for a new byte (or string) and "also" the size of the packet.
When you create packets that have a fixed length structure (or a fixed length header followed by a variable length payload area) it is a good idea to represent the fixed length area with a "packed" (pay attention to memory alignment) C/C++ structure and then populate the structure.

Field '__jmpbuf' could not be resolved -cpp

I get this error when trying to compile my program:
Field '__jmpbuf' could not be resolved
I looked for a solution for hours and can't seem to find out where is the culprit.
The Thread.h file contains the header of the class. It has the private member:
sigjmp_buf _env;
And the implementation is inside Thread.cpp:
#include "Thread.h"
#include <setjmp.h>
#include "translateAdd.h"
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define COUNTER_INIT -1
int Thread::_idCounter = COUNTER_INIT;
Thread::Thread(void (*threadsFunc)(void))
: threadsFunction(threadsFunc), _stack(new char[STACK_SIZE]), _quantums(1)
{
address_t sp, pc;
sp = (address_t)_stack + STACK_SIZE - sizeof(address_t);
pc = (address_t)threadsFunc;
// set environment for later return
sigsetjmp(_env, 1);
(_env->__jmpbuf)[JB_SP] = translate_address(sp);
(_env->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&_env->__saved_mask);
_id = ++_idCounter;
_state = READY;
}
EDIT: Using eclipse as the IDE under ubuntu 32bit
EDIT: Another complete example that doesn't compile on my machine:
#include <stdio.h>
#include <setjmp.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#define SECOND 1000000
#define STACK_SIZE 4096
char stack1[STACK_SIZE];
char stack2[STACK_SIZE];
sigjmp_buf env[2];
#ifdef __x86_64__
/* code for 64 bit Intel arch */
typedef unsigned long address_t;
#define JB_SP 6
#define JB_PC 7
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%fs:0x30,%0\n"
"rol $0x11,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#else
/* code for 32 bit Intel arch */
typedef unsigned int address_t;
#define JB_SP 4
#define JB_PC 5
/* A translation is required when using an address of a variable.
Use this as a black box in your code. */
address_t translate_address(address_t addr)
{
address_t ret;
asm volatile("xor %%gs:0x18,%0\n"
"rol $0x9,%0\n"
: "=g" (ret)
: "0" (addr));
return ret;
}
#endif
void switchThreads(void)
{
static int currentThread = 0;
int ret_val = sigsetjmp(env[currentThread],1);
printf("SWITCH: ret_val=%d\n", ret_val);
if (ret_val == 1) {
return;
}
currentThread = 1 - currentThread;
siglongjmp(env[currentThread],1);
}
void f(void)
{
int i = 0;
while(1){
++i;
printf("in f (%d)\n",i);
if (i % 3 == 0) {
printf("f: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void g(void)
{
int i = 0;
while(1){
++i;
printf("in g (%d)\n",i);
if (i % 5 == 0) {
printf("g: switching\n");
switchThreads();
}
usleep(SECOND);
}
}
void setup(void)
{
address_t sp, pc;
sp = (address_t)stack1 + STACK_SIZE - sizeof(address_t);
pc = (address_t)f;
sigsetjmp(env[0], 1);
(env[0]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[0]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[0]->__saved_mask);
sp = (address_t)stack2 + STACK_SIZE - sizeof(address_t);
pc = (address_t)g;
sigsetjmp(env[1], 1);
(env[1]->__jmpbuf)[JB_SP] = translate_address(sp);
(env[1]->__jmpbuf)[JB_PC] = translate_address(pc);
sigemptyset(&env[1]->__saved_mask);
}
int main(void)
{
setup();
siglongjmp(env[0], 1);
return 0;
}
If you really need to use the internal fields (which will only be valid for your compiler on your system) you need to check the types:
typedef struct __jmp_buf_tag sigjmp_buf[1];
That means that sigjmp_buf is not a pointer, but an array with a single structure in it. So you use it like a normal array of structures:
sigjmp_buf _env;
_env[0].__jmpbuf[x] = y;
I really recommend against the use the internal field of this structure. Linux have other functions to simplify cooperative threading (which is what you seem to be implementing).