#define PRIOR_LOW 20
#define THREAD_SHARED 0
-#define INIT_VALUE 0 /*init value for semaphor*/
+#define INIT_VALUE 1 /*init value for semaphor*/
#define PXMC_SIN_FIX_TAB_BITS 9
#define NSEC_PER_SEC (1000000000) /* The number of nsecs per sec. */
-struct sigaction sighnd; /*struktura pro signal handler*/
+
+
struct rpi_in data;
struct rpi_state{
uint8_t test;
/**
* \brief Signal handler pro Ctrl+C
*/
-void sighnd_fnc(){
+void appl_stop(){
spi_disable();
clk_disable();
/*muzeme zavrit semafor*/
sem_destroy(&thd_par_sem);
printf("\nprogram bezpecne ukoncen\n");
- exit(0);
}
void substractOffset(struct rpi_in* data, struct rpi_in* offset){
* Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
*/
void * pos_monitor(void* param){
- set_priority(param); /*set priority*/
while(1){
printData();
usleep(1000000); /*1 Hz*/
uint8_t tx[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
char first=1;
uint16_t last_index; /*we have index up-to date*/
- set_priority(param); /*set priority*/
pocatek = spi_read(tx);
clock_gettime(CLOCK_MONOTONIC ,&t);
/* start after one second */
}
}
+
/**
- * \brief Main function.
+ * \brief
+ * Commands detection.
*/
-
-int main(){
+void poll_cmd(){
unsigned int tmp;
-
- /*nastaveni priorit vlaken*/
- struct thread_param tsp;
- tsp.sch_policy = SCHED_FIFO;
-
- /*nastaveni signalu pro vypnuti pomoci Ctrl+C*/
- sighnd.sa_handler=&sighnd_fnc;
- sigaction(SIGINT, &sighnd, NULL );
-
- clk_init(); /* inicializace gpio hodin */
- spi_init(); /* iniicializace spi*/
-
- /*semafor pro detekci zpracovani parametru vlaken*/
- sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
-
- /*vlakna*/
- pthread_t tid; /*identifikator vlakna*/
- pthread_attr_t attr; /*atributy vlakna*/
- pthread_attr_init(&attr); /*inicializuj implicitni atributy*/
-
-
-
- /*ziskavani dat z motoru*//*vysoka priorita*/
- tsp.sch_prior = PRIOR_HIGH;
- pthread_create(&tid, &attr, read_data, (void*)&tsp);
-
- /*vypisovani lokalni pozice*//*nizka priorita*/
- tsp.sch_prior = PRIOR_LOW;
- sem_wait(&thd_par_sem);
- pthread_create(&tid, &attr, pos_monitor, (void*)&tsp);
-
-
-
/*
* Note:
* pri pouziti scanf("%u",&simple_hall_duty); dochazelo
}
}
- return 0;
+ return ;
}
+/**
+ * \brief Main function.
+ */
+
+int main(){
+ pthread_t base_thread_id;
+ clk_init(); /* inicializace gpio hodin */
+ spi_init(); /* iniicializace spi*/
+
+ /*semafor pro detekci zpracovani parametru vlaken*/
+ sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
+ setup_environment();
+
+ base_thread_id=pthread_self();
+ /*main control loop*/
+ create_rt_task(&base_thread_id,PRIOR_HIGH,read_data,NULL);
+
+ /*monitor of current state*/
+ create_rt_task(&base_thread_id,PRIOR_LOW,pos_monitor,NULL);
+
+ /*wait for commands*/
+ poll_cmd();
+
+ return 0;
+}
* Vetsinou pro komunikaci mezi vlakny, jejich sychronizaci a predavani priorit.
*/
-#include "misc.h"
+
#include <sched.h>
+#include <signal.h> /*signal handler*/
+#include <stdlib.h>
+#include <stdio.h> /*printf*/
+#include <pthread.h>
+
+#include "misc.h"
+
+
/**
- * nastavi prioritu a scheduler podle parametru
- * funkce na konci vrati semafor, aby mohlo dojit k opetovne zmene parametru
- * \param pointer na struct thread_sched_param
+ * \brief
+ * Signal handler.
+ */
+void appl_sig_handler(int sig){
+ appl_stop();
+ exit(1);
+}
+
+/*
+ * \brief Setup initial environment.
+ */
+void setup_environment(){
+ /*struktura pro signal handler*/
+ struct sigaction sighnd;
+
+ atexit(appl_stop);
+
+ /*nastaveni signalu pro vypnuti pomoci Ctrl+C*/
+ sighnd.sa_handler=appl_sig_handler;
+ sigaction(SIGINT, &sighnd, NULL );
+}
+
+/*
+ * \brief
+ * Creates RT thread
*/
-void set_priority(void * param){
- struct sched_param sp;
- struct thread_param *tp = ((struct thread_param*) param);
+int create_rt_task(pthread_t *thread, int prio, void *(*start_routine) (void *), void *arg){
+ int ret ;
- sp.sched_priority = tp->sch_prior; /*vysoka priorita*/
- if(sched_setscheduler(0, tp->sch_policy, &sp) == -1) {
- perror("pid sched_setscheduler failed");
+ pthread_attr_t attr;
+ struct sched_param schparam;
+
+ /*inicializace implicitnich atributu*/
+ if (pthread_attr_init(&attr) != 0) {
+ fprintf(stderr, "pthread_attr_init failed\n");
+ return -1;
+ }
+
+ /*nastavi dedeni planovace z attr*/
+ if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
+ fprintf(stderr, "pthread_attr_setinheritsched failed\n");
+ return -1;
+ }
+
+ /*nastaveni planovace*/
+ if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO) != 0) {
+ fprintf(stderr, "pthread_attr_setschedpolicy SCHED_FIFO failed\n");
+ return -1;
+ }
+
+ schparam.sched_priority = prio;
+
+ /*nastavit atribut attr podle hodnoty schparam*/
+ if (pthread_attr_setschedparam(&attr, &schparam) != 0) {
+ fprintf(stderr, "pthread_attr_setschedparam failed\n");
+ return -1;
}
- sem_post(&thd_par_sem);
+
+ /*vytvori vlakno*/
+ ret = pthread_create(thread, &attr, start_routine, arg);
+
+ /*uvolni strukturu, nema vliv na vlakna jiz vytvorena*/
+ pthread_attr_destroy(&attr);
+
+ return ret;
}
+
+
+
#ifndef MISC_H_
#define MISC_H_
+#ifndef NULL
+#define NULL (void*)0
+#endif /*NULL*/
+
#include <semaphore.h>
sem_t thd_par_sem; ///< semafor pro detekci zpracovani parametru noveho vlakna
-/*
- * struktura predana novym vlaknum
+/**
+ * \brief
+ * Setup initial environment.
*/
-struct thread_param{
- int sch_policy;
- int sch_prior;
-};
+void setup_environment();
/**
- * nastavi prioritu a scheduler podle parametru
- * na konci vrati semafor
- * \param pointer na struct thread_sched_param
+ * \brief
+ * Extern handler for signal termination.
+ * Deklarovana jako 'extern', protoze ji pouzivaji funkce v misc.c,
+ * deklarovana je ale jinde. Vetsinou v main file.
*/
-extern void set_priority(void *);
+extern void appl_stop();
+/**
+ * \brief
+ * Create RT capable thread.
+ */
+int create_rt_task(pthread_t *thread, int prio, void *(*start_routine) (void *), void *arg);
#endif /* MISC_H_ */