Master program remake
Rsadeika
Posts: 3,837
I spent some time with Spin making the slave0 & master programs, I also spent some time with PropBASIC, now it's time to get back to C.
Below I started to do a C remake of my Spin version of master program. First, I tried to implement the XBee driver code, in C, necessary to get the XBee working. My code seemed to get the XBee working, but I could not get a C version of xbee_driver_Rx() to work. In the C code I tried using fgets, and fgetc with no success. The program below uses a spin2cpp conversion of the Spin code.
I would like to have an explanation for the multiple inits that are necessary for using FILE *term ..., it seems that their should be some way to just initialize it once, and be able to use term in not only main(), but in all the functions(), where it would be necessary. I am still having trouble understanding why, when I have a term running in main(), I can not get another FDS running in do_job1. I am running main() out to a terminal program on pins 25, and 24, but when I try do get do_job1 to use stdout, or use pins 31,and 30, everything falls apart.
The other thing I noticed is that when I initialized FILE *term ..., you have to have both the extern ..., lines of code, and you have to have the _Driver code present. It seems that if you have FullDuplexSerial.c in the compile mix, why do you have to have the extern ..., and _Driver lines of code?
Once I add the filetest.c, and RTC code, I will try to make do_job1 cog behave like my logger cog which I have in the Spin version. That should be fun, I hope it works.
Ray
Below I started to do a C remake of my Spin version of master program. First, I tried to implement the XBee driver code, in C, necessary to get the XBee working. My code seemed to get the XBee working, but I could not get a C version of xbee_driver_Rx() to work. In the C code I tried using fgets, and fgetc with no success. The program below uses a spin2cpp conversion of the Spin code.
I would like to have an explanation for the multiple inits that are necessary for using FILE *term ..., it seems that their should be some way to just initialize it once, and be able to use term in not only main(), but in all the functions(), where it would be necessary. I am still having trouble understanding why, when I have a term running in main(), I can not get another FDS running in do_job1. I am running main() out to a terminal program on pins 25, and 24, but when I try do get do_job1 to use stdout, or use pins 31,and 30, everything falls apart.
The other thing I noticed is that when I initialized FILE *term ..., you have to have both the extern ..., lines of code, and you have to have the _Driver code present. It seems that if you have FullDuplexSerial.c in the compile mix, why do you have to have the extern ..., and _Driver lines of code?
Once I add the filetest.c, and RTC code, I will try to make do_job1 cog behave like my logger cog which I have in the Spin version. That should be fun, I hope it works.
Ray
/** * @file Master0.c * This is the main Master0 program start point. */ #include <propeller.h> #include <stdlib.h> #include <stdio.h> #include <driver.h> #include <unistd.h> extern _Driver _SimpleSerialDriver; extern _Driver _FullDuplexSerialDriver; _Driver *_driverlist[] = { &_SimpleSerialDriver, &_FullDuplexSerialDriver, NULL }; FILE *stdinfile; FILE *stdoutfile; volatile int input; void do_job1(void *arg) { stdinfile = stdin; stdoutfile = stdout; // FILE *term = fopen("FDS:115200,25,24","r+"); // FILE *stdT = fopen("FDS:115200,31,30","r+"); xbee_driver_Start(27,26,0,9600); xbee_driver_At_configval("ATMY",0); // int input; waitcnt(CLKFREQ + CNT); // fprintf(stdT,"Slave0 Temp & Humidity\n"); // fflush(stdT); while(1) { // input = xbee_driver_Rx(); // if (input == 0x21) //0x21 '!' char // { // fprintf(term,"%c",0xD); //0xD 'CR' carriage return // fflush(term); // } // else // { // fprintf(term,"%c",input); // fflush(term); // } // usleep(50); // fflush(term); } } void high(int WCpin) { unsigned int bits = 1 << WCpin; DIRA |= bits; OUTA |= bits; } void low(int WCpin) { unsigned int mask = 1 << WCpin; DIRA |= mask; OUTA &= ~mask; } void getxb(void) { FILE *term = fopen("FDS:115200,25,24","r+"); while(1) { input = xbee_driver_Rx(); if (input < 0x21 || input > 0x21) { fprintf(term,"%c",input); continue; } else if (input == 0x21) { fflush(term); fprintf(term, "%d\n", 10); break; } } } /** * Main program function. */ int main(void) { FILE *term = fopen("FDS:115200,25,24","r+"); int stacksize = sizeof(_thread_state_t)+sizeof(int)*3; int *stack = (int*) malloc(stacksize); int cog; cog = cogstart(do_job1, NULL, stack, stacksize); waitcnt(CLKFREQ + CNT); fprintf(term,"This is Main\n"); getxb(); while(1) { input = xbee_driver_Rx(); if (input == 0x21) //0x21 '!' char { fprintf(term,"%c",0xD); //0xD 'CR' carriage return fflush(term); } else { fprintf(term,"%c",input); fflush(term); } usleep(50); fflush(term); } return 0; }
Comments
As for your other question, about the FILE *term, there is a big difference between local variables (ones declared inside a function) and global variables (ones declared outside a function). Local variables can only be accessed inside the function, but global variables can be accessed anywhere. If you want to share the term variable, you have to make the variable global.
Eric
This looks like a big program redesign problem, need help from the experts. Not sure if this can be done, the way I think it should be done, using C and the Propeller. I am not even sure that if there was code refinement that that would even make it fit in CMM mode. So, the biggest problem that I can see is trying to get a cog to run in XMMC mode, in other words to have it work like the program outline below.
I already tried using pthreads, that did not work out. I would need a thread that acted like a cog, which does not work that way. The only other thing that is left, is trying to use a cog_c style, which is way to complex for me to even attempt to try. And in my opinion, probably would not do what I want it to do anyway. So, does my master program have to start looking for a new chip to work with?
Ray
Have you tried to check the option to use simple printf or tinylib (in beta only IIRC)? Usually (in the later case) it can shave off easily like 10kb of code.
Also, in more than one place I noticed that you're fopen-ing 'term' with "r+" but then writing to it by fprintf instead. Either I misuderstood something or this is not supposed to work unless a write mode is used. Same with 'stdT'.
-j
I implemented the getxb() command for a test run of the XBee, that seems to be working like expect, but the characters that are being output, is sometimes not the full line that I expect. I think there is a timing issue between the pthreads, but I am not sure.
The other concern that I have is that when one of the pthreads grows in terms of lines of code, will the timing have to be fine tuned to make it work correctly? In do_job1, I have the LED that is flashing at a one second rate, and in do_job2, I have a sleep(1) in the while(1) loop, so they seemed to be balanced, but are not behaving correctly. Any ideas as to how to fix the mentioned problems?
Ray
Please don't use waitcnt with pthreads. Use usleep instead.
The second thing is, I am using a DNA board, and I have it set with XMMC mode. Now in this program, a FullDuplexSerial.c(spin2cpp) is being implemented via xbee_drive.c(spin2cpp). Since the FullDuplexSerial.c program implements a cog, why is this program still able to run, I thought that cogs did not work in XMMC mode?
I am going in a different direction with this program, I will be creating a C# program that will actually take the data, that will be coming via pins 31,30, and the C# program will manipulate the data, either for display on the screen, or create a CSV file for further manipulation. Also from the C# program, I will try to control things that are running in the pthreads, for example the slave0 xbee that is sending data.
Ray
Ray
Ray
I now have a simple C# program where I have buttons to control the LED in do_job1, and a button to get a getxb() displayed in the main text window. So far it is all working as expected, but this is the easy stuff.
Ray
I tried your code without xbee since I don't have one of those or your xbee c file.
Of course it doesn't work because you didn't follow Dave Hein's suggestion above.
Here is a more flexible version of makeraw() to set echo by the driver.
If you call it with "makeraw(0);" you would be responsible for echoing the character.
Hope this helps.
--Steve