Fumbling through and failing at CODE writing. Working code, not working for me - pic

I have installed MPLAB X IDE, XC8 and MPLAB IPE to write the code. Also, I have bought 2 Dev boards for testing the code out on with a PIC16F88. A small chip to get my feet wet. As I looked over many website, I see they offered CODE for testing. Usually an example of push a button, make an LED come on.
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 4000000 // Fosc frequency for _delay() library
/*
*
*/
#include <xc.h> /* Hardware device support files. */
#include "16F88_xc8_header.h"
/*
*
*/
void main()
{
OSCCON = 0b01100000; // Internal frequency 4MHz
TRISA.F0 = 1; //Configure 1st bit of PORTA as input
TRISA.F1 = 1; //Configure 2nd bit of PORTA as input
TRISA.F2 = 1;
TRISA.F3 = 1;
TRISA.F0 = 0; //Configure 1st bit of PORTB as output
TRISB.F1 = 0; //Configure 2nd bit of PORTB as output
TRISB.F2 = 0;
TRISB.F3 = 0;
PORTB = "0x00"; //All LEDs OFF
do
{
if(PORTA.F0==0) //If 1st switch is pressed
{
__delay_ms(100); //Switch Debounce
if(PORTA.F0==0)//If the switch is still pressed
{
PORTB.F0 = 1; //1st LED ON
__delay_ms(1000); //1 Second Delay
PORTB.F0 = 0; //LED OFF
}
}
if(PORTA.F1 == 0) //If the 2nd switch is pressed
{
PORTB.F1 = 1; //2nd LED ON
__delay_ms(1000); //1 Second Delay
PORTB.F1 = 0; //LED OFF
}
if(PORTA.F2 == 0) //If the 3rd switch is pressed
{
PORTB.F2 = 1; //3rd LED ON
__delay_ms(1000); //1 Second Delay
PORTB.F2 = 0; //LED OFF
}
if(PORTA.F3 == 0) //If 4th switch is pressed
{
PORTB.F3 = 1; //4thLED ON
__delay_ms(1000); //1 Second Delay
PORTB.F3 = 0; //LED OFF
}
}
while(1);
}
Here is the Website the code came from ... https://microcontrollerslab.com/use-input-output-ports-pic18f452/
I adjusted a few things, like changing PORT letters and errors that came up when trying build. But there are some errors I fail to understand, so I can correct. Here is the build errors ...
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'F:/PIC Stuff/Basic Scanner PIC16F88/B_SCAN_TEST2.X'
make -f nbproject/Makefile-default.mk dist/default/production/B_SCAN_TEST2.X.production.hex
make[2]: Entering directory 'F:/PIC Stuff/Basic Scanner PIC16F88/B_SCAN_TEST2.X'
"C:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=16F88 -c -mdfp="C:/Program Files/Microchip/MPLABX/v5.45/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/16F88_TEST2.p1 16F88_TEST2.c
::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries
16F88_TEST2.c:28:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISA.F0 = 1; //Configure 1st bit of PORTA as input
~~~~~^~~
16F88_TEST2.c:30:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISA.F1 = 1; //Configure 2nd bit of PORTA as input
~~~~~^~~
16F88_TEST2.c:32:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISA.F2 = 1;
~~~~~^~~
16F88_TEST2.c:34:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISA.F3 = 1;
~~~~~^~~
16F88_TEST2.c:36:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISA.F0 = 0; //Configure 1st bit of PORTB as output
~~~~~^~~
16F88_TEST2.c:38:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISB.F1 = 0; //Configure 2nd bit of PORTB as output
~~~~~^~~
16F88_TEST2.c:40:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISB.F2 = 0;
~~~~~^~~
16F88_TEST2.c:42:8: error: member reference base type 'volatile unsigned char' is not a structure or union
TRISB.F3 = 0;
~~~~~^~~
16F88_TEST2.c:44:9: warning: incompatible pointer to integer conversion assigning to 'volatile unsigned char' from 'char [5]' [-Wint-conversion]
PORTB = "0x00"; //All LEDs OFF
^ ~~~~~~
16F88_TEST2.c:50:9: error: member reference base type 'volatile unsigned char' is not a structure or union
if(PORTA.F0==0) //If 1st switch is pressed
~~~~~^~~
16F88_TEST2.c:53:16: error: member reference base type 'volatile unsigned char' is not a structure or union
if(PORTA.F0==0)//If the switch is still pressed
~~~~~^~~
16F88_TEST2.c:55:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F0 = 1; //1st LED ON
~~~~~^~~
16F88_TEST2.c:57:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F0 = 0; //LED OFF
~~~~~^~~
16F88_TEST2.c:63:9: error: member reference base type 'volatile unsigned char' is not a structure or union
if(PORTA.F1 == 0) //If the 2nd switch is pressed
~~~~~^~~
16F88_TEST2.c:67:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F1 = 1; //2nd LED ON
~~~~~^~~
16F88_TEST2.c:71:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F1 = 0; //LED OFF
~~~~~^~~
16F88_TEST2.c:78:9: error: member reference base type 'volatile unsigned char' is not a structure or union
if(PORTA.F2 == 0) //If the 3rd switch is pressed
~~~~~^~~
16F88_TEST2.c:82:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F2 = 1; //3rd LED ON
~~~~~^~~
16F88_TEST2.c:86:15: error: member reference base type 'volatile unsigned char' is not a structure or union
PORTB.F2 = 0; //LED OFF
~~~~~^~~
16F88_TEST2.c:90:9: error: member reference base type 'volatile unsigned char' is not a structure or union
if(PORTA.F3 == 0) //If 4th switch is pressed
~~~~~^~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
1 warning and 20 errors generated.
(908) exit status = 1
nbproject/Makefile-default.mk:107: recipe for target 'build/default/production/16F88_TEST2.p1' failed
make[2]: Leaving directory 'F:/PIC Stuff/Basic Scanner PIC16F88/B_SCAN_TEST2.X'
nbproject/Makefile-default.mk:91: recipe for target '.build-conf' failed
make[1]: Leaving directory 'F:/PIC Stuff/Basic Scanner PIC16F88/B_SCAN_TEST2.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [build/default/production/16F88_TEST2.p1] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 781ms)

