Hallo,
some times ago I started this thread before. Now I'm a little bit better
(hopefully) but the system is crashed by changing the func_id to ao_recktangle.
Why? It's using comedi for output and if rt_func_id = RT_FUNC_SET_CURRENT
or rt_func_id = RT_FUNC_IDLE there is no crash. The functions ao_set_current
and ao_recktangle are basicly the same.
I attached the short code for discuss as well to learn on the comments on it.
Thanks Olaf
------8<----- cmd.h --------8<--------
#define CMD_DONE 100
#define CMD_SET_DEBUG_LEVEL 101
#define CMD_SET_CURRENT_SOLL 102
#define CMD_SET_DEFAULT_CURRENT 103
#define CMD_GET_ACT_CURRENT_SOLL 104
#define CMD_SET_PERIOD 105
#define CMD_SUSPEND_THREAD 106
#define CMD_WAKEUP_THREAD 107
#define CMD_SET_FUNCTION 108
#define RT_FUNC_IDLE 0
#define RT_FUNC_SET_CURRENT 1
#define RT_FUNC_SQUARE_WAVE 2
#define RT_FUNC_AI 3
#define RT_FUNC_PRINT_SLUT 4
#define RT_FUNC_N 5 /* !!! No. of RT-fcn !!! */
typedef struct {
unsigned int cmd;
int data1;
int data2;
} rtf_msg_t;
------8<----- rt.c --------8<--------
extern volatile sampl_t sampl_current1; /* daq.c: current 1 dig. val. */
extern volatile sampl_t sampl_current2; /* daq.c: current 2 dig. val. */
....
pthread_t rt_thread; /* the thread */
void (*rt_func[RT_FUNC_N])(void); /* the fnc ptr to the rt-code */
...
extern hrtime_t period_ns; /* mod param: rtreg_main.c */
int hz_freq; /* complement to period_ns (for daq.c) */
unsigned int volatile rt_func_id = RT_FUNC_IDLE; /* the numer of function */
...
void *thread_code(void *param)
{
unsigned long flags;
while(1) {
pthread_wait_np();
rtl_hard_savef_and_cli(flags); /* critical section, disable interrrupts */
rt_func[rt_func_id](); /* just do it */
rtl_hard_restore_flags(flags); /* restore interrupts */
}
return 0;
}
int rtf_handler(unsigned int fifo)
{
rtf_msg_t rtf_msg;
hrtime_t now;
int ret;
if(rtf_get(CTRL_FIFO, &rtf_msg, sizeof(rtf_msg)) > 0) {
switch(rtf_msg.cmd) {
case CMD_SET_DEBUG_LEVEL:
....
case CMD_SET_CURRENT_SOLL:
if(rtf_msg.data1 >= 0 && rtf_msg.data1 <= NI_PCI_MIO_XE10_MAXDATA
&& rtf_msg.data2 >= 0 && rtf_msg.data2 <= NI_PCI_MIO_XE10_MAXDATA ) {
sampl_current1 = (sampl_t)rtf_msg.data1;
sampl_current2 = (sampl_t)rtf_msg.data2;
} else {
RTREG_ERR("got invalid current soll %d, %d, command ignored\n",
rtf_msg.data1, rtf_msg.data2);
}
break;
case CMD_SET_DEFAULT_CURRENT:
sampl_current1 = (sampl_t)SAMPL_CURRENT1_DEFAULT;
sampl_current2 = (sampl_t)SAMPL_CURRENT2_DEFAULT;
break;
....
case CMD_SET_PERIOD:
if(rtf_msg.data1 >= PERIOD_NS_MIN && rtf_msg.data1 <= PERIOD_NS_MAX) {
period_ns = (hrtime_t)rtf_msg.data1;
now = gethrtime();
if((ret = pthread_make_periodic_np(rt_thread, now + 1000, period_ns))
!= 0) {
RTREG_ERR("unable to make thread periodic (error %d) !\n", ret);
}
hz_freq = ns2Hz(period_ns); /* this is for ao_recktangle */
} else {
RTREG_ERR("got invalid current period_ns %d, command ignored\n",
rtf_msg.data1);
}
break;
case CMD_SET_FUNCTION:
if(rtf_msg.data1 >= 0 && rtf_msg.data1 < RT_FUNC_N) {
pthread_suspend_np(rt_thread); /* stop the task */
rt_func_id = (unsigned int)rtf_msg.data1; /* set the new func_id
*/
pthread_wakeup_np(rt_thread); /* and restart imediatly */
} else {
RTREG_ERR("got invalid function ID %d, command ignored\n",
rtf_msg.data1);
}
break;
default:
....
}
}
return 0;
}
int init_rtreg(void)
{
int ret = 0;
pthread_attr_t attr;
struct sched_param sched_param;
hrtime_t now;
if((ret = rtf_create(CTRL_FIFO, CTRL_FIFO_SIZE)) != 0) {
goto fail_rtf_create_CTRL_FIFO;
}
if((ret = rtf_create(EVENT_FIFO, EVENT_FIFO_SIZE)) != 0) {
.....
if((ret = rtf_create(THREAD_FIFO, THREAD_FIFO_SIZE)) != 0) {
.....
if((ret = lock_daq_card()) != 0) {
......
init_trig_struct_ni_pci_mio_xe10();
/***
* ... initialize function ptr
*/
rt_func[RT_FUNC_IDLE] = &ao_idle; /* daq.c: the idle task */
rt_func[RT_FUNC_SET_CURRENT] = &ao_set_current; /* daq.c */
rt_func[RT_FUNC_SQUARE_WAVE] = &ao_recktangle; /* daq.c */
rt_func[RT_FUNC_AI] = &ai; /* daq.c */
rt_func_id = RT_FUNC_IDLE; /* default */
hz_freq = ns2Hz(period_ns);
pthread_attr_init(&attr);
sched_param.sched_priority = 100;
pthread_attr_setschedparam(&attr, &sched_param);
if((ret = pthread_create(&rt_thread, &attr, thread_code, (void *)0)) != 0) {
......
}
now = gethrtime();
if((ret = pthread_make_periodic_np(rt_thread, now + 1000, period_ns)) != 0) {
if((ret = pthread_setfp_np(rt_thread, 1)) != 0) {
goto fail_pthread_setfp_np;
}
}
/* sucess */
return ret;
/* failure handling */
...
}
-------8< ------ daq.c ----------8<-----------
inline void ao_idle(void)
{
static char buf[80];
ao_data[DAC0] = (sampl_t)SAMPL_CURRENT1_DEFAULT;
ao_data[DAC1] = (sampl_t)SAMPL_CURRENT2_DEFAULT;
if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
}
inline void ao_set_current(void)
{
int ret = 0;
ao_data[DAC0] = (sampl_t)sampl_current1; /* set current1 to ch0 */
ao_data[DAC1] = (sampl_t)sampl_current2; /* set current2 to ch1 */
if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
}
inline void ao_recktangle(void)
{
static int loop_index = 0;
static int square_on = 0; /* flag for wheter square wave is on/off */
int ret = 0;
static char buf[80];
if(square_on) {
ao_data[DAC0] = (sampl_t)sampl_current1; /* amplitude of analog output */
ao_data[DAC1] = (sampl_t)sampl_current2; /* amplitude of analog output */
if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
if( !(loop_index % hz_freq) )
square_on = 0; /* turn off analog output */
} else { /* !square_on */
ao_data[DAC0] = NI_PCI_MIO_XE10_MAXDATA - (sampl_t)sampl_current1;
ao_data[DAC1] = NI_PCI_MIO_XE10_MAXDATA - (sampl_t)sampl_current2;
if((ret = comedi_trig_ioctl(ao_dev, ao_subdev, &ao_trig)) < 0)
RTREG_ERR("comedi_trig_ioctl() failed (error %d) !\n", ret);
if( !(loop_index % hz_freq) )
square_on = 1; /* turn on analog output */
}
}
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
---
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/