Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by Pavel

  1. This code uses Novo RTOS and because of this needs -swcs linker command line argument. Please make sure you have it or you will see all kind of strange problems. Regards, Pavel
  2. We will investigate though SourceBoost runs fine in our environment under Vista. Are you able to run just the compilers included into SourceBoost installation? If anybody had this problem and managed to fix it please post here (or send a mail to support@sourceboost.com) Here is a free tool that might help. It analyses application dependencies and shows them in a form of a tree. It can be downloaded from http://www.dependencywalker.com/. If you experience SourceBoost IDE crash under Vista please check the ide.exe file (that is the SourceBoost IDE main file that can be found in your SourceBoost installation directory) using this tool and post the results here. Regards, Pavel
  3. Below is a sample code that will appear in the next SourceBoost release. It shows how Novo can handle serial port. Please use it as a reference. Don't forget to add -swcs to linker command line Regards, Pavel /******************************************************************** BoostC/BoostC++ sample code for Microchip "PICDEM HPC Explorer Board" Part Number: DM183022 Asynchronous UART and Novo RTOS This code uses Novo RTOS and shows how to use interrupts to receive and transmit serial data and how to safely share this data with tasks. Two tasks are implemented: - one task runs every second and updates port D connected to 8 LEDs - another task waits for data from UART, than transforms it and sends back Receive buffer uses counting semaphore to indicate data availability so that tasks waiting for data will yield if data is not available. BoostC/BoostC++ compilers are available from www.sourceboost.com Author(s) Pavel Baranov Copyright(C) 2009 Pavel Baranov This code can be used free of charge in both commercial and non-commercial projects as long as this copyright notice and this entire statement is left unchanged. This software is provided "as is", without warranty of any kind. ********************************************************************/ //System headers #include <system.h> #include <novocfg_pic18t3e5ts1.h> #include <novo.h> //Target PIC18F8722 configuration word #pragma DATA _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L #pragma DATA _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H #pragma DATA _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L #pragma DATA _CONFIG1H, _FCMEN_OFF_1H & _OSC_HS_1H //Set clock frequency #pragma CLOCK_FREQ 10000000 //Novo tasks #define hTask0 0 #define hTask1 1 //Novo semaphores #define hRxSem 0 //LED counter static unsigned char led = 0; //UART Tx and Rx data #define TX_BUFFER_SIZE 8 #define RX_BUFFER_SIZE 16 static unsigned char TxBuffer[TX_BUFFER_SIZE], txHead, txTail; static unsigned char RxBuffer[RX_BUFFER_SIZE], rxHead, rxTail; //Port settings #define USE_PORT_0 #if defined USE_PORT_0 #define TX_IRQ_FLAG pir1.TX1IF #define RX_IRQ_FLAG pir1.RC1IF #define TX_IRQ_ENABLE pie1.TX1IE #define RX_IRQ_ENABLE pie1.RC1IE #define TX_IRQ_PRIO ipr1.TXIP #define RX_IRQ_PRIO ipr1.RCIP #define TX_ENABLE txsta.TXEN #define RX_ENABLE rcsta.CREN #define UART_TX_END txsta.TRMT #define UART_ENABLE rcsta.SPEN #define UART_EVERFLOW_ERR rcsta.OERR #define UART_FRAME_ERR rcsta.FERR #define UART_BRG_HIGH_SPEED txsta.BRGH #define UART_BRG spbrg #define UART_TX_REG txreg1 #define UART_RX_REG rcreg1 #elif defined USE_PORT_1 #define TX_IRQ_FLAG pir3.TX2IF #define RX_IRQ_FLAG pir3.RC2IF #define TX_IRQ_ENABLE pie3.TX2IE #define RX_IRQ_ENABLE pie3.RC2IE #define TX_IRQ_PRIO ipr3.TXIP #define RX_IRQ_PRIO ipr3.RCIP #define TX_ENABLE txsta2.TXEN #define RX_ENABLE rcsta2.CREN #define UART_TX_END txsta2.TRMT #define UART_ENABLE rcsta2.SPEN #define UART_EVERFLOW_ERR rcsta2.OERR #define UART_FRAME_ERR rcsta2.FERR #define UART_BRG_HIGH_SPEED txsta2.BRGH #define UART_BRG spbrg2 #define UART_TX_REG txreg2 #define UART_RX_REG rcreg2 #else #error "Error: unsupported port selected" #endif ////////////////////////////////////////////// // High priority interrupt handles // handles system time ////////////////////////////////////////////// void interrupt( void ) { //Handle timer0 interrupt if( intcon.T0IF ) { // update system time every 1s static unsigned char nDivider = 0; if( 39 == ++nDivider ) { nDivider = 0; SysTimerUpdate(); } clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit } } ////////////////////////////////////////////// // Low priority interrupt handles // handles UART send and receive ////////////////////////////////////////////// void interrupt_low( void ) { //Handle UART transmit if( TX_IRQ_FLAG ) { //Check if there is data in transmit buffer if( txHead != txTail ) { UART_TX_REG = TxBuffer[txTail++]; if( TX_BUFFER_SIZE == txTail ) txTail = 0; } else { //Nothing to send, disable Tx irq //but only after the last bit from //prev transmission is out while( !UART_TX_END ); TX_ENABLE = 0; } } //Handle UART receive if( RX_IRQ_FLAG ) { //Test for errors first if( UART_EVERFLOW_ERR ) //overflow error { //read and discard incoming byte unsigned char discard = UART_RX_REG; } else if( UART_FRAME_ERR ) //frame error { //restart Rx to clear this error RX_ENABLE = 0; RX_ENABLE = 1; } else { //Check if there is free space in receive buffer BYTE cnt = SysReadSemaphore( hRxSem ); if( cnt < RX_BUFFER_SIZE ) { //Write incoming byte into the buffer and increment Rx semaphore RxBuffer[rxHead++] = UART_RX_REG; if( RX_BUFFER_SIZE == rxHead ) rxHead = 0; SysSignalSemaphoreIsr( hRxSem ); } else { //Buffer overflow, the incoming byte will be lost unsigned char discard = UART_RX_REG; } } } } ////////////////////////////////////////////// //Receive one byte from serial port ////////////////////////////////////////////// unsigned char Rx( void ) { //Wait for serial data to come Sys_WaitSemaphore( hRxSem, EVENT_NO_TIMEOUT ); //Read one byte from rx queue SysCriticalSectionBegin(); unsigned char data = RxBuffer[rxTail++]; if( RX_BUFFER_SIZE == rxTail ) rxTail = 0; SysCriticalSectionEnd(); return data; } ////////////////////////////////////////////// //Send one byte into serial port ////////////////////////////////////////////// void Tx( unsigned char data ) { //Put data into the rx queue SysCriticalSectionBegin(); TxBuffer[txHead++] = data; if( TX_BUFFER_SIZE == txHead ) txHead = 0; TX_ENABLE = 1; //enable Tx SysCriticalSectionEnd(); } ////////////////////////////////////////////// //Send a string into serial port ////////////////////////////////////////////// void Tx( char * text ) { while( *text ) Tx( *text++ ); } ////////////////////////////////////////////// // Task that processes UART data ////////////////////////////////////////////// void Task0() { //Send out hello string (string should fit into the tx buffer) Tx( "Ready..." ); //This tack will receive data, transform it and send back while( 1 ) { //Wait for serial data to come. This is a blocking //call that will yield if no data is available unsigned char data = Rx(); //If this is lover case character convert it to capital if( data >= 'a' && data <= 'z' ) data -= 'a' - 'A'; //Send data back Tx( data ); } } ////////////////////////////////////////////// // Task that every second flashes a LED ////////////////////////////////////////////// void Task1() { //Update LEDs connected to port D every second while( 1 ) { latd = ++led; Sys_Sleep( 1 ); } } ////////////////////////////////////////////// // Program entry point ////////////////////////////////////////////// void main( void ) { //Disable watchdog wdtcon.SWDTEN = 0; //Configure port A trisa = 0x00; //Configure port B trisb = 0x00; //Configure port C trisc = 0x00; //Configure port D trisd = 0x00; //Initialize port A porta = 0x00; //Initialize port B portb = 0x00; //Initialize port C portc = 0x00; //Initialize port D portd = 0x00; //Set Timer0 mode set_bit( t0con, TMR0ON ); //enable timer0 clear_bit( t0con, T0CS ); //configure timer0 as a timer //Set Timer0 resolution set_bit( t0con, T08BIT ); //set timer0 8 bit wide //Set prescaler assignment clear_bit( t0con, PSA ); //prescaler is assigned //Set prescaler rate set_bit( t0con, T0PS2 ); //prescaler rate 1:256 set_bit( t0con, T0PS1 ); set_bit( t0con, T0PS0 ); //Set timer0 source edge selection set_bit( t0con, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin //Configure serial port RX_IRQ_PRIO = TX_IRQ_PRIO = 0; //use low priority interrupt UART_BRG_HIGH_SPEED = 1; //high speed UART_BRG = 64; //9600kbps/10Mhz RX_IRQ_ENABLE = 1; //enable Rx irq TX_IRQ_ENABLE = 1; //enable Tx irq RX_ENABLE = 1; //enable continuous receive UART_ENABLE = 1; //enable serial port //Configure UART pins #if defined USE_PORT_0 trisc.7 = 1; trisc.6 = 0; #elif defined USE_PORT_1 trisg.2 = 1; trisg.1 = 0; #endif //Configure interrupts rcon.IPEN = 1; //enable priority level interrupts intcon.TMR0IE = 1; //enable timer 0 interrupt intcon.GIEH = intcon.GIEL = 1; //Enable hign and low priority interruptr //Initialize Novo RTOS SysInit(); //Create Novo tasks SysCreateTask( hTask0, 2, Task0 ); SysCreateTask( hTask1, 2, Task1 ); //Start Novo tasks SysStartTask( hTask0 ); SysStartTask( hTask1 ); //Endless loop while( 1 ) Sys_Yield(); } // End of code
  4. Intergally goodies use plain windows file API to store unpacked files. The only problem under Vista I can think of is when you run goodies as a user that does not have administrator privileges. For such users all directories in program files folder are write protected and goodies won't be able to write files there. The solution is to run goodies being logged in as administrator. Regards, Pavel
  5. There is no way to get address of a function at run time. I suggest to use fixed addresses for functions you want to modify: void foo() @ 0x100 //this function will start at address 0x100 { } Regards, Pavel
  6. Fixed. Fix will be available in the next release. Thanks for reporting. Regards, Pavel
  7. Your code is correct from language point of view but it relies on the assumption that function pointer value should be equal to the function code address in code memory. This is not the case. PIC architecture doesn't allow to use absolute function addresses. To overcome this limitation compiler uses function ordinals that are assigned at link time and builds jump table that uses these ordinals to rout code execution to the correct place. The values 1 and 2 are ordinals of the functions InitCapture and ClearRDSState from your code. Regards, Pavel
  8. This is problem with your code. Compiler behaves correctly. Your code uses function pointer values instead of calling them. Regards, Pavel
  9. You need to declare ucData global. Linker allocates space for function arguments and these locations are not known at compile time. Regards, Pavel
  10. there should be a semicolon after while(1) i guess It looks like semicolon after while(1) is a mistake and shouldn't be there. If it is intended than the code alignment after it looks at least strange. Why enclose it into curly braces? And why use it at all? It will never get reached since the code will loop around the semicolon forever Pavel
  11. Sorry but that is not true. 1. For Task2 I initialise the hTestRun semaphore in the main(). I incremented 10 times this semaphore in order for Task 2 to run 10 iteractions. ... hTestRun is initialised only if TESTMODE is defined. But your original post you did not say that TESTMODE is defined and code that you posted doesn't define it either. Pavel
  12. SourceBoost does not support extended instruction set (neither compilers not the sim/debugger). Regards, Pavel
  13. In all your tasks you wait for different semaphores but there is no code that signals them. Your tasks must be stuck waiting for these semaphores that never get signalled. Regards, Pavel
  14. This is not a compiler but language feature. None of the C compilers will support this. If function body is in a header than this header is used only with one source file or this is an inline function or a function template. Regards, Pavel
  15. OK, but the o.bj files are compiled to the project directory, so i shouldn't be a problem. If all obj files are in the project directory than linker will find them. But does that means I have to compile *.c files or the *.pp files? When compiling the *.c files I get the error about redefining functions. So it didn't get notice about the #ifndef in Standard_Functions.h. When compiling the *.pp files I get the error: Couldn't find function/label by name:main Baga You compile C files. Preprocessing is done behind the scenes by compiler. The rule about functions is your declare the in header (H) files and define (add body) in just one of source © files. Exceptions to this rule are inline functions and function templates. Regards, Pavel
  16. No it doesn't. Linker complains while processing main.obj. It will complain though when it gets to obj files that are in different directories. That happens because of the bug in IDE toolsuite that doesn't process obj files from different than project directory correctly (this problem has been fixed and update will be available really soon). The error you see seems to be related to functions that have more than one body. No. PP is invoked by compiler. Regards, Pavel
  17. Here is what I'd do. Compile/link same project under SourceBoost IDE. If you get same build errors the problem is in your code. If everything builds fine than problem is in your Eclipse set up. This will indicate where to look further. Pavel
  18. Than something else in yur setup must be wrong. Including path with spaces into double quotes is the way how windows works. I also tried your options and could not reproduce the problem. They work just fine: "C:\Program Files\SourceBoost\boostc.pic16.exe" -t PIC16F648A -O2 -I ..\..\modbus\rtu;..\..\modbus\include;port;"C:\Program Files\SourceBoost\include" test.c "..\My Documents\Test\timer.c" BoostC Optimizing C Compiler Version 6.95 (for PIC16 architecture) http://www.sourceboost.com Copyright(C) 2004-2009 Pavel Baranov Copyright(C) 2004-2009 David Hobday Licensed to Pavel Baranov under Single user Pro License for 1 node(s) Limitations: PIC12,PIC16 max code size:Unlimited, max RAM banks:Unlimited test.c ..\My Documents\Test\timer.c success Done Regards, Pavel
  19. Add -v into compiler command line and it will print preprocessor command line in its output. Regards, Pavel
  20. Not an error. Remember that strings include trailing zero. Your buffer is only 4 bytes long and trailing zero gets written past it where another variable is located. Regards, Pavel
  21. I stepped trough assembly generated by this code but could not spot any errors. Regards, Pavel
  22. Pavel


    We have modified compiler to provide better error reporting for cases like this. This update will be available in the next release. Regards, Pavel
  23. This is not a bug but done by design. Pavel
  24. BoostC does support function pointer typedefs. In this particular case because both pointers have same signature compiler wasn't adding the second typedef to its internal lists. This is now fixed and fix will be available in the next release. Thanks for reporting. Regards, Pavel
  • Create New...