Working on a C program in Debian and I need to access a directory that has numbers at the end of it that occasionally change. When accessing from the command prompt I can tab complete or use the *, how can I do this from a C program using fopen or some other method?
pwm = fopen("/sys/devices/ocp.3/pwm_test_P8_19.15/duty // this is the changing directory
pwm = fopen("/sys/devices/ocp.3/pwm_t*/duty // this did not work
using stdio.h, stdlib.h, unistd.h
int k = 0;
char pwm_path[100];
for (k = 14; k < 20; k++)
{
sprintf( pwm_path, "/sys/devices/ocp.3/pwm_test_P8_19.%d/period", k );
puts(pwm_path); //debug
if (access( pwm_path, F_OK ) == 0) // if it finds path, then = 0
{
//printf("Files does exists, %d\n", k); // debug
pwm = fopen( pwm_path, "w" );
fseek(pwm,0,SEEK_SET);
fprintf(pwm,"20000000"); // pulse period in uS
fflush(pwm); // flush free up memory
break; // break out of loop once found
}
}
Related
trying to make project in QT, I need to detect any new usb device and return the letter in my main.cpp.
I found this with google and it should work but I don't know how to have a print of the driver letter in my main.cpp with simple qDebug() by calling the function char FirstDriveFromMask(ULONG unitmask).
Could you help me?
void Main_OnDeviceChange( HWND hwnd, WPARAM wParam, LPARAM lParam )
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
TCHAR szMsg[80];
switch(wParam )
{
case DBT_DEVICEARRIVAL:
// Check whether a CD or DVD was inserted into a drive.
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (lpdbv -> dbcv_flags & DBTF_MEDIA)
{
StringCchPrintf( szMsg, sizeof(szMsg)/sizeof(szMsg[0]),
TEXT("Drive %c: Media has arrived.\n"),
FirstDriveFromMask(lpdbv ->dbcv_unitmask) );
MessageBox( hwnd, szMsg, TEXT("WM_DEVICECHANGE"), MB_OK );
}
}
break;
case DBT_DEVICEREMOVECOMPLETE:
// Check whether a CD or DVD was removed from a drive.
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (lpdbv -> dbcv_flags & DBTF_MEDIA)
{
StringCchPrintf( szMsg, sizeof(szMsg)/sizeof(szMsg[0]),
TEXT("Drive %c: Media was removed.\n" ),
FirstDriveFromMask(lpdbv ->dbcv_unitmask) );
MessageBox( hwnd, szMsg, TEXT("WM_DEVICECHANGE" ), MB_OK );
}
}
break;
default:
/*
Process other WM_DEVICECHANGE notifications for other
devices or reasons.
*/
;
}
}
/*------------------------------------------------------------------
FirstDriveFromMask( unitmask )
Description
Finds the first valid drive letter from a mask of drive letters.
The mask must be in the format bit 0 = A, bit 1 = B, bit 2 = C,
and so on. A valid drive letter is defined when the
corresponding bit is set to 1.
Returns the first drive letter that was found.
--------------------------------------------------------------------*/
char FirstDriveFromMask( ULONG unitmask )
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return( i + 'A' );
}
Either this:
#include <QDebug>
///
qDebug() <<
"Drive" << FirstDriveFromMask(lpdbv ->dbcv_unitmask) << ": Media has arrived";
or with a bit better formatting
qDebug() <<
QString("Drive %1: Media has arrived").arg(FirstDriveFromMask(lpdbv ->dbcv_unitmask));
And if that output going to default debug console rather than Windows you have to follow the answer: Qt qDebug() doesn't work in Windows shell and make a small change in project.pro file:
CONFIG += console
I want to write 2 files by using aio_write.
Used 32KB buffer and repeat aio_write 2048 times for 1 file.(file size is 64MB)
However result is not 64MB but size is 64MB + 32KB, now.
Also sometimes file is written by garbage.
I want to fill 'A' to file.
Please help me.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <aio.h>
#include <fcntl.h>
#include <siginfo.h>
#define TNAME "testAio.c"
#define BUFFER_SIZE 32 * 1024 //(32 * 1024 * 1024)
#define FILE_COUNT 2
#define FILE_PATH 256
#define FALSE 0
#define TRUE 1
int main ()
{
char sTmpFileName[FILE_COUNT][FILE_PATH];
char * sBuf;
char * sAlignedBuf;
int sFd[FILE_COUNT];
struct aiocb sAiocb[FILE_COUNT];
int sError;
int sRet;
int i;
int j;
int sWritten[FILE_COUNT];
int sWrittenSize;
int sWrittenCnt;
int sFrequence = 2048;
sBuf = (char*) malloc( BUFFER_SIZE + 512 );
sAlignedBuf = (char*)( ((long)sBuf) + (512 - ((long)sBuf) % 512));
memset( sAlignedBuf, 0x41, BUFFER_SIZE );
for( i = 0; i < FILE_COUNT; i++ )
{
memset( &sAiocb[i], 0, sizeof(struct aiocb) );
sAiocb[i].aio_buf = sAlignedBuf;
sAiocb[i].aio_nbytes = BUFFER_SIZE;
snprintf( sTmpFileName[i],
FILE_PATH,
"testAio_%d",
i);
unlink( sTmpFileName[i] );
sFd[i] = open( sTmpFileName[i],
O_CREAT | O_RDWR | O_EXCL |
O_DIRECT | O_LARGEFILE,
S_IRUSR | S_IWUSR );
sAiocb[i].aio_fildes = sFd[i];
if( sFd[i] == -1 )
{
printf( TNAME " Error at open(): %s\n", strerror( errno ) );
exit(1);
}
}
for( j = 0; j < sFrequence; j++ )
{
for( i = 0; i < FILE_COUNT; i++ )
{
if( sWrittenSize = aio_write( &sAiocb[i] ) == -1 )
{
printf( TNAME " Error at aio_write(): %s\n", strerror( errno ) );
close( sFd[i] );
exit(2);
}
sAiocb[i].aio_offset += sAiocb[i].aio_nbytes;
// printf( "offset %ld\n", sAiocb[i].aio_offset );
}
}
printf( "offset %ld %ld\n",
sAiocb[0].aio_offset,
sAiocb[1].aio_offset );
/* Wait until completion */
i = 0;
sWritten[0] = FALSE;
sWritten[1] = FALSE;
sWrittenCnt = 0;
while( 1 )
{
sError = aio_error( &sAiocb[i] );
if( sError != EINPROGRESS )
{
if( sWritten[i] == FALSE )
{
sWrittenCnt++;
sWritten[i] = TRUE;
}
}
if( sWrittenCnt == FILE_COUNT )
{
break;
}
i = (i + 1) % FILE_COUNT;
}
for( i = 0; i < FILE_COUNT; i++ )
{
sError = aio_error( &sAiocb[i] );
sRet = aio_return( &sAiocb[i] );
if( sError != 0 )
{
printf( TNAME " Error at aio_error() : %d, %s\n",
i,
strerror( sError ) );
close( sFd[i] );
exit(2);
}
if( sRet != BUFFER_SIZE )
{
printf( TNAME " Error at aio_return()\n" );
close( sFd[i] );
exit(2);
}
}
for( i = 0; i < FILE_COUNT; i++ )
{
close( sFd[i] );
}
printf( "Test PASSED\n" );
return 0;
}
Most POSIX implementations enforce severe limits on the number of concurrent asynchronous i/o operations which can be in flight in total on the system, and per process. This limit is 16 on some major implementations. You therefore cannot simply call aio_write 2048 times in sequence, you must call it only up until AIO_LISTIO_MAX which is the maximum possible, always checking error codes for system resource exhaustion before that maximum possible limit. Even on NT which has no hard limits, performance noticeably nosedives after a certain amount of concurrency when FILE_FLAG_NO_BUFFERING is on, especially on older Windows kernels.
Once you have scheduled as many aio_write as the system will take, you then need to call aio_suspend on what you've scheduled and retire out any ops which complete, trying again to refill the pending i/o queue. If you'd like to see a production example of usage, try https://github.com/ned14/boost.afio/blob/master/include/boost/afio/v2.0/detail/impl/posix/io_service.ipp.
I should emphasise that POSIX aio scales poorly, provides virtually no performance benefit, and on Linux or FreeBSD your "asynchronous i/o" is really a thread pool of workers which call the synchronous i/o APIs for you. Virtually no POSIX OS implements much asynchronicity in practice unless O_DIRECT or its equivalent is turned on, it's only really worth bothering with on NT.
As many other posts on Stackoverflow have said, async filesystem i/o is not worth the time nor hassle for 99% of users, just use a thread pool calling the synchronous APIs instead, it scales far far better and is portable across all platforms, doesn't have daft problems with signals, plus always on Linux or on FreeBSD when O_DIRECT is off it's how POSIX aio is implemented anyway.
Thanks for the comment.
Now I noticed about the code that I made mistake.
I don't know whether it is certain or not.
I assume that aio_nbytes should be handled concurrently.
After I called aio_write for certain file(ex file1), I have to wait until end of the call for next aio_write call for file1.
Is my assumption right?
My chip just stop doing anything. sometimes it prints good results, sometimes its not, i just cant understand whats wrong with this code( and generally any time you using Strings it happens )
void ParseGetRequest(char* data)
{
String parseGET=data;
String from="GET /";
String to="HTTP";
int ind1 = parseGET.indexOf(from);
int ind2 = parseGET.indexOf(to);
parseGET=parseGET.substring(ind1+from.length(), ind2-1);
strcpy(data, parseGET.c_str () );
}
And calling it with :
void readWifDataAsSever(char* reqData)
{
uint8_t buffer[128] = {0};
uint8_t mux_id;
uint32_t len = wifi.recv(&mux_id, buffer, sizeof(buffer), 100);
char serverData[100]={0};
if (len > 0)
{
for(uint32_t i = 0; i < len; i++)
serverData[i]=(char)buffer[i];
ParseGetRequest( serverData ); ///****** the call
Serial.println(serverData); // prints only part of the values
//here the chip just freeze and stop the main loop
NULL termination !!!!
serverData[len ] = '\0';
I've wrote a program in C to connect the pc with a device by bluetooth. The program runs from terminal and the data received is shown in terminal as well. So far so good.
Now I've created a gui in qt, in which the main aim is to present the information which was before shown in terminal, now in qwtplots.
Well, I can so far connect the device with pc with the gui, but when I request the information form the device, it is shown in the terminal but the gui starts non responding.
here's the slot that requests the information from the device:
// Main Bluetooth
void gui::main_b()
{
// BLUETOOTH STUFF
int status, bytes_read;
int conta = 0;
FILE *data = NULL;
fd_set readmask;
struct timeval tv;
char buf[101];
int v, v1, v2;
tv.tv_sec = 0;
tv.tv_usec = 100000;
// Standard messages
char *startstr = "#START,0060,FF,12;";
write (sock, startstr, strlen (startstr));
data = fopen ("data.txt", "w");
while (conta < 100)
{
int i;
memset (buf, 0, 100);
FD_ZERO (&readmask);
FD_SET (sock, &readmask);
if (select (255, &readmask, NULL, NULL, &tv) > 0)
{
if (FD_ISSET (sock, &readmask))
{
int numb;
numb = read (sock, buf, 100);
// 12 bits
if (ui->comboBox->currentIndex() == 1)
{
if (numb == 14)
{
conta++;
//printf ("received %d bytes:\n", numb);
// print of counter
//printf ("%d,", buf[0]);
fprintf (data, "%d,", buf[0]);
for (i = 1; i < numb-1; i += 3)
{
v1 = buf[i] | ((buf[i + 1] & 0x0F) << 8);
v2 = buf[i + 2];
v2 = (v2 << 4) | ((buf[i + 1] & 0xf0) >> 4);
printf ("%d,%d,", v1, v2);
//fprintf (data, "%d,%d,", v1, v2);
}
printf ("\n");
//fprintf (data, "\n");
}
}
}
}
}
fclose (data);
}
so, when i click the button which calls this slot, it will never let me use the gui again.
This works in terminal.
thanks in advance.
Instead of your own select, you should use QSocketNotifier class and give your own file handles for Qt event loop.
You can also use this overload of QFile::open to turn your socket into a QIODevice instance.
Third choice is to put your own select loop into a different thread, so it does not block the Qt main event loop. But that is going to bring quite a lot of extra complexity, so I'd do that only as a last resort.
You are running the while loop in the same thread as the GUI so the event queue is blocked. You have two choices:
During the loop, call QCoreApplication::processEvents(). This forces the event queue to be processed.
Separate the while loop logic into it's own thread.
The first one is much simpler, but is generally considered inefficient, as just all about all computers have multiple cores.
I have recently written a guide on how to mount partitions from image files on Raspberry Pi.SE. The instructions are rather complicated and I have a bit of time, so want to replace them by a C program. I have successfully listed the partitions of the image and calculated to appropriate offsets.
In the original instructions, we needed to run
$ sudo mount -o loop,offset=80740352 debian6-19-04-2012.img /mnt
I now need to do this in code. I have found the mount function and libmount in util-linux.
I have now found loopdev.c in util-linux. Is there an easy way to create loop devices or do I have to learn from this code and use ioctl?
The following function binds the loop device device to file at offset. It returns 0 on success, 1 otherwise.
int loopdev_setup_device(const char * file, uint64_t offset, const char * device) {
int file_fd = open(file, O_RDWR);
int device_fd = -1;
struct loop_info64 info;
if(file_fd < 0) {
fprintf(stderr, "Failed to open backing file (%s).\n", file);
goto error;
}
if((device_fd = open(device, O_RDWR)) < 0) {
fprintf(stderr, "Failed to open device (%s).\n", device);
goto error;
}
if(ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
fprintf(stderr, "Failed to set fd.\n");
goto error;
}
close(file_fd);
file_fd = -1;
memset(&info, 0, sizeof(struct loop_info64)); /* Is this necessary? */
info.lo_offset = offset;
/* info.lo_sizelimit = 0 => max avilable */
/* info.lo_encrypt_type = 0 => none */
if(ioctl(device_fd, LOOP_SET_STATUS64, &info)) {
fprintf(stderr, "Failed to set info.\n");
goto error;
}
close(device_fd);
device_fd = -1;
return 0;
error:
if(file_fd >= 0) {
close(file_fd);
}
if(device_fd >= 0) {
ioctl(device_fd, LOOP_CLR_FD, 0);
close(device_fd);
}
return 1;
}
References
linux/loop.h
piimg