All Bit declarations are wrong. Look into the controller header.
e.g. This
TRISA.F0 = 1;
should be
TRISAbits.TRISA0 = 1; //Bit 0 of PORTA is an input
And as #Tagli mentioned there are more errors like:
PORTB = "0x00";
Which should be :
PORTB = 0x00;

Related

Make gcc print the code line when "required from here" error is printed

When my static assertion triggers, I get the following error message:
In file included from test2.cpp:1:
test.h: In instantiation of ‘test::test<T, test_from,test_to>::test() [with T = Eigen::Transform<double, 3, 1>; unsigned int test_from = 3740358174u; unsigned int test_to = 837757431u]’:
test2.cpp:51:27: required from here
test.h:38:9: error: static assertion failed: Wrong number assignment. Numbers in computation are assigned to a different object.
static_assert(test_from==test_from2,"Wrong number assignment. Numbers in computation are assigned to a different object.");
^
I would like gcc to print the line and highlight the character for the "required from here" disgnostic:
In file included from test2.cpp:1:
test.h: In instantiation of ‘test::test::test() [with T = Eigen::Transform; unsigned int test_from = 3740358174u; unsigned int test_to = 837757431u]’:
test2.cpp:51:27: required from here
destination = source.inverse();
^
test.h:38:9: error: static assertion failed: Wrong number assignment. Numbers in computation are assigned to a different object.
static_assert(test_from==test_from2,"Wrong number assignment. Numbers in computation are assigned to a different object.");
^
Is there any compiler flag or code pragma I can activate to have this behaviour?

How do you explain gcc's inline assembly constraints for the IN, OUT instructions of i386?

