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 8 years ago.
Improve this question
i try to learn internals of Windows OS.
is SSDT defined as "all system calls address list" ?
is SSDT also interrupt handling mechanism that allows to catch hardware events?
Thanks for answers now.
No, SSDT is not how the OS catches hardware events. If we start at the hardware, say a PCI card for a network adapter, it will have a signal of type interrupt, which via the PCI interface goes to an interrupt controller. In a PC, that would be an "APIC" (Advanced Programmable Interrupt Controller), which in turn is connected to the processor core(s) themselves. Other hardware works in a similar way, so I will use APIC as the example below.
When the OS initializes the APIC, it will give each hardware interrupt a "vector", which goes into the interrupt vector table - each interrupt vector entry will contain an address to which the processor jumps when that interrupt is active. In x86, the interrupt vector table is called "Interrupt Descriptor Table", because the vector is more than a simple address to jump to - it also contains a little bit of extra information about HOW to deal with the interrupt and so on.
So when our network adapter receives a packet of data, it will "pull" the interrupt signal active. The processor will then detect the interrupt, and when it does, the interrupt controller gives the vector to use. The processor looks up the vector, saves the current state, and jumps to the address in the vector.
Inside the vector, the OS will do some "admin" work, and then look up which device driver has asked to be informed about this interrupt, so the OS finds our network adapter driver, and calls it's interrupt handling routine. The interrupt handling code checks the state of the network adapter, sees that it was a "new packet arrived" type of interrupt, reads out the data from the buffer and probably updates some semaphore or similar so that some driver function can start to execute the "we've recieved a new packet" code. Once that is done the interrupt handler returns back to the OS.
On return from the interrupt handling code, the OS will check if any "new process got wakened up", so the process waiting for packets will now be "runnable", and it may switch process at this point, or just mark it as "run this in the future".
The SSDT is used for when an application calls, say, CreateFile, ReadFile, WriteFile and CloseHandle, and any other system calls (there are quite a lot of them). Basically, there is an entry in the SSDT for NtCreateFile, another for NtReadFile and so on - note that NtCreateFile is not exactly the same as CreateFile - it is the part that happens inside the OS Kernel.
Related
I recently started experimenting with I2C-Hardware on my raspberry pi. Following this tutorial Using the I2C interface I already know how to read and set values. However, the program I want to realize needs the current value on a specific address all the time. So, I made a thread and query the value constantly in a never ending loop, which seems primitive to me. Is it possible to get notified in an event-like manner when a value on an I2C-adress changes?
A platform independend solution would also be much welcomed.
I was able to get what I wanted.
I use the following repeater for the I2C-Bus: link and it turns out there is a soldering bridge (LB2) you can set that sets a signal on GPIO17 whenever a value on the I2C-Bus changes since it has last been changed. I can now listen on this events accordingly.
Generally speaking, the I2C bus has no interrupt capability. So with only I2C, all you can do is poll the chip for a certain event to happen or value to change.
Most chips do have an interrupt line (sometimes even more than one) that can be programmed to trigger on certain events. The behavior of this line depends on the chip. Usually it needs to be enabled (using I2C commands) and it needs to be linked to a GPIO input line. For these, interrupt support is available.
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 3 years ago.
Improve this question
I'm new to embedded programming and I apologise in advance for any confusion.
I need to handle multiple events from different devices connected to a gpio. These events need to be monitored continually. This means that after one event is generated and handled, the code needs to keep monitoring the device for other events.
I understand the concept of interruptions and polling in Linux (the kernel gets an interruption and dispatch it to the handler which goes on up to the callee of an epoll which is inside an infinite loop while(1)-like).
This is fine for one-time, single-event toy models. In a embedded system with limited resources such as the AT91SAM9x5 that runs at 400mhz and has 128mb of ram what can I do ? I believe that the while(1)-like pattern isn't the best choice. I've heard good things about thread pool solution but at the heart of each thread don't we find a while(1) ?
What are my options to attack this problem ?
Thank you in advance !
For an embedded system, the AT91SAM is actually quite "resource rich" rather than resource limited. The idea is the same as if you writing it using Linux: you set up a pin interrupt, and in your interrupt handler, you do some minimal processing and maybe set up some global data so that your main loop "while (1)" can detect the situation and then process the information in the non-interrupt context. Basically you want the interrupt handler to finish as quickly as possible so that it can handle the next interrupt.
In most systems, interrupts can be pended or nested. With systems that allow nested interrupts, you have to make sure that it does not trash the context of the previous interrupt that is still being executed.
The actual communication scheme between the interrupt handler and the main code depends on your requirement. You can even use an RTOS with support for such requirements.
It depends a lot on what is your application and what are your constrains but here are some of the common methods to monitor gpio pins for event
In many of the newer controllers, all GPIO pins are capable of generating a combined interrupt. You can use this to trigger an ISR call on any change on any of the pins and then inside the ISR detect which specific pin triggered it.
If there is nothing else your controller should be doing, then there is nothing wrong is a while(1) loop continuously monitoring all port pins and triggering relevant actions
If none of the above solutions are acceptable, you can perhaps try to load a small OS like FreeRTOS on your controller and then use different tasks to monitor port pins
A lighter version of the above method is to have a configure a timer interrupt and poll for all the port pins inside it. You can then save the state of pins in global variable and use that in the main loop to take relevant actions.
Not sure whether I should post this here or not but I gotta ask.
Context :
Linux on an embedded platform (CPU #~500MHz)
One team working on the single userspace software
One team working on Linux + driver + uboot etc.
The software has to handle GPIO, some are output (write when needed), some are input (read when needed for some, preferably interrupt-like for others).
The software is a multi-threaded app with ~10-15 threads in SCHED_FIFO scheduling policy.
Let's say I have a module called WGPIO which is a wrapper handling GPIO. (this is developed by the Linux team btw. WGPIO is still in user-space, but they could develop a driver if needed)
Here is some pseudo_code of what is designed as we speak.
gpio_state state = ON;
// IO_O is output. Set to ON, don't care if it's active_high or active_low btw
WGPIO_WriteOutput(IO_O,state);
// IO_I is input, read when needed
WGPIO_ReadInput(IO_I,&state);
// register callback when rising edge occurs on IO named IO_IT
WGPIO_SetCallback(IO_IT,EDGE_RISING,my_callback);
// Unmask to enable further IT-like processing
WGPIO_UnmaskIRQ(IO_IT);
I must be able to handle some of the GPIO changes in 5 to 10ms.
Is some userspace polling (WGPIO would have a SCHED_FIFO thread then) on multiple FDs enough to simulate an "interrupt-like" handling in my app ? This looks like the most simple idea.
If you need more details, feel free to ask.
Thanks in advance.
From kernel gpio/sysfs.txt:
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
is configured as an output, this value may be written;
any nonzero value is treated as high.
If the pin can be configured as interrupt-generating interrupt
and if it has been configured to generate interrupts (see the
description of "edge"), you can poll(2) on that file and
poll(2) will return whenever the interrupt was triggered. If
you use poll(2), set the events POLLPRI and POLLERR. If you
use select(2), set the file descriptor in exceptfds. After
poll(2) returns, either lseek(2) to the beginning of the sysfs
file and read the new value or close the file and re-open it
to read the value.
"edge" ... reads as either "none", "rising", "falling", or
"both". Write these strings to select the signal edge(s)
that will make poll(2) on the "value" file return.
This file exists only if the pin can be configured as an
interrupt generating input pin.
The preferred way is usually to configure the interrupt with /sys/class/gpio/gpioN/edge and poll(2) for POLLPRI | POLLERR (important it's not POLLIN!) on /sys/class/gpio/gpioN/value. If your process is some "real-time" process that needs to handle the events in real time, consider decreasing it's niceness.
You can even find some example code on github that uses poll, ex. this repo.
I have a Qt application that runs on Linux.
The user can switch the system to mem sleep using this application.
Switching to mem sleep is trivial, but catching the wake up event in user space isn't.
My current solution is to use a infinite loop to trap the mem sleep, so that when the system wakes up, my application always continues from a predictable point.
Here is my code:
void MainWindow::memSleep()
{
int fd;
fd = ::open("/sys/power/state", O_RDWR);// see update 1)
QTime start=QTime::currentTime();
write(fd,"mem",3); // command that triggers mem sleep
while(1){
usleep(5000); // delay 5ms
const QTime &end=QTime::currentTime();// check system clock
if(start.msecsTo(end)>5*2){// if time gap is more than 10ms
break; // it means this thread was frozen for more
} // than 5ms, indicating a wake up after a sleep
start=end;
}
:: close(fd); // the end of this function marks a wake up event
}
I described this method as a comment on this question, and it was pointed out that it's not a good solution, which I agree.
Question: Is there a C API that I can use to catch the wake up event?
Update:
1) what is mem sleep?
https://www.kernel.org/doc/Documentation/power/states.txt
The kernel supports up to four system sleep states generically, although three
of them depend on the platform support code to implement the low-level details
for each state.
The states are represented by strings that can be read or written to the
/sys/power/state file. Those strings may be "mem", "standby", "freeze" and
"disk", where the last one always represents hibernation (Suspend-To-Disk) and
the meaning of the remaining ones depends on the relative_sleep_states command
line argument.
2) why do I want to catch the wake up event?
Because some hardware need to be reset after a wake up. A hardware input device generates erroneous input events after system wakes up, so it has to be disabled before sleep(easy) and enable after wake up(this question).
This should/could be handled by the driver in the kernel, which I have access to, or fixed in hardware, which my team can do but does not have the time to do it.(why I, a app developer, need to fix it in user space)
3) constraints
This is embedded linux, kernel 2.6.37, arch:arm, march:omap2, distro:arago. It's not as convenient as PC distros to add packages, not does it have ACPI. And mem sleep support in kernel 2.6.37 isn't mature at all.
Linux device drivers for PCI devices can optionally handle suspend and resume which, presumably, the kernel calls, respectively, just before the system is suspended, and just after resuming from a suspend. The PCI entrypoints are in struct pci_driver.
You could write and install a trivial device driver which does nothing more than sense resume operations and provides an indication to any interested processes. The simplest might be to support a file read() which returns a single byte whenever a resume is sensed. The program only need open the device and leave a thread stuck reading a single character. Whenever the read succeeds, the system just resumed.
More to the point, if the devices your application is handling have device drivers, the drivers should be updated to react appropriately to a resume.
When the system wakes from sleep, it should generate an ACPI event, so acpid should let you detect and handle that: via an /etc/acpi/events script, by connecting to /var/run/acpid.socket, or by using acpi_listen. (acpi_listen should be an easy way to test if this will work.)
Check pm-utils which you can place a hook at /etc/pm/sleep.d
In the hook you can deliver signal to your application, e.g. by kill or any IPC.
You can also let pm-utils to do the computer suspend, which IMO is far more compatible with different configurations.
EDIT:
I'm not familiar with arago but pm-utils comes with arch and ubuntu.
Also note that, on newer system that uses systemd, pm-utils is obsoleted and you should instead put hooks on systemd.
REF: systemd power events
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 9 years ago.
Improve this question
I have a motor connected to my computer, which is connected through CAN to the motor. Basically, I have a USB-to-CAN adapter, to which I connect a USB cable from my computer. Then, from the adapter, the motor is connected through CAN.
Now, I wish to send data to the motor- I already know what sequence of bytes I need to send, but I'm not sure what commands to use to "talk" to my motor that is connected through CAN. I have been able to send data by direct USB connection from my computer to motor (using the WriteFile command in C++), but this method does not work for CAN.
Are there any libraries/functions that I can use to talk to my motor via CAN in C++?
Since you cannot connect a motor directly to a CAN bus, there must be some sort of motor controller, drive or I/O controller between the bus. Details of this device are required in order to advise on a more than fundamental level.
CAN itself does not define an application layer protocol, and several application protocols exist for CAN, such as CANopen, DeviceNet and SDS. Your device may use such a protocol or possibly something entirely proprietary. Your starting point should be the documentation for your I/O device.
For testing, most PC CAN adapter manufacturers will provide some sort of debug or development tool that allows you to construct and send individual messages and message sequences at a low-level; such a tool will allow you to verify the operation of the bus and I/O device.