Show Posts
Pages: [1] 2
1  Development / Other Software Development / Re: New FreeRTOS and ChibiOS/RT real time operating system libraries on: December 22, 2012, 08:25:34 pm
Thanks.  Regarding the cbSysInit() I'm initializing the memory pool, mailbox, and tasks after this call so it should be OK. 

I've swapped the chPoolInit() for the for loop.  No difference in operation.

The oddness is that I have to prime the Mailbox with a post in setup() to get things to work.  If I leave this out, the LCD thread does not seem to wake up.

Github is down right now, so I'm unable to look at some of the other examples.  From memory though, I don't recall them having to do this.

I'll keep twiddling with it.  I will likely add a few interrupts to the mix as well which will kick the tasks off.  I'll let you know if I find anything else.

Oh, and thanks again for the port.  Happy Holidays!
2  Development / Other Software Development / Re: SoftwareSerial magic numbers on: December 22, 2012, 02:13:48 pm
@robtillaart,

Noob question, but what's the reason for these values in SoftwareSerial? 

Obviously, less memory usage is a good thing. smiley
3  Development / Other Software Development / Re: New FreeRTOS and ChibiOS/RT real time operating system libraries on: December 22, 2012, 02:08:51 pm
Has anyone tried to use Memory Pools and Mailboxes in this port?  Here's my two questions:

1) I'm seeing some odd behavior in the mailboxes, particularly in the first pull from the mailbox.  The data of the object pulled seems corrupted though I suspect it's some header information.  Likely pilot error. 

2) Also seeing "junk" at the top of every memory pool item allocated.  Again, I think from reading the ChibiOS forums and documentation I think this is the pool header though some examples on the ChibiOS forums do not show this needing to be exlicitly defined in the memory structure.

Here's the code in question.  Two small tasks delaying a second each, posting to the mailbox a seconds counter, and a third task picking it up and displaying it on an LCD.  Pretty simple stuff.  Notice I do a bit of error checking on the content to weed out the first mailbox data error.

Here's the structure definition for the mailbox/mempool data:
Code:

typedef struct {
int junk;
int thread;
unsigned long cnt;
} msgLCD;


Here's the RTOS code.  Did not include header info and support functions to keep it short.:
Code:
#define MB_SIZE 6

#define TEAM_A_TITLE_LOC 0
#define TEAM_B_TITLE_LOC 16
#define TEAM_A_TITLE "Time A"
#define TEAM_B_TITLE "Time B"
#define TEAM_A_TIMER_H 7
#define TEAM_B_TIMER_H 16+TEAM_A_TIMER_H
#define TEAM_A_TIMER_M 10
#define TEAM_B_TIMER_M 16+TEAM_A_TIMER_M
#define TEAM_A_TIMER_S 13
#define TEAM_B_TIMER_S 16+TEAM_A_TIMER_S

#define ACTIVE_TEAM_A_LOC 15
#define ACTIVE_TEAM_B_LOC 16+ACTIVE_TEAM_A_LOC
#define ACTIVE_TEAM_INDICATOR "<"

const uint8_t LED_PIN = 13;
//const uint8_t servo_PIN = 9;

//Servo myServo;

SoftwareSerial mainLCD(2, 3);

static char buffer[sizeof(msgLCD)*MB_SIZE];

//MemoryPool pool;

static MEMORYPOOL_DECL(pool, sizeof(msgLCD)*MB_SIZE, NULL);
static MAILBOX_DECL(mbox, buffer, sizeof(buffer));


// align data, this depends on your compiler. this works for GCC
msgLCD data[MB_SIZE] __attribute__((aligned(sizeof(stkalign_t))));


String formatTwoDigits(unsigned int iVal) {
  String sTens = "";
  sTens += iVal / 10;
  String sOnes = "";
  sOnes += iVal % 10;
  return sTens+sOnes;
}

void printTime(unsigned int h, unsigned int m, unsigned int s, int team) {
int rowLoc = TEAM_A_TIMER_H;

if (team == 2) {
rowLoc = TEAM_B_TIMER_H;
}
setLCDCursor(&mainLCD, rowLoc);
mainLCD.print(formatTwoDigits(h));
mainLCD.print(":");
mainLCD.print(formatTwoDigits(m));
mainLCD.print(":");
mainLCD.print(formatTwoDigits(s));
}

//------------------------------------------------------------------------------
// Simulated Worker Thread 1
static WORKING_AREA(waThread1, 64);