As far as I can tell, the constraints used in gcc inline assembly tell gcc where input and output variables must go (or must be) in order to generate valid assembly. As the Fine Manual says, "constraints on the placement of the operand".
Here's a specific, working example from a tutorial.
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "Nd"(port) );
return ret;
}
inb is AT&T syntax-speak for the i386 IN instruction that receives one byte from an I/O port.
Here are the specs for this instruction, taken from the i386 manual. Note that port numbers go from 0x0000 to 0xFFFF.
IN AL,imm8 // Input byte from immediate port into AL
IN AX,imm8 // Input word from immediate port into AX
IN EAX,imm8 // Input dword from immediate port into EAX
IN AL,DX // Input byte from port DX into AL
IN AX,DX // Input word from port DX into AX
IN EAX,DX // Input dword from port DX into EAX
Given a statement like uint8_t x = inb(0x80); the assembly output is, correctly, inb $0x80,%al. It used the IN AL,imm8 form of the instruction.
Now, let's say I just care about the IN AL,imm8 form, receiving a uint8_t from a port between 0x00 and 0xFF inclusive. The only difference between this and the working example is that port is now a uint8_t template parameter (to make it effectively a constant) and the constraint is now "N".
template<uint8_t port>
static inline uint8_t inb()
{
uint8_t ret;
asm volatile ( "inb %1, %0"
: "=a"(ret)
: "N"(port) );
return ret;
}
Fail!
I thought that the "N" constraint would mean, "you must have a constant unsigned 8-bit integer for this instruction", but clearly it does not because it is an "impossible constraint". Isn't the uint8_t template param a constant unsigned 8-bit integer?
If I replace "N" with "Nd", I get a different error:
./test.h: Assembler messages:
./test.h:23: Error: operand type mismatch for `in'
In this case, the assembler output is inb %dl, %al which obviously is not valid.
Why would this only work with "Nd" and uint16_t and not "N" and uint8_t?
EDIT:
Here's a stripped-down version I tried on godbolt.org:
#include <cstdint>
template<uint8_t N>
class Port {
public:
uint8_t in() const {
uint8_t data;
asm volatile("inb %[port], %%al"
:
: [port] "N" (N)
: // clobbers
);
return data;
}
};
void func() {
Port<0x7F>().in();
}
Interestingly, this works fine, except if you change N to anything between 0x80 and 0xFF. On clang this generates a "128 is out of range for constraint N" error. This generates a more generic error in gcc.
Based on how constraints are documented your code should work as expected.
This appears to still be a bug more than a year later. It appears the compilers are converting N from an unsigned value to a signed value and attempting to pass that into an inline assembly constraint. That of course fails when the value being passed into the constraint can't be represented as an 8-bit signed value. The input constraint "N" is suppose to allow an unsigned 8-bit value and any value between 0 and 255 (0xff) should be accepted:
N
Unsigned 8-bit integer constant (for in and out instructions).
There is a similar bug report to GCC's bugzilla titled "Constant constraint check sign extends unsigned constant input operands".
In one of the related threads it was suggested you can fix this issue by ANDing (&) 0xff to the constant (ie: N & 0xff). I have also found that static casting N to an unsigned type wider than uint8_t also works:
#include <cstdint>
template<uint8_t N>
class Port {
public:
uint8_t in() const {
uint8_t data;
asm volatile("inb %[port], %0"
: "=a"(data)
: [port] "N" (static_cast<uint16_t>(N))
: // clobbers
);
return data;
}
};
void func() {
Port<0x7f>().in();
Port<0x80>().in();
// Port<0x100>().in(); // Fails as expected since it doesn't fit in a uint8_t
}
To test this you can play with it on godbolt.

passing argument 1 of 'strlen' makes pointer from integer without a cast

It is not clear why I get a warning of:
[Warning] passing argument 1 of 'strlen' makes pointer from integer without a cast [enabled by default]
expected 'const char *' but argument is of type 'char'
on two of the 3 statements containing strlen() below.
Even when I attempted to cast *str it still gave the same warning.
bfr is a character buffer. *str points to that char buffer after the call to
gets(). If I use strlen(*str) I get a warning. If I use strlen(bfr) I do not.
But *str should be the equivalent to bfr. Thus the confusion regarding the error.
Now in reality, strlen arg 1 is defined as strlen(const char *string). So I
would have expected strlen(bfr) to also produce an error since bfr[] is a
char string and not a const char either.
And where is the integer that is being made into a pointer?
I am using gcc under wXDev-C++.
void test(){
FILE *fileID = fopen("somefile.txt","r");
char *str, len;
char bfr[16];
str = fgets(bfr,16,fileID); // str will be set equal to &bfr[0]
len = strlen(*str); // This gives a warning
len = strlen((const char)*str); // This gives a warning
len = strlen(bfr); // This does not give a warning
}
Sometimes you just need to take a fresh look in the morning at a problem. I realized that strlen is looking for a pointer to a string and 'str' is defined as a pointer. So *str would be a pointer to a pointer. So the warning was correct. It should read len = strlen(s) not len = strlen(*s). And it is 'str' pointing to 'bfr' not *str;
Answered my own question.

Attempting to use (SSE4) blendvpd with inline assembly in gcc

I would like to let the compiler choose registers automatically by parameter-izing my inline assembly in my C code, but I'm having some trouble. Can anyone tell me what is going wrong? If I use the code that I have commented out (forcing the affiliation with %xmm0), it will compile and get the expected result. But if I leave it commented out as written here, I get the compiler error:
/tmp/ccJxmSbm.s: Assembler messages:
/tmp/ccJxmSbm.s:81: Error: the first operand of `blendvpd' must be `%xmm0'
Also, if I do nothing other than remove the printf statement, the code block compiles successfully too. So it has something to do with moving parameters around to prepare for the printf call. I have explicitly put in the "Yz" constraint which is supposed to force the use of %xmm0, but it looks like it is not being honored.
Here is the code in question:
#include <stdio.h>
const unsigned long long myConst[2] = {0x0000000000000000,0xffffffffffffffff};
const unsigned long long myConst2[2] = {0x0000000000000000,0x1111111111111111};
const unsigned long long myConst3[2] = {0x0123456789abcdef,0x0000000000000000};
#define ASSIGN_CONST128( val, const ) \
val = *((__uint128_t *)const);
int main( void )
{
register __uint128_t regVal1 /* asm("%xmm0") */ ;
register __uint128_t regVal2;
register __uint128_t regVal3;
ASSIGN_CONST128( regVal1, myConst );
ASSIGN_CONST128( regVal2, myConst2 );
ASSIGN_CONST128( regVal3, myConst3 );
asm( "blendvpd %[mask], %[val1], %[val2]" :
[val2] "+x" (regVal3) :
[mask] "Yz" (regVal1),
[val1] "x" (regVal2) );
printf( "REGVAL1: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL2: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL3: %016llx%016llx (original=%016llx%016llx)\n",
(unsigned long long)(regVal1>>64), (unsigned long long)regVal1,
myConst[1], myConst[0],
(unsigned long long)(regVal2>>64), (unsigned long long)regVal2,
myConst2[1], myConst2[0],
(unsigned long long)(regVal3>>64), (unsigned long long)regVal3,
myConst3[1], myConst3[0] );
// Expected result:
// REGVAL1: ffffffffffffffff0000000000000000 (original=ffffffffffffffff0000000000000000)
// REGVAL2: 11111111111111110000000000000000 (original=11111111111111110000000000000000)
// REGVAL3: 11111111111111110123456789abcdef (original=00000000000000000123456789abcdef)
}
I appreciate any thoughts.
Why not just use the relevant intrinsic?
regVal3 = _mm_blendv_pd (regVal1, regVal2, regVal3);
As others have noted, regVal1, regVal2 and regVal3 should all be declared as __m128d.

