Conversion of code from software timers to Hardware timers - c

The below code is generating a single line signal with 30ms on time and 8ms off time using software timers, want to do this process using hardware timers. Please seek and help.
#include <stdio.h>
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include <stdbool.h>
#include "esp_err.h"
#include "sdkconfig.h"
void timer_callback_1(void *param);
int count = 0;
void app_main(void)
{
esp_timer_handle_t timer_handler1;
gpio_pad_select_gpio(GPIO_NUM_2);
gpio_set_direction(GPIO_NUM_2, GPIO_MODE_OUTPUT);
const esp_timer_create_args_t my_timer_args = {
.callback = &timer_callback_1,
.name = "a timer"};
ESP_ERROR_CHECK(esp_timer_create(&my_timer_args, &timer_handler1));
ESP_ERROR_CHECK(esp_timer_start_periodic(timer_handler1, 1000));
while (true)
{
esp_timer_dump(stdout);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void timer_callback_1(void *param)
{
count++;
if(count == 30)
{
gpio_set_level(GPIO_NUM_2,0);
}
else if(count == 38)
{
gpio_set_level(GPIO_NUM_2,1);
count = 0;
}
}

Related

(C QUESTION) Whenever my program runs it gets overloaded with memory. Basically it returns a memory error

So im running a program and I think I messed up the code, whenever it runs it gets overloaded with memory. Basically it returns a memory error, I think it relates to the mutex.
It basically means that you're accessing memory that you're not supposed to be accessing and I'm trying to figure out why it's doing this.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "headers/queue.h"
#include "headers/main.h"
#include "headers/connection.h"
void bruter_queue_ip(char *address)
{
pthread_mutex_lock(&mutex);
for(int i = 0; i < 999999; i++)
{
if(!queue[i].queued)
{
ATOMIC_INC(&left_in_queue);
strcpy(queue[i].address, address);
queue[i].queued = 1;
break;
}
}
pthread_mutex_unlock(&mutex);
}
void *handle_queued()
{
while(1)
{
if(processing <= ACTUAL_MAX_CONS)
{
for(int i = 0; i < 999999; i++)
{
if(queue[i].queued)
{
start_connection(queue[i].address, NULL);
queue[i].queued = 0;
memset(queue[i].address, 0, 16);
ATOMIC_DEC(&left_in_queue);
}
if(processing >= ACTUAL_MAX_CONS)
break;
}
}
sleep(1);
}
}

Porting LKM to LSM - Unexpected behavior [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a Linux Kernel Module that checks for the presence of a specific USB device and performs a printk upon a match. This code works fine and performs as i expect.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/list.h>
#include <linux/slab.h>
MODULE_LICENSE("GPL");
static int HARD_VEND;
static int HARD_PROD;
static char *HARD_SERI;
struct USBCred
{
int vendor;
int product;
char serial[128];
};
static struct USBCred create_creds_device(struct usb_device *dev)
{
struct USBCred creds;
creds.vendor = dev->descriptor.idVendor;
creds.product = dev->descriptor.idProduct;
if((dev->serial) == NULL)
{
strcpy(creds.serial, "(null)");
} else {
strcpy(creds.serial, dev->serial);
}
return creds;
}
static struct USBCred create_creds_hub(struct usb_bus *bus)
{
struct USBCred creds;
creds.vendor = bus->root_hub->descriptor.idVendor;
creds.product = bus->root_hub->descriptor.idProduct;
if((bus->root_hub->serial) == NULL)
{
strcpy(creds.serial, "(null)");
} else {
strcpy(creds.serial, bus->root_hub->serial);
}
return creds;
}
static int check_usb_creds(struct USBCred usb_data)
{
if(usb_data.vendor != HARD_VEND && usb_data.product != HARD_PROD && strcmp(usb_data.serial, HARD_SERI))
{
return 1;
} else
{
printk(KERN_INFO "*********** RootPug Module - Match ***********");
printk(KERN_INFO "Vendor ID = %x, HC Vendor ID = %x", usb_data.vendor, HARD_VEND);
printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
return 0;
}
}
static int __init usb_fun_init (void)
{
int id;
int chix;
struct USBCred cred;
struct usb_bus *bus;
struct usb_device *dev, *childdev = NULL;
HARD_VEND = 0x26bd;
HARD_PROD = 0x9917;
HARD_SERI = "070172966462EB10";
mutex_lock(&usb_bus_idr_lock);
idr_for_each_entry(&usb_bus_idr, bus, id)
{
cred = create_creds_hub(bus);
//print_USBCred(cred);
check_usb_creds(cred);
dev = bus->root_hub;
usb_hub_for_each_child(dev, chix, childdev)
{
if(childdev)
{
usb_lock_device(childdev);
cred = create_creds_device(childdev);
//print_USBCred(cred);
check_usb_creds(cred);
usb_unlock_device(childdev);
}
}
}
mutex_unlock(&usb_bus_idr_lock);
return 0;
}
static void __exit usb_fun_exit (void)
{
printk(KERN_INFO "***************** RootPug Module - Exit *****************\n");
}
module_init(usb_fun_init);
module_exit(usb_fun_exit);
When moving over to an LSM, the LSM registers without an issue, and the hook registers correctly, yet the code is not behaving as I would like, and I can not understand why. I have added debugging statements to understand at which points the code is getting to, but it seems the idr_for_each_entry() is not being executed, as the debug statment ithin that loop is not being printed. I have used a flag based system to provide a mechanism for having -EPERM as the default return value, being overwritten if the usb is found.
I cannot understand why only the mutex is being performed, with no check to the hubs or usb devices, yet the same code works as an LKM. The actual code that is in question is within the appcl_inode_create hook. I have left out the other hooks for brevity, but they currently do nothing except return the expected value of 0.
#include <linux/init.h>
#include <linux/kd.h>
#include <linux/kernel.h>
#include <linux/tracehook.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/lsm_hooks.h>
#include <linux/xattr.h>
#include <linux/security.h>
#include <linux/capability.h>
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/proc_fs.h>
#include <linux/magic.h>
#include <linux/ctype.h>
#include <linux/swap.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/dcache.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/tty.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/parser.h>
#include <linux/nfs_mount.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/posix-timers.h>
#include <linux/syslog.h>
#include <linux/user_namespace.h>
#include <linux/export.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/fsnotify.h>
#include <linux/path.h>
#include <linux/fdtable.h>
#include <linux/binfmts.h>
#include <linux/time.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include "include/appcl_lsm.h"
//#include "include/audit.h"
MODULE_LICENSE("GPLv3");
MODULE_AUTHOR("Jack Cuthbertson");
static int HARD_VEND;
static int HARD_PROD;
static char *HARD_SERI;
struct USBCred
{
int vendor;
int product;
char serial[128];
};
static struct USBCred create_creds_device(struct usb_device *dev)
{
struct USBCred creds;
creds.vendor = dev->descriptor.idVendor;
creds.product = dev->descriptor.idProduct;
if((dev->serial) == NULL)
{
strcpy(creds.serial, "(null)");
} else {
strcpy(creds.serial, dev->serial);
}
return creds;
}
static struct USBCred create_creds_hub(struct usb_bus *bus)
{
struct USBCred creds;
creds.vendor = bus->root_hub->descriptor.idVendor;
creds.product = bus->root_hub->descriptor.idProduct;
if((bus->root_hub->serial) == NULL)
{
strcpy(creds.serial, "(null)");
} else {
strcpy(creds.serial, bus->root_hub->serial);
}
return creds;
}
static int check_usb_creds(struct USBCred usb_data)
{
if(usb_data.vendor != HARD_VEND && usb_data.product != HARD_PROD && strcmp(usb_data.serial, HARD_SERI))
{
printk(KERN_INFO "*********** RootPlug Module - Non Match ***********");
printk(KERN_INFO "Vendor ID = %x, HC Vendor ID = %x", usb_data.vendor, HARD_VEND);
printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
return 1;
} else
{
printk(KERN_INFO "*********** RootPlug Module - Match ***********");
printk(KERN_INFO "Vendor ID = %x, HC Vendor ID = %x", usb_data.vendor, HARD_VEND);
printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
return 0;
}
}
static int appcl_lsm_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
{
int id;
int chix;
int flag = -EPERM;
struct USBCred cred;
struct usb_bus *bus;
struct usb_device *dev, *childdev = NULL;
HARD_VEND = 0x26bd;
HARD_PROD = 0x9917;
HARD_SERI = "070172966462EB10";
printk(KERN_ALERT "Rootplug: Beginning check\n");
mutex_lock(&usb_bus_idr_lock);
printk(KERN_ALERT "Rootplug: Mutex locked the bus list\n");
//loop though all usb buses
idr_for_each_entry(&usb_bus_idr, bus, id)
{
printk(KERN_ALERT "Rootplug: Checking hubs.\n");
cred = create_creds_hub(bus);
//Check creds of usb buses
if(check_usb_creds(cred) == 0)
{
mutex_unlock(&usb_bus_idr_lock);
printk(KERN_ALERT "Rootplug: Unlock hub success!\n");
flag = 0;
} else {
printk(KERN_ALERT "Rootplug: Unlock hub fail!\n");
}
dev = bus->root_hub;
usb_hub_for_each_child(dev, chix, childdev)
{
if(childdev)
{
printk(KERN_ALERT "Rootplug: Checking USB devices\n");
usb_lock_device(childdev);
cred = create_creds_device(childdev);
if(check_usb_creds(cred) == 0)
{
usb_unlock_device(childdev);
mutex_unlock(&usb_bus_idr_lock);
printk(KERN_ALERT "Rootplug: Unlock USB success!\n");
} else {
usb_unlock_device(childdev);
printk(KERN_ALERT "Rootplug: Unlock USB Failure!\n");
}
} else {
printk(KERN_ALERT "Rootplug: No child dev\n");
}
}
}
mutex_unlock(&usb_bus_idr_lock);
printk(KERN_ALERT "Rootplug: Unlock failed - Flag: %i\n", flag);
return flag;
}
static struct security_hook_list appcl_hooks[] = {
/*
* XATTR HOOKS
*/
LSM_HOOK_INIT(inode_setxattr, appcl_lsm_inode_setxattr),
LSM_HOOK_INIT(inode_post_setxattr, appcl_lsm_inode_post_setxattr),
LSM_HOOK_INIT(inode_getxattr, appcl_lsm_inode_getxattr),
LSM_HOOK_INIT(inode_removexattr, appcl_lsm_inode_removexattr),
LSM_HOOK_INIT(d_instantiate, appcl_lsm_d_instantiate),
LSM_HOOK_INIT(inode_setsecurity, appcl_lsm_inode_setsecurity),
LSM_HOOK_INIT(inode_init_security, appcl_lsm_inode_init_security),
/*
* INODE HOOKS
*/
LSM_HOOK_INIT(inode_alloc_security, appcl_lsm_inode_alloc_security),
LSM_HOOK_INIT(inode_free_security, appcl_lsm_inode_free_security),
/*
* General permission mask
*/
LSM_HOOK_INIT(inode_permission, appcl_lsm_inode_permission),
/*
* Specific permission hooks
*/
LSM_HOOK_INIT(inode_create, appcl_lsm_inode_create),
LSM_HOOK_INIT(inode_rename, appcl_lsm_inode_rename),
LSM_HOOK_INIT(inode_link, appcl_lsm_inode_link),
LSM_HOOK_INIT(inode_unlink, appcl_lsm_inode_unlink),
LSM_HOOK_INIT(inode_symlink, appcl_lsm_inode_symlink),
LSM_HOOK_INIT(inode_mkdir, appcl_lsm_inode_mkdir),
LSM_HOOK_INIT(inode_rmdir, appcl_lsm_inode_rmdir),
LSM_HOOK_INIT(inode_mknod, appcl_lsm_inode_mknod),
LSM_HOOK_INIT(inode_readlink, appcl_lsm_inode_readlink),
LSM_HOOK_INIT(inode_follow_link, appcl_lsm_inode_follow_link),
//LSM_HOOK_INIT(inode_setattr, appcl_lsm_inode_setattr),
//LSM_HOOK_INIT(inode_getattr, appcl_lsm_inode_getattr),
/*
* FILE HOOKS
*/
LSM_HOOK_INIT(file_alloc_security, appcl_lsm_file_alloc_security),
LSM_HOOK_INIT(file_free_security, appcl_lsm_file_free_security),
LSM_HOOK_INIT(file_permission, appcl_lsm_file_permission),
//LSM_HOOK_INIT(file_fcntl, appcl_lsm_file_fcntl),
LSM_HOOK_INIT(file_open, appcl_lsm_file_open),
LSM_HOOK_INIT(file_receive, appcl_lsm_file_receive),
/*
* CRED HOOKS
*/
LSM_HOOK_INIT(cred_alloc_blank, appcl_lsm_cred_alloc_blank),
LSM_HOOK_INIT(cred_free, appcl_lsm_cred_free),
LSM_HOOK_INIT(cred_prepare, appcl_lsm_cred_prepare),
LSM_HOOK_INIT(cred_transfer, appcl_lsm_cred_transfer),
LSM_HOOK_INIT(bprm_set_creds, appcl_lsm_bprm_set_creds),
/*
* SUPERBLOCK HOOKS
*/
LSM_HOOK_INIT(sb_alloc_security, appcl_lsm_sb_alloc_security),
LSM_HOOK_INIT(sb_free_security, appcl_lsm_sb_free_security),
};
static __init int appcl_init(void)
{
printk(KERN_ALERT "Rootplug: Module loading... \n");
/*
* Set security attributes for initial task
*/
security_add_hooks(appcl_hooks, ARRAY_SIZE(appcl_hooks), "appcl");
printk(KERN_ALERT "Rootplug: module initialised\n");
return 0;
}
DEFINE_LSM(appcl) = {
.name = "appcl",
.init = appcl_init,
};
The function that handled the matching used a different alert level for the printk function. As such, the messages were not displayed to the console at that stage in the boot process.
What was:
printk(KERN_INFO "message");
Should be:
printk(KERN_ALERT "message");
The matching function was being called, after recompiling the kernel with the hooks forced to return 0, i could see from /var/log/* that the function was being executed and outputting the correct information.

How to immediately cancel a work item of a workqueue in a Linux kernel module?

Kernel module code:
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/workqueue.h>
MODULE_LICENSE("GPL");
static struct workqueue_struct *queue;
static void work_func(struct work_struct *work)
{
int i = 0;
while (i < 5) {
printk(KERN_INFO "%d\n", i);
usleep_range(1000000, 1000001);
i++;
}
}
DECLARE_WORK(work, work_func);
int init_module(void)
{
queue = create_workqueue("myworkqueue");
queue_work(queue, &work);
return 0;
}
void cleanup_module(void)
{
cancel_work_sync(&work);
destroy_workqueue(queue);
}
If I do:
insmod mymod.ko
rmmod mymod
rmmod hangs on cancel_work_sync, which first waits for the work to finish, until the counting is over.
Is it possible to immediately cancel that work item?
Minimal runnable example here.
Tested in Linux kernel 4.9.
There is another way to stop kthread with signals. This approach is better than yours because it doesn't require your thread to wake up regularly and poll the stop variable with kthread_should_stop(). No wasting CPU time, it allows your thread to sleep as long as it neeeded.
static int kthread_handle(void *param)
{
allow_signal(SIGINT);
allow_signal(SIGKILL);
for (;;)
{
// ...
// Some blocking functions such as kernel_read()/kernel_write()
// ...
if (signal_pending(current))
{
goto end;
}
// ...
// Some interruptible functions
// ...
if (mutex_lock_interruptible(...) == -EINTR)
{
goto end;
}
}
end:
while (!kthread_should_stop())
{
schedule();
}
return 0;
}
static int __init drv_init(void)
{
// Create and start kernel thread
kthread = kthread_run(kthread_handle, NULL, "kthread");
return 0;
}
static void __exit drv_exit(void)
{
send_sig(SIGKILL, kthread, 1);
kthread_stop(kthread);
}
module_init(drv_init);
module_exit(drv_exit);
I don't know how to send signals to work queues, so the solution is only for kthreads by now.
Atomic control variable
I could not find a way to stop work in a workqueue, but using a simple control variable is a possible solution.
#include <linux/delay.h> /* usleep_range */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h> /* atomic_t */
#include <linux/workqueue.h>
MODULE_LICENSE("GPL");
static struct workqueue_struct *queue;
static atomic_t run = ATOMIC_INIT(1);
static void work_func(struct work_struct *work)
{
int i = 0;
while (atomic_read(&run)) {
printk(KERN_INFO "%d\n", i);
usleep_range(1000000, 1000001);
i++;
if (i == 10)
i = 0;
}
}
DECLARE_WORK(work, work_func);
int init_module(void)
{
queue = create_workqueue("myworkqueue");
queue_work(queue, &work);
return 0;
}
void cleanup_module(void)
{
atomic_set(&run, 0);
destroy_workqueue(queue);
}
kthread kthread_stop
Work queues are based on kthreads, and a work queue is basically useless in that example, so we could use the kthreads directly.
kthread_stop waits for the thread to return.
See also:
Proper way of handling threads in kernel?
How to wait for a linux kernel thread (kthread)to exit?
Signal handling in kthreads seems to have been a polemic subject, and is now not possible: https://unix.stackexchange.com/questions/355280/how-signals-are-handled-in-kernel
#include <linux/delay.h> /* usleep_range */
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static struct task_struct *kthread;
static int work_func(void *data)
{
int i = 0;
while (!kthread_should_stop()) {
printk(KERN_INFO "%d\n", i);
usleep_range(1000000, 1000001);
i++;
if (i == 10)
i = 0;
}
return 0;
}
int init_module(void)
{
kthread = kthread_create(work_func, NULL, "mykthread");
wake_up_process(kthread);
return 0;
}
void cleanup_module(void)
{
kthread_stop(kthread);
}
Timer
Run in interrupt context directly, so more accurate, but more restricted.
See also: How to use timers in Linux kernel device drivers?
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
MODULE_LICENSE("GPL");
static void callback(unsigned long data);
static unsigned long onesec;
DEFINE_TIMER(mytimer, callback, 0, 0);
static void callback(unsigned long data)
{
pr_info("%u\n", (unsigned)jiffies);
mod_timer(&mytimer, jiffies + onesec);
}
int init_module(void)
{
onesec = msecs_to_jiffies(1000);
mod_timer(&mytimer, jiffies + onesec);
return 0;
}
void cleanup_module(void)
{
del_timer(&mytimer);
}

Linux kernel version mismatch

I'm trying to create a simple kernel module which makes the keyboard LEDs flashing. It works fine on Linux 3.16 (Ubuntu 14.04) but it doesn't change the LED status on 4.5 (Arch).
I can't figure out what kind of difference causes it, I didn't find anything useful in demsg. Any idea how could I find about this problem?
Code:
#include <linux/module.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kd.h>
#include <linux/vt.h>
#include <linux/console_struct.h>
#include <linux/vt_kern.h>
#include "device.h"
#include "timer.h"
#define LEDS_ON 0x07
#define LEDS_OFF 0xFF
static int major_number;
static struct class *class;
static struct tty_driver *driver;
static unsigned long led_status = LEDS_OFF;
static void timer_callbak(void)
{
if (led_status == LEDS_OFF) {
led_status = LEDS_ON;
} else {
led_status = LEDS_OFF;
}
driver->ops->ioctl(vc_cons[fg_console].d->port.tty, KDSETLED, led_status);
}
static long device_ioctl(struct file *file, unsigned int command, unsigned long argument)
{
if (command == ON && led_status == LEDS_OFF) {
timer_init(&timer_callbak);
} else if (command == OFF && led_status == LEDS_OFF){
timer_exit();
} else if (command != OFF && command != ON) {
printk(KERN_WARNING "Invalid ioctl() command");
return -1;
}
return 0;
}
static struct file_operations operations = {
.unlocked_ioctl = device_ioctl
};
dev_t create_dev_type(void)
{
return MKDEV(major_number, 0);
}
void create_device(void)
{
major_number = register_chrdev(0, NAME, &operations);
printk("Keyboard leds registered with major_number \"%d\"", major_number);
class = class_create(THIS_MODULE, NAME);
device_create(class, NULL, create_dev_type(), NULL, NAME);
}
void device_init(void)
{
create_device();
driver = vc_cons[fg_console].d->port.tty->driver;
printk("Keyboard leds device Initialized");
}
void device_exit(void)
{
device_destroy(class, create_dev_type());
class_unregister(class);
class_destroy(class);
unregister_chrdev(major_number, NAME);
printk("Keyboard leds device exited");
}
MODULE_LICENSE("GPL");
That's how I'm trying to invoke it:
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include "src/device.h"
int main(void)
{
int fd;
if ((fd = open("/dev/keyboard_leds", O_RDWR|O_NONBLOCK)) < 0) {
perror("Open failed!");
return -1;
}
ioctl(fd, ON);
close(fd);
return 0;
}

OpenCV multithreading XInitThreads error

I am an embedded programmer and using a multithreaded application which is going to receive pixel data over serial line and display it in a window. I am using openCV's cvSetData() method to copy the data received over serial line and populate it to an openCV array. Also using the cvShowImage() function I am displaying the continuously updating pixel data( concept of displaying a video).
Here is a snippet from my code:
//-------------------------------------Start of code------------------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include "serial_comm_defines.h"
#include <opencv2/highgui/highgui.hpp>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
extern unsigned char array[COUNT_LIM];
IplImage *newimage;
img_disp_method(void)
{
cvSetData((CvArr*)newimage, (void*)array, 1556);
cvNamedWindow("Mywindow",CV_WINDOW_FREERATIO);
cvResizeWindow("Mywindow", 1556, 360);
cvShowImage("Mywindow",(CvArr*)newimage);
cvWaitKey(1);
}
void *serial_thread_method(void* my_fd)
{
clock_t start = 0, end = 0;
double time_taken = 0;
if ((int)my_fd<0)
printf("\nError opening device file\n");
else
{
printf("\nDevice file opened successfully\n");
if ( serial_config((int)my_fd) < 0)
printf("\nUnable to configure serial port\n");
else
{
printf("\nSerial port configured successfully\n");
for(;;)
{
start = clock();
serial_read((int)my_fd);
end = clock();
printf("\nTime taken:%f seconds\n", (double)((end-start)/CLOCKS_PER_SEC));
}
}
}
close ((int)my_fd);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t serial_read_thread;
int my_fd=0, i=0, temp=0, serial_thread_ret=0;
newimage = cvCreateImageHeader(cvSize(HEIGHT, WIDTH), IPL_DEPTH_8U, 0x01);
struct timeval my_value={0,10000};
struct timeval my_interval={0,10000};
struct itimerval my_timer={my_interval,my_value};
setitimer(ITIMER_REAL, &my_timer, 0);
signal(SIGALRM, img_disp_method);
my_fd = open_device_file((char**)argv);
if ( (serial_thread_ret = pthread_create(&serial_read_thread, NULL, serial_thread_method, (void*)my_fd) == 0))
fprintf(stdout, "\nSerial read thread created successfully\n");
else
perror("\nError creating serial read thread\n");
pthread_join(&serial_read_thread, NULL);
cvReleaseImageHeader(&newimage);
return NULL;
}
//----------------------------------------End of code--------------------------------------//
The code is compiling fine. But when I execute the binary it throws the following error. I also observed that if change the value of timer (value of my_value and my_interval) to anywhere greater than 30ms (30000) the code works just fine. Please explain what is happening.
Try using a virtual timer instead of a real timer.
Something like this
setitimer(SIGVTALRM, &my_timer, 0);
signal(SIGVTALRM, img_disp_method);

Resources