static msg_t Thread1(void *arg) {

int counter = 0;
while (TRUE) {
    chThdSleepMilliseconds(1000);
    counter++;

    //grab a memory pool item
    msgLCD *msg = (msgLCD *)chPoolAlloc(&pool);
    if (msg != NULL) {
    msg->thread = 1;
    msg->cnt = counter;
    // Here we'll send something to the LCD thread
    chMBPost(&mbox, (msg_t)msg, TIME_INFINITE);
    }
}
return 0;
}

//------------------------------------------------------------------------------
// Simulated Worker Thread 2
static WORKING_AREA(waThread2, 64);

static msg_t Thread2(void *arg) {
int counter = 0;
while (TRUE) {
    chThdSleepMilliseconds(1000);
    counter++;

    //grab a memory pool item
    msgLCD *msg = (msgLCD *)chPoolAlloc(&pool);
    if (msg != NULL) {
    msg->thread = 2;
    msg->cnt = counter;
    // Here we'll send something to the LCD thread
    chMBPost(&mbox, (msg_t)msg, TIME_INFINITE);
    }
}
return 0;
}

//------------------------------------------------------------------------------
// LCD Thread - This thread waits on a Mailbox (FIFO Queue) and depending on who
// sent the message, displays in the proper quadrant of the LCD
static WORKING_AREA(waLCDThread, 64);

static msg_t LCDThread(void *arg) {
msg_t msg1;
msgLCD msg2;
unsigned int teamA_h = 0, teamA_m = 0, teamA_s = 0;
unsigned int teamB_h = 0, teamB_m = 0, teamB_s = 0;

static boolean t1s = FALSE;
static boolean t2s = FALSE;
static boolean LED_state = FALSE;

clearDisplay(&mainLCD);

setLCDCursor(&mainLCD, TEAM_A_TITLE_LOC);
mainLCD.print(TEAM_A_TITLE);
setLCDCursor(&mainLCD, TEAM_A_TIMER_H);
mainLCD.print("00:00:00");

setLCDCursor(&mainLCD, TEAM_B_TITLE_LOC);
mainLCD.print(TEAM_B_TITLE);
setLCDCursor(&mainLCD, TEAM_B_TIMER_H);
mainLCD.print("00:00:00");

while (TRUE) {

// Wait on a message from the working threads to display
msg1 = chMBFetch(&mbox, (msg_t *)&msg2, TIME_INFINITE);

if (msg1 == RDY_OK) {
LED_state = !LED_state;
digitalWrite(LED_PIN, LED_state);
// If we get here, we have a message

if (msg2.thread == 1) {
setLCDCursor(&mainLCD, TEAM_A_TIMER_H);
t1s = !t1s;
teamA_h = msg2.cnt / 3600;
teamA_m = (msg2.cnt % 3600) / 60;
teamA_s = msg2.cnt % 60;

printTime(teamA_h, teamA_m, teamA_s, msg2.thread);

}
if (msg2.thread == 2) {
setLCDCursor(&mainLCD, TEAM_B_TIMER_H);
t2s = !t2s;
teamB_h = msg2.cnt / 3600;
teamB_m = (msg2.cnt % 3600) / 60;
teamB_s = msg2.cnt % 60;
printTime(teamB_h, teamB_m, teamB_s, msg2.thread);
}
} else {
Serial.print("Fetch Status: ");
Serial.println(msg1);
}
// Now we have to free the memory pool object
chPoolFree(&pool, (void *)&msg2);

}
return 0;
}
//------------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
  mainLCD.begin(9600);
  pinMode(LED_PIN, OUTPUT);

//  myServo.attach(servo_PIN);
//  myServo.write(10);
  chThdSleepMilliseconds(15);


  // Here we can muck with the LCD because nothing in the RTOS system is initialized
  clearDisplay(&mainLCD);
  setLCDCursor(&mainLCD, 2);  // Set cursor to the 3rd spot, 1st line
  mainLCD.print("Initializing");
  setLCDCursor(&mainLCD, 16);  // Set the cursor to the beginning of the 2nd line
  mainLCD.print("RTOS System...");

  // From here on, only the LCD thread should handle this hardware.

  halInit();
  chSysInit();

  // add each element to the pool
  // this is the least obvious part of the process, as far as my experience went

  for(int i=0; i <= MB_SIZE; i++) {
      chPoolFree(&pool, &data[i]);
  }

  //Initialize the mailbox
  chMBInit(&mbox, (msg_t *)buffer, MB_SIZE);
  chMBReset(&mbox);
  delay(2000);

  msg_t msg1;

  msgLCD msg, msg2;

  chMBPost(&mbox, (msg_t)&msg, TIME_INFINITE);
  chMBPost(&mbox, (msg_t)&msg2, TIME_INFINITE);

  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO + 2, Thread1, NULL);
  chThdCreateStatic(waThread2, sizeof(waThread2), NORMALPRIO + 1, Thread2, NULL);
  chThdCreateStatic(waLCDThread, sizeof(waLCDThread), NORMALPRIO + 3, LCDThread, NULL);

  while(TRUE){}
}
void loop() {
  // never called
}