How to pass input to soap_call in gsoap client application?

I have problem to pass request variable in my gsoap client app. The error is Segmentation Fault (core dump).
This is my header file:
class _ns1__NewTransactionDataRequest;
class _ns1__NewTransactionDataResponse;
class _ns1__GetTransactionResultRequest;
class _ns1__GetTransactionResultResponse;
class _ns1__NewTransactionDataRequest
{
public:
char* UserID 1;
char* UserPwd 1;
char* TransID 1;
char* TransDate 1;
char* A_NO 1;
char* B_NO 1;
char* Denom 1;
char* TransType 1;
struct soap *soap ;
};
class _ns1__NewTransactionDataResponse
{ public:
char* TransID 1;
char* ResultCode 1;
char* ResultDesc 1;
struct soap *soap ;
};
class _ns1__GetTransactionResultRequest
{
public:
char* UserID 1;
char* UserPwd 1;
char* TransID 1;
char* TransDate 1;
char* A_NO 1;
char* B_NO 1;
char* Status 1;
char* Remark 1;
struct soap *soap ;
};
class _ns1__GetTransactionResultResponse
{
public:
char* TransID 1;
char* ResultCode 1;
char* ResultDesc 1;
struct soap *soap ;
};
int __ns1__NewTransactionData(_ns1__NewTransactionDataRequest* ns1__NewTransactionDataRequest, _ns1__NewTransactionDataResponse* ns1__NewTransactionDataResponse
);
int __ns1__GetTransactionResult(_ns1__GetTransactionResultRequest*ns1__GetTransactionResultRequest,_ns1__GetTransactionResultResponse* ns1__GetTransactionResultResponse
);
This is the client app that I try to compile:
int main(int argc, char **argv)
{
struct soap soap;
_ns1__GetTransactionResultRequest *ns1__GetTransactionResultRequest;
_ns1__GetTransactionResultResponse *ns1__GetTransactionResultResponse;
_ns1__NewTransactionDataRequest *ns1__NewTransactionDataRequest;
_ns1__NewTransactionDataResponse *ns1__NewTransactionDataResponse;
(*ns1__GetTransactionResultRequest).UserID = "myuserid"; //<--fail at this line
(*ns1__GetTransactionResultRequest).UserPwd = "userpwd";
(*ns1__GetTransactionResultRequest).TransID = "amwani";
(*ns1__GetTransactionResultRequest).TransDate = "2013-09-09 01:01:01";
(*ns1__GetTransactionResultRequest).A_NO = "mynumber";
(*ns1__GetTransactionResultRequest).B_NO = "yournumber";
(*ns1__GetTransactionResultRequest).Status = "success";
(*ns1__GetTransactionResultRequest).Remark = "done";
printf("Content-type: text/html\r\n\r\n<html><h1>Magic Square of Rank</h1><pre>\n");
if (soap_call___ns1__GetTransactionResult(&soap, server, NULL, ns1__GetTransactionResultRequest, ns1__GetTransactionResultResponse))
{
soap_print_fault(&soap, stderr);
soap_print_fault_location(&soap, stderr);
}
else
{
printf("%s", (*ns1__GetTransactionResultRequest).TransID);
}
printf("</pre></html>\n");
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
}
I did not get any error during compilaton, but few warnings:
xpulsaclient.cpp: In function ‘int main(int, char**)’:
xpulsaclient.cpp:46: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:47: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:48: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:49: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:50: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:51: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:52: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:53: warning: deprecated conversion from string constant to ‘char*’
xpulsaclient.cpp:42: warning: unused variable ‘ns1__NewTransactionDataRequest’
xpulsaclient.cpp:43: warning: unused variable ‘ns1__NewTransactionDataResponse’
xpulsaclient.cpp:46: warning: ‘ns1__GetTransactionResultRequest’ is used uninitialized in this function
xpulsaclient.cpp:57: warning: ‘ns1__GetTransactionResultResponse’ may be used uninitialized in this function
Maybe the way I initialize variable in class ns1_GetTransactionResultRequest is not correct that caused the segmentation fault?. Can anyone help me? I have been stuck at this point for 2 days....Thanks!
You're right - you're not initializing ns1__GetTransactionResultRequest (or any of the other pointers). The variables you've declared are pointers, but they're never assigned to a new object. You can either instantiate objects, or declare the variables on the stack instead.
I've posted a simple gSOAP client app in another response. It includes assignment to a gSOAP request object property, which should help you out.
Example: making a web services query using gSoap with query arguments

Resources