HPI driver modification and some fragmentation

Source: Internet
Author: User
Tags id3 semaphore

The DSP and FPGA video image processing cards are used to process 24 frames of images per second, calculate the position of the target object (ball) (generally, the object is decomposed by color difference), and then interrupt the arm, arm reads related data through the HPI port.
Because HPI is not a real character device, it looks like a block device. Given a random address, it can read a large part of DSP data, which makes me not know how to implement it, however, I have not read the driver of a block device, so I still select a character device to implement it. However, I cannot create a buffer like a character device to store the received data, because the host never passively accepts data and actively reads data, I think no matter what it is, the read/write operation sets the address first, and then reads and writes the data of the specified size. For interruptions, what I thought was that after the interruption, I read the specified data to a buffer in the kernel through the interrupt service program, and then notified the application to retrieve the data. However, the data is not accumulated as the serial port, until the buffer is full, because the data I need to transmit is the object location information in the image, 24 frames per second, I only need to get the data of the latest frame, therefore, the previous data is overwritten each time. Therefore, there should be a flag that sets 1 when the data is obtained to the kernel during interruption and 0 after the application reads the current data, in this way, it can be used as a condition for the process to sleep. However, if I change the READ function to an interrupt driver, I cannot read any other data, and since each transmission only contains three data of the type, therefore, I would like to read the three data using ioctl, and put the function of enabling and disabling the interrupt in IOCTL to keep the original read and write, in this way, I can read and write the DSP Ram at will through read and write, and can obtain the target information in each frame when the interrupt is enabled.
Resources need to be protected during reading and writing. For example, a stream buffer zone allows only one process to read or write data at a time. Therefore, the semaphore or spin lock is used to protect resources, the spin lock is invalid on a single CPU machine. Here we only discuss semaphores. The kernel uses mutex semaphores and can only be obtained once. Once obtained by one process, the other process can only block and wait for the semaphores to be released.
Another blocking case is that when no data is readable or the buffer is full and cannot be written, the process enters the sleep state, and the driver must first determine the condition. If the condition is not met, the semaphore is released, do not hold semaphores to sleep, or the process is prone to deadlocks.
Here we still need to use the spin lock, because the interrupt is generated at any time. If I encounter an interruption while reading the shared variable, the data I read may not be in the same frame, therefore, shared variables must be read for protection and spin locks must be used. although the spin lock is not valid for a single CPU, we only use its function of Guanzhong disconnection.
Spin_lock_irq (& Dev-> hpi_lock) only calls CLI disconnection when a single CPU is used. Therefore, if you do not need to use a spin lock, it is also possible to only use it. in addition, the lock should be released before interruptible_sleep_on is used; otherwise, it is a deadlock. In this way, the process can be awakened through wake_up_interruptible during the interruption, so the real-time performance should be much better than the query.
Spin_lock_irq (& Dev-> hpi_lock );
While (! Dev-> new_frame)
{
Spin_unlock_irq (& Dev-> hpi_lock );
Interruptible_sleep_on (& Dev-> hpi_queue );
If (signal_pending (current ))
Return-erestartsys;
Spin_lock_irq (& Dev-> hpi_lock );
}
Dev-> new_frame = 0;
Ret = copy_to_user (void *) Arg, & Dev-> ball, sizeof (Dev-> ball ))? -Efault: sizeof (Dev-> ball );
Spin_unlock_irq (& Dev-> hpi_lock );
It was originally intended to use wait_event_interruptible to sleep the process, but Ms does not allow me to release the lock before sleep.
Basically, these are the three variables obtained to create a decision-making process for robots.
Class cball
{
Public:
Ball_info m_ball_info;
Int angle;
Int FD;
Void hpi_init ();
};

Void cball: hpi_init (INT portno)
{
If (FD = open ("/dev/HPI", o_rdwr) <0)
{
Perror ("can not open device/N ");
Exit (1 );
}
IOCTL (FD, hpi_reset, 0 );
IOCTL (FD, enable_int, 0 );
}
The cball class is used to initialize and save data.
Void * get_ball_info (void *) // obtain the ball information.
{
IOCTL (m_data.m_ball.fd, get_ball, & m_data.m_ball.m_ball_info );
M_data.m_ball.angle = 25*(2 * m_data.m_ball.m_ball_info.cx-240)/240;
}

Create a new thread in the main function to obtain the ball_info data structure from the kernel.
Ret = pthread_create (& ID3, null, get_ball_info, null );
If (Ret! = 0)
{
Printf ("create get_ball_info pthread error! /N ");
Exit (1 );
}
Of course there is also a decision-making thread.
The main function is as follows:
Int main ()
{
Pthread_t id1, Id2, ID3;
Int ret;
Struct itimerval value, ovalue;

M_data.m_drive.drive_init (1); // driver initialization
M_data.m_sensor.sensor_init (2); // sensor Initialization
M_data.m_ball.hpi_init ();
Ret = pthread_create (& id1, null, demo-, null); // create a decision thread
If (Ret! = 0)
{
Printf ("create demo-pthread error! /N ");
Exit (1 );
}

Ret = pthread_create (& Id2, null, sensorlisten, null); // create a sensor serial port listening thread
If (Ret! = 0)
{
Printf ("create sensorlisten pthread error! /N ");
Exit (1 );
}

Ret = pthread_create (& ID3, null, get_ball_info, null );
If (Ret! = 0)
{
Printf ("create get_ball_info pthread error! /N ");
Exit (1 );
}

Signal (sigalrm, sigroutine); // create timer and timer functions
Value. it_value. TV _sec = 0;
Value. it_value. TV _usec = 200000;
Value. it_interval. TV _sec = 0;
Value. it_interval. TV _usec = 200000;
Setitimer (itimer_real, & Value, & ovalue );

Pthread_join (id1, null );
Pthread_join (Id2, null );
Pthread_join (ID3, null );
}
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.