From b7f2d913caef06457b1b68889895ba01f141935f Mon Sep 17 00:00:00 2001 From: Martin Prudek Date: Fri, 8 May 2015 18:31:30 +0200 Subject: [PATCH] Upgareded priority and scheduler settings of new threads. Inspired by Pavel Pisa's solution. --- pmsm-control/test_sw/main_pmsm.c | 77 +++++++++++++---------------- pmsm-control/test_sw/misc.c | 85 +++++++++++++++++++++++++++----- pmsm-control/test_sw/misc.h | 28 +++++++---- 3 files changed, 126 insertions(+), 64 deletions(-) diff --git a/pmsm-control/test_sw/main_pmsm.c b/pmsm-control/test_sw/main_pmsm.c index 5195150..cbc6879 100644 --- a/pmsm-control/test_sw/main_pmsm.c +++ b/pmsm-control/test_sw/main_pmsm.c @@ -34,7 +34,7 @@ #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 @@ -53,7 +53,8 @@ #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; @@ -89,13 +90,12 @@ inline void clk_disable(){ /** * \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){ @@ -227,7 +227,6 @@ void prepare_tx(uint8_t * tx){ * 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*/ @@ -439,7 +438,6 @@ void * read_data(void* param){ 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 */ @@ -482,45 +480,13 @@ void * read_data(void* param){ } } + /** - * \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 @@ -581,6 +547,31 @@ int main(){ } } - 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; +} diff --git a/pmsm-control/test_sw/misc.c b/pmsm-control/test_sw/misc.c index 78d4eb5..170bd54 100644 --- a/pmsm-control/test_sw/misc.c +++ b/pmsm-control/test_sw/misc.c @@ -8,21 +8,84 @@ * Vetsinou pro komunikaci mezi vlakny, jejich sychronizaci a predavani priorit. */ -#include "misc.h" + #include +#include /*signal handler*/ +#include +#include /*printf*/ +#include + +#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; } + + + diff --git a/pmsm-control/test_sw/misc.h b/pmsm-control/test_sw/misc.h index 14b1089..7a131c0 100644 --- a/pmsm-control/test_sw/misc.h +++ b/pmsm-control/test_sw/misc.h @@ -8,24 +8,32 @@ #ifndef MISC_H_ #define MISC_H_ +#ifndef NULL +#define NULL (void*)0 +#endif /*NULL*/ + #include 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_ */ -- 2.39.2