I'm new to programming the mouse in C, so can someone please expalin me this basic code?
#include <dos.h>
union REGS in, out;
void detect_mouse ()
{
in.x.ax = 0;
int86 (0X33,&in,&out); //invoke interrupt
if (out.x.ax == 0)
printf ("\nMouse Failed To Initialize");
else
printf ("\nMouse was Succesfully Initialized");
}
int main ()
{
detect_mouse ();
getch ();
}
This would be code for old, plain MS DOS which would query if the mouse driver (mouse.com/mouse.sys) is loaded or not.
To talk to mouse.sys, you had to fill some processor registers with specific contents, execute interrupt 0x33, then check the processor registers for return values. That's what the function does. You can find a list of most possible register contents and functions here: http://www.delorie.com/djgpp/doc/rbinter/ix/33/00.html
Related
I'd like to replace/emulate syscalls in a static binary running on 64bit linux 4.4.0-33, preferably using Intel Pin
from the documentation there is PIN_AddSyscallEntryFunction(...)
https://software.intel.com/sites/landingpage/pintool/docs/98484/Pin/html/group__SYSCALL.html
but it seems unable to skip the real syscall, am I missing something? Google didn't do the trick :(
I can try to replace syscall with a invalid id inside syscall entry callback and patching the retval inside syscall exit callback, but I'd rather not do these
there also seems to be other lower level functions(e.g. https://software.intel.com/sites/landingpage/pintool/docs/98484/Pin/html/group__INS__REF.html) but I'd like to try higher level functions first for readability and also to exploit the full potential of Pin and get familiar with the tool
-- BACKGROUND --
I've implemented a virtual file system(of HDFS) using LD_PRELOAD, letting any program able to access HDFS unmodified using a special path /hdfs/..., but it didn't work for static linked binaries, and it has too many interception points(open and also open64, seek and also fseek, fputs etc)
here are the methods that I'v considered, please suggest if there's a better way:
LD_PRELOAD replacing open/read/write/... // not working for static linked binaries, so I'm trying Pin here
ptrace/SYSEMU // it seems too complex and likely to have performance issues
nfs/fuse/... // too complex, need to adapt to too many protocols and can only be used for vfs, can't be extended to support other tech(e.g. hook socket operations) later when needed
replace sysenter/syscall with int3 // should be the same as Pin? and SIGTRAP would be slower
is there any alternatives to Pin? https://github.com/pmem/syscall_intercept also relies on LD_PRELOAD so no luck there
Pin allows to add a call of function before the instruction using INS_InsertCall(). You can add the call of the function before the syscall instruction. This function will check the syscall arguments and emulate the system call if it is necessary. The arguments for system calls are passed only via registers, therefore it is necessary to pass the CONTEXT object to the function. This object keeps the state of the processor and allows to get the register values. Also, this object can be passed to PIN_ExecuteAt() to skip the syscall instruction:
#include "pin.H"
#include <sys/syscall.h>
VOID syscall_handler(CONTEXT* ctx) {
bool skip_orig_sycall = true;
switch (PIN_GetContextReg(ctx, REG_RAX)) {
case SYS_write:
// emulate the syscall here or
// just notify the app that somthing went wrong with write() call
PIN_SetContextReg(ctx, REG_RAX, static_cast<ADDRINT>(-1));
break;
default:
skip_orig_sycall = false;
break;
}
if (skip_orig_sycall) {
const ADDRINT syscall_ins_size = 2;
const ADDRINT cur_ip = PIN_GetContextReg(ctx, REG_RIP);
PIN_SetContextReg(ctx, REG_RIP, cur_ip + syscall_ins_size);
PIN_ExecuteAt(ctx); // continue execution after syscall instruction
}
}
VOID image_load(IMG img, VOID* v) {
if(!IMG_IsMainExecutable(img)) {
return;
}
for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) {
for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) {
RTN_Open(rtn);
for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) {
if (INS_IsSyscall(ins)) {
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)syscall_handler,
IARG_CONTEXT, IARG_END);
}
}
RTN_Close(rtn);
}
}
}
int main(int argc, char* argv[]) {
if (PIN_Init(argc, argv)) {
PIN_ERROR("Cannot initialize Pin");
return EXIT_FAILURE;
}
PIN_InitSymbols();
IMG_AddInstrumentFunction(image_load, 0);
PIN_StartProgram();
return EXIT_SUCCESS;
}
I am using STM32F407 Discovery Board for interfacing USB OTG FS. I am using CubeMx and Keil for development.
First thing first, I have enabled PC0 - USB_Power(for Discovery Board) and the state is RESET for proper USB running.I have enabled PA9 - VBUS as GPIO Input.My System is running at 168MHz.Have used MAX_SS(Max Sector size) - 4096(This option is available in Cube Mx).Enabled USB as Host and used FATFS provided by CubeMX.Enbaled MSC(Mass Storage Class).
CODE:
#include "main.h"
#include "stm32f4xx_hal.h"
#include "fatfs.h"
#include "usb_host.h"
#define GREEN_High HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET)
#define GREEN_Low HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET)
#define ORANGE_High HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_SET)
#define ORANGE_Low HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_RESET)
extern USBH_HandleTypeDef hUsbHostFS;
extern ApplicationTypeDef Appli_state;
FATFS USBDISKFatFs;
FIL MyFile;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void MX_USB_HOST_Process(void);
void Green_Blink(uint16_t ms);
void Orange_Blink(uint16_t ms);
void USB_Write_Demo(char* fileName);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_HOST_Init();
MX_FATFS_Init();
Green_Blink(100);
Orange_Blink(100);
while (1)
{
MX_USB_HOST_Process();
if (Appli_state == APPLICATION_START)
{
USB_Write_Demo("myCSV.csv");
}
*THIS IS THE AREA OF PROBLEM*
// else if (Appli_state == APPLICATION_IDLE)
// {
// GREEN_High;
// ORANGE_High;
// HAL_Delay(100);
// GREEN_Low;
// ORANGE_Low;
// HAL_Delay(100);
// }
}
}
void USB_Write_Demo(char *fileName)
{
FRESULT fres;
uint32_t bytesWritten;
uint8_t w_text[] = {"Hello, I, AM, STM32, Discovery\r\n"};
if (f_mount(&USBDISKFatFs,(TCHAR const*)USBHPath,0) != FR_OK)
{
Orange_Blink(1000);
Error_Handler();
}
else
{
Green_Blink(100);
if (open_append(&MyFile,fileName) != FR_OK)
{
Orange_Blink(100);
Error_Handler();
}
else
{
Green_Blink(100);
fres = f_write(&MyFile,w_text,sizeof(w_text),(void*)bytesWritten);
if (bytesWritten == 0 || fres != FR_OK)
{
Orange_Blink(100);
Error_Handler();
}
else
{
f_close(&MyFile);
Green_Blink(100);
}
}
}
}
void Green_Blink(uint16_t ms)
{
GREEN_High;
HAL_Delay(ms);
GREEN_Low;
HAL_Delay(ms);
}
void Orange_Blink(uint16_t ms)
{
ORANGE_High;
HAL_Delay(ms);
ORANGE_Low;
HAL_Delay(ms);
}
So what is happening here is i am creating a CSV file and with every loop i am appending the new data in it. And i am really succesffull in doing so. I have created a really long(500KB not so long) csv file using this particular code.
But i have found an abnormality here which i am not able to understand.
When i add this part to the code, there is no file created and every iteration the control reaches this function.
else if (Appli_state == APPLICATION_IDLE)
{
GREEN_High;
ORANGE_High;
HAL_Delay(100);
GREEN_Low;
ORANGE_Low;
HAL_Delay(100);
}
I am not able to understand how this function is affecting the working code. I am sure that APPLICATION_START and APPLICATION_IDLE are two diffrent things. When i comment this portion of the code, Everything is just fine i can make files as long as my storage doesn't end.
It took me several hours(like 2days) to figure out this is the problem.
I tried to increase Minimum heap size - 0x2000 and Minimum Stack size - 0x4000 (This option is available on linker setting in cubeMx. While generating file the place where you give the project name,location and all there only)
Any suggestions will be helpful as i am out of ideas.
I found a way to deal with this problem without using RTOS. As i have never tried RTOS before It was difficult to complete the project in few days.
The idea is simple. It is we need to wait till MX_USB_HOST_Process() doesn't returns Appli_state as Idle.
I dont take the credit.
You can check this LINK
so i added a new function in usb_host.c which retuns Appli_state
uint8_t IsUSB_Busy(void)
{
return Appli_state;
}
And in main.c i waited till it returns anything but 0. As APPLICATION_IDLE=0
typedef enum {
APPLICATION_IDLE = 0,
APPLICATION_START,
APPLICATION_READY,
APPLICATION_DISCONNECT
}ApplicationTypeDef;
Added this bit of code in main file and everything is working as expected
while (!IsUSB_Busy())
{
MX_USB_HOST_Process();
}
I hope someone finds it helpful.
And Thanks for your help.
You can create two Tasks (FreeRTOS) with CubeMX, separate the USB stuff from the LED stuff. taskLED() and taskUSB()
How can I catch the timeout exception in a third dll function,I use c language in Windows
I want to catch a timeout Exception while call a thirdly dll function, you know the function takes a long while, and I need it return a value in limited time, if it doesn't return in the time, I will give it a default value.
I have to look for so much infomation about but it doesn't work.
I get the two point:
1.use the alarm function in ,but it only work in Linux,I can't use it in Windows even I use the MinGW standerd GCC complier.
2.use the timeSetEvent function in and the setjmp/longjmp function in ,the three function maybe so closed to take it work.but I use them caused the programe dump,windows pops a DialogMessage say something wrong.
I give the code and the picture like this :
`
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <setjmp.h>
jmp_buf j;
/**
* 时间中断函数
*/
void PASCAL OneMilliSecondProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dwl, DWORD dw2) {
printf("Timout!\n");
longjmp(j,1);
}
int longTimeFunction(){
while (1) {
printf("operating...\n");
Sleep(1000);
}
return 0;
}
int main(){
HANDLE hHandle;
UINT wTimerRes_1ms;//定义时间间隔
UINT wAccuracy; //定义分辨率
UINT TimerID_1ms; //定义定时器句柄
wTimerRes_1ms = 5000;
if((TimerID_1ms = timeSetEvent(
wTimerRes_1ms,
wAccuracy,
(LPTIMECALLBACK)OneMilliSecondProc, // 回调函数
(DWORD)(1), // 用户传送到回调函数的数据;
TIME_PERIODIC//周期调用定时处理函数
)) == 0) {
printf("start!!!!!!!!!!!\n");
} else {
printf("end!!!!!!!!!!!\n");
}
int temp = 0;
if(setjmp(j) == 0){
temp = longTimeFunction();
}else{
printf("xxxxxx...\n");
temp = -1;
}
printf("%d\n", temp);
return 0;
}
`
Unlike UNIX signals, timeSetEvent doesn't interrupt a thread, the callback runs in parallel and longjmping across threads is undefined behavior.
Concerning your actual question, this is a bad idea. Such an abortion could leave the library in an inconsistent state.
Instead, try to get the library vendor to offer an API that accepts a timeout, or use another library that already supports it.
I have a light sensor that prints the value of its input to the Serial monitor. It's pretty much a trip wire but when an object is in its way, it prints the value every 1 millisecond. If I add a delay it won;t trigger the second sensor until the delay is done. How would I get it to only print once, without any disturbance or interference with the other sensors?
void loop() {
if (analogRead(sensor1) == 0) {
timer.start ();
tStop = false;
//Serial.println (timer.elapsed());
Serial.println ("Start Time = 0");
}
This is quite an interesting problem, in the normal world of computers we would solve this via threading. However as you are running without an OS we have to do one of two things, implement coroutines (fake threading without an OS) or use asynchronous code and interrupts.
My understanding is that you print something when an object first comes into the way of your sensor, as the arduino uno as opposed to the due is not easy to implement coroutines on we shall try the interrupt route.
First you will likely be interested in this library http://playground.arduino.cc/Code/Timer1
It allows you to add an interrupt service routine to run on a timer. Use the attachInterrupt(function, period) function in the library for this.
In your interrupt service routine you will want to check the sensor, set a variable to say how long ago since it was last triggered and print the message if appropriate. This means your main loop is completely free to run other code and will not block your other sensors.
For example:
void TimFun()
{
static int LastRead;
if(LastRead && (0 == analogRead(sensor1))
{
Serial.println("SensorTrip");
}
LastRead = analogRead(sensor1);
}
void loop()
{
// Do other stuff here
}
void setup()
{
Timer1.initialize(100000);
Timer1.attachInterrupt(TimFun);
// Rest of setup Here
}
I managed to make an int before the void setup and then used a while loop. with in the if statement.
int i = 1;
if (analogRead(sensor1) == 0) {
timer.start ();
tStop = false;
while (i == 1) {
Serial.println ("Start Time = 0");
i++;
}
}
You probably should use an if instead of a while loop that will never execute more than once.
bool tripped = false;
void setup(){
//setup stuff here
}
void loop() {
if ( analogRead(sensor1) == 0 )
{
timer.start ();
tStop = false;
if ( tripped == false )
{
Serial.println ("Start Time = 0");
tripped = true;
}
}
}
I have this loop, how would I end the loop?
void loop() {
// read the pushbutton input pin:
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300){
analogWrite(speakerOut, 200);
}
if(a <= 49){
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499){
analogWrite(speakerOut, NULL);
}
This isn't published on Arduino.cc but you can in fact exit from the loop routine with a simple exit(0);
This will compile on pretty much any board you have in your board list. I'm using IDE 1.0.6. I've tested it with Uno, Mega, Micro Pro and even the Adafruit Trinket
void loop() {
// All of your code here
/* Note you should clean up any of your I/O here as on exit,
all 'ON'outputs remain HIGH */
// Exit the loop
exit(0); //The 0 is required to prevent compile error.
}
I use this in projects where I wire in a button to the reset pin. Basically your loop runs until exit(0); and then just persists in the last state. I've made some robots for my kids, and each time the press a button (reset) the code starts from the start of the loop() function.
Arduino specifically provides absolutely no way to exit their loop function, as exhibited by the code that actually runs it:
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
Besides, on a microcontroller there isn't anything to exit to in the first place.
The closest you can do is to just halt the processor. That will stop processing until it's reset.
Matti Virkkunen said it right, there's no "decent" way of stopping the loop. Nonetheless, by looking at your code and making several assumptions, I imagine you're trying to output a signal with a given frequency, but you want to be able to stop it.
If that's the case, there are several solutions:
If you want to generate the signal with the input of a button you could do the following
int speakerOut = A0;
int buttonPin = 13;
void setup() {
pinMode(speakerOut, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
}
int a = 0;
void loop() {
if(digitalRead(buttonPin) == LOW) {
a ++;
Serial.println(a);
analogWrite(speakerOut, NULL);
if(a > 50 && a < 300) {
analogWrite(speakerOut, 200);
}
if(a <= 49) {
analogWrite(speakerOut, NULL);
}
if(a >= 300 && a <= 2499) {
analogWrite(speakerOut, NULL);
}
}
}
In this case we're using a button pin as an INPUT_PULLUP. You can read the Arduino reference for more information about this topic, but in a nutshell this configuration sets an internal pullup resistor, this way you can just have your button connected to ground, with no need of external resistors.
Note: This will invert the levels of the button, LOW will be pressed and HIGH will be released.
The other option would be using one of the built-ins hardware timers to get a function called periodically with interruptions. I won't go in depth be here's a great description of what it is and how to use it.
The three options that come to mind:
1st) End void loop() with while(1)... or equally as good... while(true)
void loop(){
//the code you want to run once here,
//e.g., If (blah == blah)...etc.
while(1) //last line of main loop
}
This option runs your code once and then kicks the Ard into
an endless "invisible" loop. Perhaps not the nicest way to
go, but as far as outside appearances, it gets the job done.
The Ard will continue to draw current while it spins itself in
an endless circle... perhaps one could set up a sort of timer
function that puts the Ard to sleep after so many seconds,
minutes, etc., of looping... just a thought... there are certainly
various sleep libraries out there... see
e.g., Monk, Programming Arduino: Next Steps, pgs., 85-100
for further discussion of such.
2nd) Create a "stop main loop" function with a conditional control
structure that makes its initial test fail on a second pass.
This often requires declaring a global variable and having the
"stop main loop" function toggle the value of the variable
upon termination. E.g.,
boolean stop_it = false; //global variable
void setup(){
Serial.begin(9600);
//blah...
}
boolean stop_main_loop(){ //fancy stop main loop function
if(stop_it == false){ //which it will be the first time through
Serial.println("This should print once.");
//then do some more blah....you can locate all the
// code you want to run once here....eventually end by
//toggling the "stop_it" variable ...
}
stop_it = true; //...like this
return stop_it; //then send this newly updated "stop_it" value
// outside the function
}
void loop{
stop_it = stop_main_loop(); //and finally catch that updated
//value and store it in the global stop_it
//variable, effectively
//halting the loop ...
}
Granted, this might not be especially pretty, but it also works.
It kicks the Ard into another endless "invisible" loop, but this
time it's a case of repeatedly checking the if(stop_it == false) condition in stop_main_loop()
which of course fails to pass every time after the first time through.
3rd) One could once again use a global variable but use a simple if (test == blah){} structure instead of a fancy "stop main loop" function.
boolean start = true; //global variable
void setup(){
Serial.begin(9600);
}
void loop(){
if(start == true){ //which it will be the first time through
Serial.println("This should print once.");
//the code you want to run once here,
//e.g., more If (blah == blah)...etc.
}
start = false; //toggle value of global "start" variable
//Next time around, the if test is sure to fail.
}
There are certainly other ways to "stop" that pesky endless main loop
but these three as well as those already mentioned should get you started.
This will turn off interrupts and put the CPU into (permanent until reset/power toggled) sleep:
cli();
sleep_enable();
sleep_cpu();
See also http://arduino.land/FAQ/content/7/47/en/how-to-stop-an-arduino-sketch.html, for more details.
just use this line to exit function:
return;