This works if you are in the folder where you have the files. Still not sure how I would accomplish multiple file compiles using the command line batch file?
Ray
Hi Ray, I've been looking at this today. There are different options to answering this question.
Create your own batch file that compiles everything
Use make to manage it (default for geany)
Have a custom program that knows what to do with your files
Overview of those options:
1. Adding multiple files to the command line works fine up to a point and is probably easiest for simple multi-file projects.
@rem file build.bat
@rem batch file to build a project with multiple files.
@rem example syntax c:\projectpath\> build.bat program
@c:\propgcc\bin\propeller-elf-gcc -o program.elf -Os file1.c file2.c file3.c mainfile.c -s
Well, the following was a neat idea, but I can't get it to work. Just use the command line. [You could put "build.bat" in the Geany Build->Set Build Commands "make button" dialog box and use make to build your project. Using the build button would only affect the file shown in the editor.]
Using batch files to compile everything can be overwhelming for big projects. For small projects it's ok. Problem is in understanding all the rules for building and applying the rules, which is kind of like learning how to create make files.
2. Using make and Makefiles is a standard practice and is supported by many IDEs including Geany. We have examples in the demos that show what to do with these. Still, I understand that regular people don't like make files, so this is a non starter for some.
3. Having a custom program that uses built-in rules on files and project properties can be very simple for users, but it may not be the best way to go. I do have some code from a project that can handle most of this although I'm reluctant to go further with it at the moment, but I can experiment a little.
Your on-going support and development question would be best answered by Parallax. I'll invite an answer.
It is common knowledge that Parallax is developing the Eclipse Prop-GCC IDE, but who will be maintaining, and doing further development of Prop-GCC? I am hoping that Prop-GCC does not go dormant like Spin development.
Ray
Hey Ray -
I'm glad you asked because it gives us an opportunity to start establishing our intent to support Propeller GCC for the long term. In Parallax we've been busy with the timeline and management, but the real effort has come from the team (Erik Smith, Bill Henning, Ken Rose, Charlie Kelly, Jeff Martin, Steve Denson) and a series of volunteers (Dave Hein, David Betz, and others) quite numerous and very important to this project. This year we realized and acted upon the importance of mainstream language support with multi-platform and open-source code base. Propeller GCC is a major, long-term commitment from Parallax. Porting the GCC compiler to Propeller 1 allows us to get familiar with the code base and to start developing new programs and community acceptance around it, while having the added benefit of preparing the development team for Propeller 2. The investment here is very significant in terms of cost and time, and you should feel comfortable putting your time into using our C tools for the long term. The same team who developed the tools will also maintain them for the long term. And if they are unable to do so for some reason we've got an open-source code base from professional developers that could be maintained by others. That's why our team is much larger than a few people. Although [in my view] it took skilled developers to do the kernel, GCC port and Eclipse GUI, the resultant code base is far more accessible for change than if it were done by a small team or a single person. It is our policy to provide long-term support for Propeller GCC, just to be clear.
If you are interested in C from the standpoint of learning a new skill you will have our support (via learn.parallax.com) and many code examples. Learn.parallax.com is being launched with Spin, but you'll see C examples side by side. In fact, this same portal will also have PBASIC and Arduino C examples. You'll see Propeller C in the KickStart examples, too.
Spin shall grow and is the language presently used in all of the higher-volume commercially-available products based on the Propeller. These same customers expect to have Spin support in Propeller 2, with some level of code compatibility. The recent focus on C is because of business timing and preparations for Propeller 2. Remember, we've been here for 22 years and we're in business for the long-term - being quiet on Spin improvements for the last year should have no bearing on what lies ahead. Since you asked, however, Chip plans on writing "an awesome Spin interpreter" for Propeller 2. Also, remember not to overlook the compiler port from X86 to C/C++ which finally allows Spin improvements.
From a PC development tool standpoint, the likely evolution for Spin is that we will adopt an existing open-source alternative presently available for Propeller 1 and 2 support, and that Eclipse will be used for Propeller-GCC for Propeller 1 and 2. It is not clear that the two languages will be able to live and peacefully co-exist in the same world (please don't open this up as a discussion, at least in this thread). We are currently evaluating choices for the future Spin development environment.
Thanks Ken for addressing my concerns, hopefully everybody will now feel more confident with investing their time in using Prop-GCC software.
The program below, I am trying to capture a keypress, and display it on the local terminal. The program does not compile, and it displays these errors:
fds5.c:19:34: error: macro "getchar" passed 1 arguments, but takes just 0
fds5.c:19:22: warning: initialization makes integer from pointer without a cast [enabled by default]
For this piece of code I would like to see the keypress on the external terminal be displayed on the local terminal. The next thing would be to have a specific keypress on the external terminal turn on/off an LED on the C3 board.
getchar and putchar use the standard input and output, which by default is the serial port on pins 31 and 30. You need to use fgetc and fputc instead. Also, you need to call fgetc on a separate line after to declare serport_byte or it will only execute once. Your loop should look like this:
while (1)
{
int serport_byte;
serport_byte = fgetc(port);
fputc(serport_byte, port);
}
Another problem you'll run into is that the serial port will be buffered, so you won't get a character until a CR is received. At least that's the way stdin works. You also won't get any output until you send a CR, or maybe a newline. The may be a way to open the port in an unbuffered mode, but I don't know how to do that. Maybe someone else can describe and easy way to do unbuffered I/O.
The program sort of works. The problem is that I am getting erratic output of characters, sometimes I have to type in two chars to see them displayed, and their seems to be a lag time between keypress and the display of a character(s), probably a couple of seconds, if not more. I am not sure what the fix for this would be, anybody have any ideas? I also lowered the baud rate to 9600, plus I tried putting in some waitMS(25), but that does not seem to help.
The program sort of works. The problem is that I am getting erratic output of characters, sometimes I have to type in two chars to see them displayed, and their seems to be a lag time between keypress and the
Hi Ray,
As Dave Hein mentioned we have to press "enter" after input with the standard library I/O - that is, by default the serial streams are buffered.
There is a way to change the default behavior to receive and echo characters as they are typed. This program works perfectly for me either buffered or unbuffered in windows. I use PST for the port on P0/1 and have preferences set with New Line checked and Line Feed not checked. I've used baud rates from 9600 to 115200.
Interestingly the program is 8KB regardless of using -Dprintf=__simple_printf or not. If we used a different custom driver for the separate serial port, the program would be much bigger.
#include <stdio.h>
#include <propeller.h>
/*
* Setup serial IO so that characters typed to stdio
* are echoed immediately to the port.
*/
void disableBufferedIO(FILE *port)
{
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(port, NULL, _IONBF, 0);
}
int main(void)
{
char *serdevice = "SSER:9600,1,0";
FILE *port = fopen(serdevice,"r+");
/* remove to keep default buffered IO behavior */
disableBufferedIO(port);
/* wait for console to start */
sleep(1);
/* let user know we are working */
fprintf(stdout, "Started echo program.\n");
fprintf(port, "Echo to here.\n");
/* receive and echo characters */
while(1)
{
int byte = fgetc(stdin);
fprintf(port,"%c",byte);
}
fclose(port);
return 0;
}
Interestingly the program is 8KB regardless of using -Dprintf=__simple_printf or not. If we used a different custom driver for the separate serial port, the program would be much bigger.
The compiler replaces printf and fprintf with putc, puts, fputc and fputs for simple formats that don't include numeric conversion, so it doesn't load printf or sprintf from the library. That's probably why there was no apparent effect from using __simple_printf.
The program below compiles and runs, but it is not doing what I expected. When I have the external terminal running on p 23,22 and the stdout terminal active, and I keypress 'a', with an 'ENTER' on the external terminal I get an 'a' on the screen. When I do the same thing on the stdout terminal, I get an 'a' plus the 'You pressed 'a'.' message, plus the message also appears on the external terminal window. So, basically when I keypress 'a' on the external terminal, I am not getting the 'You pressed 'a'.' message. What am I missing?
The program below compiles and runs, but it is not doing what I expected. When I have the external terminal running on p 23,22 and the stdout terminal active, and I keypress 'a', with an 'ENTER' on the external terminal I get an 'a' on the screen. When I do the same thing on the stdout terminal, I get an 'a' plus the 'You pressed 'a'.' message, plus the message also appears on the external terminal window. So, basically when I keypress 'a' on the external terminal, I am not getting the 'You pressed 'a'.' message. What am I missing?
Your code doesn't fetch characters from the terminal on P23,22.
There is a problem though. If I use this program it works mostly.
I changed fgetc(stdin) to fgetc(port) and added "setvbuf(port, NULL, _IONBF, 0);".
This makes the input from "port" and unbuffered.
Not sure at this point why it would be necessary to make port unbuffered.
Looks like a bug to me.
Below, I have added some more things, like a menu, and LED on/off choice. Is their a better way to handle the 'F1' and 'F2' keypress? I tried running this with the unbuffered code, and I get three repeats when I press a key. When I keypress 'a' I get: "aaaYou pressed 'a' " displayed, plus it gets displayed on the stdin terminal, but has no keyboard interaction, except for the Esc key, when you switch to that window.
Does the stdin terminal have any cursor movement control commands? I suppose it would also be nice to add some color.
Ray
/*
* fds7.c
*/
#include <stdio.h>
#include <unistd.h>
#include <propeller.h>
#include "misc.h"
int main(void)
{
char *serdevice = "SSER:9600,23,22";
FILE *port = fopen(serdevice, "r+");
/* disabIO(port); */
/*setvbuf(port, NULL, _IONBF,0);*/
waitMS(100);
fprintf(stdout, "Start echo.\n");
fprintf(port, "Start echo.\n");
fprintf(stdout, "F1 for menu\n");
while(1)
{
int byte = fgetc(stdin);
/* int byte = fgetc(port); */
fprintf(port,"[%c]",byte);
if ( byte == 'a')
{
fprintf(port, "You pressed 'a'.\n");
fprintf(stdout, "You pressed 'a'.\n");
}
if (byte == ('\xff' & '\x3c')) /* 'F2' to quit while loop. */
{
break;
}
if (byte == ('\xff' & '\x3b')) /* F1 key */
{
fprintf(stdout,"Menu\n");
fprintf(stdout,"F1 - Menu\n");
fprintf(stdout,"F2 - quit\n");
fprintf(stdout,"1, - LED on\n");
fprintf(stdout,"2, - LED off\n");
}
if (byte == '1')
{
high(21);
fprintf(stdout,"LED is on\n");
}
if (byte == '2')
{
low(21);
fprintf(stdout,"LED is off\n");
}
}
fprintf(stdout, "Hit 'Esc' leave program.\n");
fclose(port);
return 0;
}
Below, I have added some more things, like a menu, and LED on/off choice. Is their a better way to handle the 'F1' and 'F2' keypress?
You could use a "switch" statement.
// this is a fragment that must be put into a function
int running = 1;
while(running) {
switch(byte) {
case 1:
// led is on
break;
case 2:
// led is OFF
break;
case 'a':
// print you pressed a
break;
case 0xff:
int nextbyte = fgetc(stdin);
switch(nextbyte) {
case 0x3b:
// print menu
break;
case 0x3c:
// exit condition - change while(1) to while(running)
running = 0;
break;
}
break;
}
}
I tried running this with the unbuffered code, and I get three repeats when I press a key. When I keypress 'a' I get: "aaaYou pressed 'a' " displayed, plus it gets displayed on the stdin terminal, but has no keyboard interaction, except for the Esc key, when you switch to that window.
I've seen something like this "aaaYou pressed 'a'" thing, and sent a note out to the team this morning. Haven't heard back yet.
In this program I am trying to open two ports, get input from the external terminal, and display it on both terminal screens. I am not getting anything displayed on the std terminal. The stuff that gets displayed on the external terminal is getting mixed results, in the PST I get nothing displayed, on my personal terminal program, I get what I typed in, but it is single spaced between chars in some cases, and double spaced between other chars, all from the same input. I am trying to move up to entering a word command as opposed to a single letter command, i.e. quit vs q.
In another post, it was mentioned that their will be a lib provided for making use of the propeller, what sort of functions will be made available. I will keep my misc.h to bare minimum if the "team" is coming up with something better.
In this program I am trying to open two ports, get input from the external terminal, and display it on both terminal screens. I am not getting anything displayed on the std terminal.
You can't open a port on pins 30/31 because it is already open at startup as stdin/stdout. Normally you can "freopen" the stdio port at a different baud rate. Unfortunately the v0_2_2 standard library has a bug in it. We have to post an update to fix it. Please use stdin and stdout as is until we post a new package.
In another post, it was mentioned that their will be a lib provided for making use of the propeller, what sort of functions will be made available. I will keep my misc.h to bare minimum if the "team" is coming up with something better.
The library has not been specified yet. Most likely it will be something like the Arduino library and include missing PBASIC functions. I'm hoping that the library can be an Alpha group effort too, so any common functions that you write may make it into the library.
I am going to do some things with threads, first problem, when I compile the thread example program in the demo folder I get:
thread1.c:23:5: warning: implicit declaration of function 'sleep' [-Wimplicit-function-declaration]
I am assuming that the header file that contains sleep was not included in the program, where is the sleep function?
<edit>
This is the complete error text:
thread1.c:23:5: warning: implicit declaration of function 'sleep' [-Wimplicit-function-declaration]
C:\DOCUME~1\Ray\LOCALS~1\Temp\ccaYo998.o: In function `_main':
(.text+0x134): undefined reference to `_pthread_create'
C:\DOCUME~1\Ray\LOCALS~1\Temp\ccaYo998.o: In function `_main':
(.text+0x16c): undefined reference to `_pthread_join'
collect2: ld returned 1 exit status
Compilation failed.
<edit>
The function "sleep" is defined in unistd.h, so #include <unistd.h>
The pthread library header is pthread.h, so #include <pthread.h>
The pthread library must be linked to your program.
propeller-elf-gcc -o program -Os program.c -lpthread
I highly recommend demos/toggle/pthread_toggle for understanding how to use pthreads.
Below is my interpretation of what I think pthreads is all about. The program compiled, but did not do what I expected. It seemed like the waitMS() had no affect, the LED stayed on, and "Hello, World" was just streaming down the window. I expected "Hello, World" to be displayed every two seconds, and the LED to turn on/off every second. I wonder what could possibly be wrong.
Below is my interpretation of what I think pthreads is all about. The program compiled, but did not do what I expected. It seemed like the waitMS() had no affect, the LED stayed on, and "Hello, World" was just streaming down the window. I expected "Hello, World" to be displayed every two seconds, and the LED to turn on/off every second. I wonder what could possibly be wrong.
I see a few issues:
(1) The call to pthread_create() is incorrect. The first parameter has to be a pointer to a pthread_t object. Try:
(2) I don't see where you're setting the DIRA bits on any of the cogs. In particular I think you'll need to do it in the do_toggle function after the thread affinity locks the thread to a particular cog.
(3) Using waitcnt() to do a blocking wait (as waitMS does) is probably not a good idea with pthreads. A better way to wait is to call sleep() or usleep(), which actually gives up the processor to any other waiting threads. This isn't actually a bug per se, your code should work with waitMS, it's more of a style issue.
When I keypress 'a' I get: "aaaYou pressed 'a' " displayed, plus it gets displayed on the stdin terminal, but has no keyboard interaction, except for the Esc key, when you switch to that window.
Hi Ray,
The consensus is that these strange results are because of the way C handles file streams (a serial port using fopen, fgetc, fputc, etc... using the standard C library is a file).
According to Eric's notes if we read and write a file (FILE *port = fopen(devicestr, "r+");) we must use fflush(port) between the read and the write.
The example below illustrates having a console on P0/1 that echos chars correctly one character at a time.
#include <stdio.h>
#include <unistd.h>
#include <propeller.h>
int main(void)
{
char *serdevice = "SSER:9600,1,0";
/* open a separate port to use for a console */
FILE *port = fopen(serdevice, "r+");
/* set port flag so characters are echoed as they are typed */
port->_flag |= _IOCOOKED;
/* set port to non-buffered so you don't have to press enter */
setvbuf(port, NULL, _IONBF, 0);
fprintf(stdout, "Start echo.\n");
fprintf(port, "Start echo.\n");
while(1)
{
/* get the byte */
int byte = fgetc(port);
/* flush the port after get */
fflush(port);
/* print byte in brackets */
fprintf(port,"[%c]",byte);
/* if byte is an 'a' report it */
if ( byte == 'a')
{
fprintf(port, "You pressed 'a'.\n");
fprintf(stdout, "You pressed 'a'.\n");
}
}
/* close port for good practice */
fclose(port);
return 0;
}
The previous example did not make things better, in fact when I pressed 'a' , I now get four repetitions of 'a', instead of the three that I was getting before. When I moved the fflush(port) to the end of the while function, I started to get some activity. Where the fflush() is placed in the example, I think it is just immediately flushing the buffer, and you have nothing to work with, IMO.
For the example you are using p0,1, on my C3 board I am using p23,22, do the pins have to prepped in some way prior to use? Also, I am not using the -b C3 condition when I do the propeller-load.
The previous example did not make things better, in fact when I pressed 'a' , I now get four repetitions of 'a', instead of the three that I was getting before. When I moved the fflush(port) to the end of the while function, I started to get some activity. Where the fflush() is placed in the example, I think it is just immediately flushing the buffer, and you have nothing to work with, IMO.
For the example you are using p0,1, on my C3 board I am using p23,22, do the pins have to prepped in some way prior to use? Also, I am not using the -b C3 condition when I do the propeller-load.
Ray
Actually I'm using P1 for RX and P0 for TX "SSER:9600,1,0" (SSER:baud,rx,tx). The driver prepares the pins, so don't change DIRA/OUTA for the pins.
The -b c3 flag is only used for xmm and xmmc modes. The cog and lmm modes do not need special treatment for C3 because the default clock setup 80MHz and PLL16x matches C3. Another clock setup like SpinStamp that uses 80MHz and PLL8x would need -b spinstamp for example.
The program works for me as is with propgcc v0_2_1 and v0_2_2. See attachment.
I was just looking at the thumbnail on the previous post, what are all the bracketed chars? If that is considered normal display, then I guess the program is running as expected. I was getting the same thing on my screen, I thought there was something wrong with the program. Will that be the best that we will be able to achieve in screen appearance?
I was just looking at the thumbnail on the previous post, what are all the bracketed chars? If that is considered normal display, then I guess the program is running as expected. I was getting the same thing on my screen, I thought there was something wrong with the program. Will that be the best that we will be able to achieve in screen appearance?
Ray
Hi Ray. The brackets and the character in the middle can be removed.
I was following the lead of the program where you first mentioned too many characters.
For the pthread(), and associated:
usleep() is found, and it works, just have to remember 1000000 = 1 second.
As for pthread, the results are as before, works for the LMM mode, but does not work for XMM, and XMMC mode. Could there be a possibility that my C3 board is bad? But, I can not see how, programs that do not use pthread work in XMM, and XMMC mode.
For the fgetc() and others:
It seems that fflush() is not clearing the port buffer. When I press 'a', with the echo turned off, I still get "aYou pressed 'a'.". I am still using 'fprintf(port, "You pressed 'a'.' command.
As for pthread, the results are as before, works for the LMM mode, but does not work for XMM, and XMMC mode. Could there be a possibility that my C3 board is bad? But, I can not see how, programs that do not use pthread work in XMM, and XMMC mode.
The program below works for me with the new version v0_2_3 posted on propgcc.googlecode.com.
For the fgetc() and others:
It seems that fflush() is not clearing the port buffer. When I press 'a', with the echo turned off, I still get "aYou pressed 'a'.". I am still using 'fprintf(port, "You pressed 'a'.' command.
So you don't want to echo 'a' on the terminal where you type?
In that case you don't want to enable the _IOCOOKED flag.
This program echos "You pressed 'a'." on both windows only if you press 'a'. It will not echo anything else.
/*
* echo.c
*/
#include <stdio.h>
#include <unistd.h>
#include <propeller.h>
int main(void)
{
char *serdevice = "SSER:9600,1,0";
/* open a separate port to use for a console */
FILE *port = fopen(serdevice, "r+");
/* set port to non-buffered so you don't have to press enter */
setvbuf(port, NULL, _IONBF, 0);
fprintf(stdout, "Start echo.\n");
fprintf(port, "Start echo.\n");
while(1)
{
/* get the byte */
int byte = fgetc(port);
/* flush the port after get */
fflush(port);
/* if byte is an 'a' report it */
if ( byte == 'a')
{
fprintf(port, "You pressed 'a'.\n");
fprintf(stdout, "You pressed 'a'.\n");
}
}
/* close port for good practice */
fclose(port);
return 0;
}
Using the compiler flag -Dprintf=__simple_printf causes issues printing from multiple threads because it's "simple."
Please do not use that compiler flag with pthreads programs. Most likely we will never support threads with __simple_printf.
I tried out the new version of propgcc for Windows, and the pthread example that you supplied works as expected. Playing around a bit with threads program I noticed that if you leave the while() in the do_toggle function empty, then the program no longer works as expected. I thought that by having an empty while() in the do_toggle() it would be sufficient to keep the program running.
I am still working with the fgetc() stuff, I am still not getting the results that I am expecting.In fact I will be adding some getc() in a pthread just see what happens.
Speaking of pthreads in order to get more than one pthread working, you would just need another 'pthread_t thr(x);' in order for it to work correctly?
Playing around a bit with threads program I noticed that if you leave the while() in the do_toggle function empty, then the program no longer works as expected. I thought that by having an empty while() in the do_toggle() it would be sufficient to keep the program running.
Can you give an example of the empty while() program and what you expect should happen?
Speaking of pthreads in order to get more than one pthread working, you would just need another 'pthread_t thr(x);' in order for it to work correctly?
Yes. You need a pthread_t variable per thread. In the demos/toggle/pthread_toggle example, an array of pthread_t is used.
Just a note: I think we also need to remember that pthreads is just one way of doing multi processing with PropGCC.
While pthreads gives us the power to have N threads running (N > 8) like in a microprocessor, it has drawbacks. One drawback is lack of determinism when N > 8 (more than one thread per cog for LMM or N > 1 for XMM modes). Determism problems with pthreads will manifest as imprecise waiting with usleep for example, and "somewhat" unpredictable event timing of thread execution (threads are scheduled and run using a queue data structure whose size depends on the number of threads and time to execute depends on the code sizes). Of course this is one reason why Propeller was invented.
PropGCC can also take advantage of Propeller's multi-core determinism of course. The toggle demos show different ways to employ COGs to overcome issues that can be had with pthreads.
So why pthreads then? Pthreads is available for those who need more than COG number of processes running. In the case of LMM, pthreads lets you N*COG threads for solving a computing problem in parallel with all COGs.
Comments
Hi Ray, I've been looking at this today. There are different options to answering this question.
- Create your own batch file that compiles everything
- Use make to manage it (default for geany)
- Have a custom program that knows what to do with your files
Overview of those options:1. Adding multiple files to the command line works fine up to a point and is probably easiest for simple multi-file projects.
Well, the following was a neat idea, but I can't get it to work. Just use the command line.
[You could put "build.bat" in the Geany Build->Set Build Commands "make button" dialog box and use make to build your project. Using the build button would only affect the file shown in the editor.]
Using batch files to compile everything can be overwhelming for big projects. For small projects it's ok. Problem is in understanding all the rules for building and applying the rules, which is kind of like learning how to create make files.
2. Using make and Makefiles is a standard practice and is supported by many IDEs including Geany. We have examples in the demos that show what to do with these. Still, I understand that regular people don't like make files, so this is a non starter for some.
3. Having a custom program that uses built-in rules on files and project properties can be very simple for users, but it may not be the best way to go. I do have some code from a project that can handle most of this although I'm reluctant to go further with it at the moment, but I can experiment a little.
Your on-going support and development question would be best answered by Parallax. I'll invite an answer.
Thanks.
--Steve
Hey Ray -
I'm glad you asked because it gives us an opportunity to start establishing our intent to support Propeller GCC for the long term. In Parallax we've been busy with the timeline and management, but the real effort has come from the team (Erik Smith, Bill Henning, Ken Rose, Charlie Kelly, Jeff Martin, Steve Denson) and a series of volunteers (Dave Hein, David Betz, and others) quite numerous and very important to this project. This year we realized and acted upon the importance of mainstream language support with multi-platform and open-source code base. Propeller GCC is a major, long-term commitment from Parallax. Porting the GCC compiler to Propeller 1 allows us to get familiar with the code base and to start developing new programs and community acceptance around it, while having the added benefit of preparing the development team for Propeller 2. The investment here is very significant in terms of cost and time, and you should feel comfortable putting your time into using our C tools for the long term. The same team who developed the tools will also maintain them for the long term. And if they are unable to do so for some reason we've got an open-source code base from professional developers that could be maintained by others. That's why our team is much larger than a few people. Although [in my view] it took skilled developers to do the kernel, GCC port and Eclipse GUI, the resultant code base is far more accessible for change than if it were done by a small team or a single person. It is our policy to provide long-term support for Propeller GCC, just to be clear.
If you are interested in C from the standpoint of learning a new skill you will have our support (via learn.parallax.com) and many code examples. Learn.parallax.com is being launched with Spin, but you'll see C examples side by side. In fact, this same portal will also have PBASIC and Arduino C examples. You'll see Propeller C in the KickStart examples, too.
Spin shall grow and is the language presently used in all of the higher-volume commercially-available products based on the Propeller. These same customers expect to have Spin support in Propeller 2, with some level of code compatibility. The recent focus on C is because of business timing and preparations for Propeller 2. Remember, we've been here for 22 years and we're in business for the long-term - being quiet on Spin improvements for the last year should have no bearing on what lies ahead. Since you asked, however, Chip plans on writing "an awesome Spin interpreter" for Propeller 2. Also, remember not to overlook the compiler port from X86 to C/C++ which finally allows Spin improvements.
From a PC development tool standpoint, the likely evolution for Spin is that we will adopt an existing open-source alternative presently available for Propeller 1 and 2 support, and that Eclipse will be used for Propeller-GCC for Propeller 1 and 2. It is not clear that the two languages will be able to live and peacefully co-exist in the same world (please don't open this up as a discussion, at least in this thread). We are currently evaluating choices for the future Spin development environment.
Sincerely,
Ken Gracey
The program below, I am trying to capture a keypress, and display it on the local terminal. The program does not compile, and it displays these errors:
fds5.c:19:34: error: macro "getchar" passed 1 arguments, but takes just 0
fds5.c:19:22: warning: initialization makes integer from pointer without a cast [enabled by default]
For this piece of code I would like to see the keypress on the external terminal be displayed on the local terminal. The next thing would be to have a specific keypress on the external terminal turn on/off an LED on the C3 board.
Ray
Ray
Hi Ray,
As Dave Hein mentioned we have to press "enter" after input with the standard library I/O - that is, by default the serial streams are buffered.
There is a way to change the default behavior to receive and echo characters as they are typed. This program works perfectly for me either buffered or unbuffered in windows. I use PST for the port on P0/1 and have preferences set with New Line checked and Line Feed not checked. I've used baud rates from 9600 to 115200.
Interestingly the program is 8KB regardless of using -Dprintf=__simple_printf or not. If we used a different custom driver for the separate serial port, the program would be much bigger.
Ray
Your code doesn't fetch characters from the terminal on P23,22.
There is a problem though. If I use this program it works mostly.
I changed fgetc(stdin) to fgetc(port) and added "setvbuf(port, NULL, _IONBF, 0);".
This makes the input from "port" and unbuffered.
Not sure at this point why it would be necessary to make port unbuffered.
Looks like a bug to me.
Does the stdin terminal have any cursor movement control commands? I suppose it would also be nice to add some color.
Ray
I've seen something like this "aaaYou pressed 'a'" thing, and sent a note out to the team this morning. Haven't heard back yet.
The propeller-gcc terminal has no bells and whistles. Another terminal program must be used for cursor movement and colors.
In another post, it was mentioned that their will be a lib provided for making use of the propeller, what sort of functions will be made available. I will keep my misc.h to bare minimum if the "team" is coming up with something better.
Ray
The library has not been specified yet. Most likely it will be something like the Arduino library and include missing PBASIC functions. I'm hoping that the library can be an Alpha group effort too, so any common functions that you write may make it into the library.
thread1.c:23:5: warning: implicit declaration of function 'sleep' [-Wimplicit-function-declaration]
I am assuming that the header file that contains sleep was not included in the program, where is the sleep function?
<edit>
This is the complete error text:
thread1.c:23:5: warning: implicit declaration of function 'sleep' [-Wimplicit-function-declaration]
C:\DOCUME~1\Ray\LOCALS~1\Temp\ccaYo998.o: In function `_main':
(.text+0x134): undefined reference to `_pthread_create'
C:\DOCUME~1\Ray\LOCALS~1\Temp\ccaYo998.o: In function `_main':
(.text+0x16c): undefined reference to `_pthread_join'
collect2: ld returned 1 exit status
Compilation failed.
<edit>
Ray
The function "sleep" is defined in unistd.h, so #include <unistd.h>
The pthread library header is pthread.h, so #include <pthread.h>
The pthread library must be linked to your program.
propeller-elf-gcc -o program -Os program.c -lpthread
I highly recommend demos/toggle/pthread_toggle for understanding how to use pthreads.
Ray
I see a few issues:
(1) The call to pthread_create() is incorrect. The first parameter has to be a pointer to a pthread_t object. Try: instead.
(2) I don't see where you're setting the DIRA bits on any of the cogs. In particular I think you'll need to do it in the do_toggle function after the thread affinity locks the thread to a particular cog.
(3) Using waitcnt() to do a blocking wait (as waitMS does) is probably not a good idea with pthreads. A better way to wait is to call sleep() or usleep(), which actually gives up the processor to any other waiting threads. This isn't actually a bug per se, your code should work with waitMS, it's more of a style issue.
Eric
Hi Ray,
The consensus is that these strange results are because of the way C handles file streams (a serial port using fopen, fgetc, fputc, etc... using the standard C library is a file).
According to Eric's notes if we read and write a file (FILE *port = fopen(devicestr, "r+");) we must use fflush(port) between the read and the write.
The example below illustrates having a console on P0/1 that echos chars correctly one character at a time.
For the example you are using p0,1, on my C3 board I am using p23,22, do the pins have to prepped in some way prior to use? Also, I am not using the -b C3 condition when I do the propeller-load.
Ray
Actually I'm using P1 for RX and P0 for TX "SSER:9600,1,0" (SSER:baud,rx,tx). The driver prepares the pins, so don't change DIRA/OUTA for the pins.
The -b c3 flag is only used for xmm and xmmc modes. The cog and lmm modes do not need special treatment for C3 because the default clock setup 80MHz and PLL16x matches C3. Another clock setup like SpinStamp that uses 80MHz and PLL8x would need -b spinstamp for example.
The program works for me as is with propgcc v0_2_1 and v0_2_2. See attachment.
Ray
Hi Ray. The brackets and the character in the middle can be removed.
I was following the lead of the program where you first mentioned too many characters.
Ray
"You pressed 'a'." shows up on the propeller-load terminal.
It also shows up on the second "port" terminal (my PST window).
To remove brackets, delete/comment the fprintf line:
/* print byte in brackets */
// fprintf(port,"[%c]",byte);
usleep() is found, and it works, just have to remember 1000000 = 1 second.
As for pthread, the results are as before, works for the LMM mode, but does not work for XMM, and XMMC mode. Could there be a possibility that my C3 board is bad? But, I can not see how, programs that do not use pthread work in XMM, and XMMC mode.
For the fgetc() and others:
It seems that fflush() is not clearing the port buffer. When I press 'a', with the echo turned off, I still get "aYou pressed 'a'.". I am still using 'fprintf(port, "You pressed 'a'.' command.
Ray
The program below works for me with the new version v0_2_3 posted on propgcc.googlecode.com.
Build with one of these:
propeller-elf-gcc -o threads -Os -Wall threads1.c -lpthread -s
propeller-elf-gcc -o threads -mxmm -Os -Wall threads1.c -lpthread -s
propeller-elf-gcc -o threads -mxmmc -Os -Wall threads1.c -lpthread -s
Load with this:
propeller-load -r -t threads -b c3
So you don't want to echo 'a' on the terminal where you type?
In that case you don't want to enable the _IOCOOKED flag.
This program echos "You pressed 'a'." on both windows only if you press 'a'. It will not echo anything else.
Please do not use that compiler flag with pthreads programs. Most likely we will never support threads with __simple_printf.
Using normal printf works fine with pthreads.
I am still working with the fgetc() stuff, I am still not getting the results that I am expecting.In fact I will be adding some getc() in a pthread just see what happens.
Speaking of pthreads in order to get more than one pthread working, you would just need another 'pthread_t thr(x);' in order for it to work correctly?
Ray
Can you give an example of the empty while() program and what you expect should happen?
Yes. You need a pthread_t variable per thread. In the demos/toggle/pthread_toggle example, an array of pthread_t is used.
Just a note: I think we also need to remember that pthreads is just one way of doing multi processing with PropGCC.
While pthreads gives us the power to have N threads running (N > 8) like in a microprocessor, it has drawbacks. One drawback is lack of determinism when N > 8 (more than one thread per cog for LMM or N > 1 for XMM modes). Determism problems with pthreads will manifest as imprecise waiting with usleep for example, and "somewhat" unpredictable event timing of thread execution (threads are scheduled and run using a queue data structure whose size depends on the number of threads and time to execute depends on the code sizes). Of course this is one reason why Propeller was invented.
PropGCC can also take advantage of Propeller's multi-core determinism of course. The toggle demos show different ways to employ COGs to overcome issues that can be had with pthreads.
So why pthreads then? Pthreads is available for those who need more than COG number of processes running. In the case of LMM, pthreads lets you N*COG threads for solving a computing problem in parallel with all COGs.
Ray
propeller-elf-gcc -o thread1 -mxmmc -Os -Wall thread1.c -lpthread -s
propeller-load -r -t thread1 -b C3