4  Community / Exhibition / Gallery / Re: Arduino + FreeRTOS + C++ = Platform for Teaching Real-Time Software Design on: August 28, 2012, 09:23:03 pm
Chip,

Good stuff!  I was brought up in the embedded world back in the 80's and think interrupts vs. polling loops.  I've always been surprised how small an RTOS can be to fit into a microprocessor.  You really don't need much.

I'm working on a project now that involves a few serial devices (XBee being one) and would love to try it out after I get the initial design in place.  Keep up the good work!
5  Development / Other Software Development / Re: ChibiOS/RT 2.2.8 RTOS update on: February 20, 2012, 07:57:38 pm
Looks like ChibiOS was updated on 2/5 to v2.4.0.

How hard was it to port the 2.2.8 version?
6  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: January 22, 2011, 07:17:35 pm
I've tested semaphores being set via interrupts on Arduino v22.

Note the hardware directory is a little different but seems to compile, load, and run correctly.

Does it makes sense for someone to put a regression test outline on the Google project site?  The thought here is if we have various parties checking off a known set of previously supported features, we can move the process along.  

Also, if there were a list of unresolved and untested subsystems, those interested could work on those as needed and contribute to the project.

Thoughts?
7  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: December 19, 2010, 06:10:55 pm
That's great news!  

Are the incompatibilities here still an issue?

http://www.multiplo.org/duinos/wiki/index.php?title=Tracker#Incompatibility_issues_with_Arduino_libraries

8  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: October 31, 2010, 07:08:38 pm
Thanks.

Saw you were working on v0.3.  Any ETA on that?  Need help testing?
9  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: October 30, 2010, 09:52:00 pm
Julian,

I'm getting back into some Arduino/DuinOS coding after some time off and was wondering if the latest DuinOS rev is compatible with the latest Arduino build (21).  

Thanks.
10  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: March 31, 2010, 07:42:56 pm
Julian,

Is this fork going to be the start of your next rev?  Any news on when that will be?
11  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: February 08, 2010, 05:39:23 pm
I vote for getting v.02 out ASAP.  That way we can start debugging it and hopefully get those fixes in the next rev that will support the new version of Arduino.
12  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: February 07, 2010, 07:32:33 pm
Julian,

Any ETA on the next update?  What did you decide to do regarding the next major rev?

FYI, I'm working on a project that has sockets via WiFi.  Once I get the hardware in place I'll test DuinOS out with it.
13  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: January 10, 2010, 07:02:59 pm
Julian,

I'd go ahead and post your next release now.  At least it will help those just starting out with it to avoid the issues to date and could provide more testing.

14  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: January 08, 2010, 03:11:46 am
Julian, any ETA on v 0.02?
15  Forum 2005-2010 (read only) / News / Re: DuinOS: small and simple rtos on: December 31, 2009, 10:27:12 pm
Julian,

Thanks for the detailed code review.  smiley 

I think I mentioned before that I'm an old time (mid-80's) RTOS programmer who's used to preemptive multitasking and interrupts in the code I wrote.  That being said, I'm just getting my feet wet again after about 15 years being away from it and I appreciate what you're doing to ease the transition.  As Chumbud points out, it will help those who need their Arduino projects to "do more" once they're ready.

I did have a few questions/comments:

I.  My original code had the semaphore being posted from an ISR.  The FreeRTOS API reference recommends against a mutex in an ISR.  Will this still work?  I think the benefit of an RTOS is combining interrupts with tasks to optimize the CPU.

II. Your details about differences are important.  I used the FreeRTOS as a guide and found the creation of the semaphore in the task.  Since it's in a loop then your right that trying to create it a second time probably whacked out the queuing and ultimately the context switch.  Might be worth browsing through the API on FreeRTOS and noting any other differences.

III. As mentioned, my original code had an ISR and the protection of the resource was the intent.  In the example posted, I was more using the semaphore as a task synchronization mechanism.   Is this valid between two tasks?  I got the impression in the FreeRTOS docs that it was.

Thanks for the new sample code.  I'll load it up and give it a try.  I will also try it with an ISR to see how well that works.  I'll let you know what I find.  Looking forward to 0.2!!
Pages: [1] 2