I want to know how can I get a keyboard input in contiki os.
I already tried getchar(),getch(),scanf(),gets() and none worked, so I want to know if somebody can help me.
getchar,getch,scanf,gets are sort of POSIX things that read from files (e.g. stdin) --- these don't exist in Contiki (all though you could probably use them with the native platform).
So the first question to ask is what platform are you using and what do you mean by "keyboard". If keyboard means typing characters that are sent via a serial port from a computer then you have to know where they are received on the thing running Contiki. A typical arrangement is to receive characters on a uart, say, uart1.
In this case, contiki uses a callback such as uart1_input_handler that will be defined by the application. Platform main loops will check if there are characters to send to the input_handler and then check that an input_handler is defined. If so, will call something like uart1_input_handler(c).
You can see this code for the various platforms by grepping for uart1_input_handler:
platform/redbee-econotag/contiki-mc1322x-main.c: uart1_input_handler(uart1_getc());
cpu/msp430/dev/uart1x.c: if(uart1_input_handler(c)) {
cpu/stm32w108/dev/uart1.c: uart1_input_handler(c);
etc...
Some examples that register an input handler and process the characters:
example/shell:
/* set up the shell */
uart1_set_input(serial_line_input_byte);
serial_line_init();
serial_shell_init();
slip, in examples/ipv6/rpl-border-router/slip-bridge.c
slip_set_input_callback(slip_input_callback);
My guess for what you want to do would be to start with the shell examples and try to get those working.
The example cited below is from the Wiki pages of contiki on github. It demonstrates how the contiki specific mechanism for serial input works. Like mariano mentioned above that a callback has to be defined for the serial drivers specific to the platform you are using. I have used for ex. "rs232_set_input(RS232_PORT_0, serial_line_input_byte) ; " for my atmega128 MCU. The serial i/o drivers use this callback mechanism to post input characters to the "serial_line_process" defined in serial-line.c file. This process then broadcasts the serial_line_event_message to all processes along with the data read on the serial line. A process like the eg. stated below, can catch this event and process the input as per the requirements.
The callback mentioned above is defined in $(CONTIKI)/core/dev/serial-line.c. Check that out.
Once you initialise it using serial_line_init(), you are good to go.
#include "contiki.h"
#include "dev/serial-line.h"
#include <stdio.h>
PROCESS(test_serial, "Serial line test process");
AUTOSTART_PROCESSES(&test_serial);
PROCESS_THREAD(test_serial, ev, data)
{
PROCESS_BEGIN();
for(;;) {
PROCESS_YIELD();
if(ev == serial_line_event_message) {
printf("received line: %s\n", (char *)data);
}
}
PROCESS_END();
}
I assume you use COOJA (or maybe you connected a keyboard to your device so my answer will not be correct).
COOJA is an emulator, not a simulator.
If you want a responsive design, use the sensor button (on sky platform for example)
SENSORS_ACTIVATE(button_sensor);
/* Wait until we get a sensor event with the button sensor as data. */
PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event &&
data == &button_sensor);
Hope it helped.
Related
Issue
-When using the ESP8266 wired up in this way it will randomly disconnect the USB interface when it powers the relay. It may then re-connect but is sporadic.
-The code can be viewed below, but essentially the relay is powered for 300ms then waits 10 seconds to loop.
Wiring Diagram https://i.stack.imgur.com/4mycx.png
Tests:
I have swapped out the relay, pump, ESP8266, aswell as re-wiring the circuit multiple times to check for a short. I also have a integer incrementing every loop cycle, when the ESP8266 is able to re-connect it will print this variable, which shows the board is not crashing:
Serial output
https://i.stack.imgur.com/ziM8g.png
I then modified the diagram so the 5v power was not in parallel, but where two different power sources, one for the ESP8266 and one for the pump circuit, however the same issue was observed:
Test Wiring Diagram https://i.stack.imgur.com/7S0aP.png
Question:
Why does the USB disconnect when sending the control signal to the relay?
Is there a way to mitigate this?
Code:
int relayInput = 5; // the input to the relay pin
int debug_test = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(relayInput, OUTPUT); // initialize pin as OUTPUT
}
void loop() {
// put your main code here, to run repeatedly:
debug_test ++ ;
Serial.println(debug_test);
digitalWrite(relayInput, HIGH); // turn relay on
Serial.println("Water on!");
delay(300);
digitalWrite(relayInput, LOW); // turn relay off
Serial.println("Water off!");
Serial.println("Waiting 10 seconds");
delay(10000);
}
Parts:
Pump - https://www.ebay.co.uk/itm/Mini-Water-Pump-DC-3V-4-5V-Fish-Tank-Fountain-Aquarium-Submersible-White-Parts/174211676084?hash=item288fd337b4:g:128AAOSwfQteYWF3
ESP8255 - https://www.amazon.co.uk/gp/product/B07F5FJSYZ/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
Relay - https://www.amazon.co.uk/gp/product/B07BVXT1ZK/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1
Ok, so researching in to this, it seems when the pump is on it pulls more current (amps) than the PC can provide.
This will be used connected to a external power source which should supply enough current to it, however I also wanted the flexibility to connect it to a PC with a serial connection to troubleshoot.
So in the end something like this:
https://i.stack.imgur.com/MKD1h.png
You are driving a 5v relay module with 3.3v output, which works perfectly for some people but it depends on the relay module and the board, this might be the problem. or the relay draws more than 12mA which is the maximum current can the ESP8266's GPIO deliver.
so I suggest you use an external power source for the relay and control it through the pin (D1 in your case).
Or just use a generic 5v relay with an external 5v power source and control it using a transistor, here is a circuit.
Additional information: https://electronics.stackexchange.com/questions/213051/how-do-i-use-a-5v-relay-with-a-3-3v-arduino-pro-mini?
I have a configuration setup with two CAN nodes and an attached database. I have added a CANOEILNLVECTOR.dll to both the nodes. By adding this Dll file all my messages are sent cyclic as I see in trace window.
Now I set some value for a signal in a message, For Eg:
variables
{
message Battery_Traction Batt_msg;
}
on start
{
Batt_msg.Isolation_Signal = 0x02; //0x02:On
output(Batt_msg);
}
What I see on trace is: The message is cyclic but only for the first instance the value set by me above appears in trace. For all of the rest times the signal value in the message in set to default.
As seen in the image value 0x02 is sent only once.
I am not sure what could be the problem, as seen in image attached value set by me is only sent once.
When using output you are putting the message directly onto the CAN bus, but you are not changing the value inside of your (simulated) node, so the interaction layer is still sending the old value.
You can change the signal value in the interaction layer by just putting a $ in front of the signal name and set the value.
In your case most likely $Isolation_Signal = 0x02
Outputting the message on the CAN bus at the right time, with the right cycle time and so on will be handled by the interaction layer.
You have two ways to influence dynamically the value of your message: IL DLLs and custom message sending.
Custom message sending is the basic way, where
you define the message ex.: message Battery_Traction Batt_msg;
you trigger its sending(output function)
you set up cyclic sending on timer Cycletimemsg1 {output(msg1);}
and so on.
IL DLLs are doing this all for you, without much coding effort from your side, but they rely heavily on the dbc settings and attributes you have linked as database to your CAN Channel.
Unfortunately, they don't play well together, meaning you need advanced CANoe know-how of them to use both in the same environment. You basically bypassed your CANOEILNLVECTOR.dlls working by sending explicit message.
So your code if you are accessing your signal through IL, should look like this:
variables
{
/*no need to define custom message object, they are already "known" to IL by dbc*/
}
on start
{
$Batt_msg::Isolation_Signal = 0x02; //0x02:On
/*NO need for output either (IF YOUR MESSAGE IS defined Cyclic in dbc), */
}
If your signal is not identified at $Batt_msg::Isolation_Signal, just dragndrop the signal from the CAPL browsers Symbols panel, and add the $ sign before it.
Through dollar($) sign, you access the dbsignal class objects signal value attribute.
Does anyone know if there is an API to get the current monitor state (on or off) in Windows (XP/Vista/2000/2003)?
All of my searches seem to indicate there is no real way of doing this.
This thread tries to use GetDevicePowerState which according to Microsoft's docs does not work for display devices.
In Vista I can listen to GUID_MONITOR_POWER_ON but I do not seem to get events when the monitor is turned off manually.
In XP I can hook into WM_SYSCOMMAND SC_MONITORPOWER, looking for status 2. This only works for situations where the system triggers the power off.
The WMI Win32_DesktopMonitor class does not seem to help out as well.
Edit: Here is a discussion on comp.os.ms-windows.programmer.win32 indicating there is no reliable way of doing this.
Anyone else have any other ideas?
GetDevicePowerState sometimes works for monitors. If it's present, you can open the \\.\LCD device. Close it immediately after you've finished with it.
Essentially, you're out of luck—there is no reliable way to detect the monitor power state, short of writing a device driver and filtering all of the power IRPs up and down the display driver chain. And that's not very reliable either.
You could hook up a webcam, point it at your screen and do some analysis on the images you receive ;)
Before doing anything based on the monitor state, just remember that users can use a machine with remote desktop of other systems that don't require a monitor connected to the machine - so don't turn off any visualization based on the monitor state.
You can't.
Look like all monitor power capabilities connected to the "power safe mode"
After searching i found here code that connecting between SC_MONITORPOWER message and system values (post number 2)
I use the code to testing if the system values is changing when i am manually switch off the monitor.
int main()
{
for(;monitorOff()!=1;)
Sleep(500);
return 0;
}//main
And the code is never stopped, no matter how long i am switch off my monitor.
There the code of monitorOff function:
int monitorOff()
{
const GUID MonitorClassGuid =
{0x4d36e96e, 0xe325, 0x11ce,
{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
list<DevData> monitors;
ListDeviceClassData(&MonitorClassGuid, monitors);
list<DevData>::iterator it = monitors.begin(),
it_end = monitors.end();
for (; it != it_end; ++it)
{
const char *off_msg = "";
//it->PowerData.PD_PowerStateMapping
if (it->PowerData.PD_MostRecentPowerState != PowerDeviceD0)
{
return 1;
}
}//for
return 0;
}//monitorOff
Conclusion : when you manually switch of the the monitor, you cant catch it by windows (if there is no unusual driver interface for this), because all windows capabilities is connected to "power safe mode".
In Windows XP or later you can use the IMSVidDevice Interface.
See
http://msdn.microsoft.com/en-us/library/dd376775(VS.85).aspx
(not sure if this works in Sever 2003)
With Delphi code, you can detect invalid monitor geomerty while standby in progress:
i := 0
('Monitor'+IntToStr(i)+': '+IntToStr(Screen.Monitors[i].BoundsRect.Left)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Top)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Right)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Bottom))
Results:
Monitor geometry before standby:
Monitor0: 0, 0, 1600, 900
Monitor geometry while standby in Deplhi7:
Monitor0: 1637792, 4210405, 31266576, 1637696
Monitor geometry while standby in DeplhiXE:
Monitor0: 4211194, 40, 1637668, 1637693
This is a really old post but if it can help someone, I have found a solution to detect a screen being available or not : the Connecting and Configuring Displays (CCD) API of Windows.
It's part of User32.ddl and the interesting functions are GetDisplayConfigBufferSizes and QueryDisplayConfig. It give us all informations that can be viewed in the Configuration Panel of windows.
In particular the PathInfo contains a TargetInfo property that have a targetAvailable flag. This flag seems to be correctly updated on all the configurations I have tried so far.
This allow you to know the state of every screens connected to the PC and set their configurations.
Here a CCD wrapper for .Net
If your monitor has some sort of built-in USB hub, you could try and use that to detect if the monitor is off/on.
This will of course only work if the USB hub doesn't stay connected when the monitor is consider "off".
My team has been trying to send data through a CC2520 using a
MSPEXP430F5438 board. We tried using the FIFO_READ and FIFO_WRITE
command but it was of no avail. We also tried using the RAM_READ and
RAM_WRITE command but still the results were the same. We checked the
interfacing of MSP430 and CC2520 and that seems fine. Could anyone
suggest some way to find out where our problem lies(sender/reciever)?
Regards, Pratyush
At a high level, the CC2520 is a SPI-controlled state machine. This means that the radio transceiver requires a particular sequence of commands to transmit or receive data.
I would recommend taking a look at Section 21 (page 85, when written) within the CC2520 Datasheet. Additionally, Section 19 and 20 shows the TX and RX procedure, respectively.
SmartRF Studio is often the easiest way to get started, as it has a full GUI interface to the radio. However, you may need to purchase the CC2520 dev kit or have a supported baseboard for the CC2520. I believe the MSP-EXP430F5438 board does not support SmartRF Studio, but I could not easily find the answer. I know SmartRF studio recognizes the MSP-EXP430F5438 when you launch the software, but I'm not sure the software can use the MSP-EXP430F5438 as a baseboard for the desktop GUI control of the radio.
If you want to program a "hello world" onto your MSP-EXP430F5438 and CC2520, I recommend using TI's provided sample code for the CC2520, and perusing the CC2520 page.
For TI's CCxxxx radios, in C pseudo-code, to transmit/send a message you might do the following:
SPI_Strobe(IDLE); /* Reset radio state machine to 'start' state (IDLE) */
SPI_WriteBurstReg(TXFIFO, tx_data, tx_data_length); /* Write data to TX FIFO */
SPI_Strobe(TX); /* Start radio transmission */
_BIS(LPM3+GIE); /* While TX finishes, sleep MCU with general interrupt enable */
/* Use GPIO to interrupt. When TX is finished, RETI from ISR */
/* and continue to next line */
SPI_Strobe(FLUSH_TXFIFO); /* Flush TX buffer (optional) */
SPI_Strobe(IDLE); /* Reset radio state machine to 'start' state (IDLE)
/* Can auto enter IDLE when TX done - see doc. */
SPI_Strobe(PWR_DOWN); /* Turn off radio to save power (optional) */
Above, I'm using all-caps to indicate a static address/byte definition from a header file.
How would one go about modifying individual assembly instructions in an application while it is running?
I have a Mobile Substrate tweak that I am writing for an existing application. In the tweak's constructor (MSInitialize), I need to be able to rewrite individual instruction(s) in the app's code. What I mean by this is that there may be multiple places in the application's address space that I wish to modify, but in each instance, only a single instruction needs to be modified. I have already disabled ASLR for the application and know the exact memory address of the instruction to be patched, and I have the hex bytes (as a char[], but this is uninportant and can be changed if necessary) of the new instruction. I just need to figure out how to perform the change.
I know that iOS uses Data Execution Prevention (DEP) to specify that executable memory pages cannot also be writeable and vice versa, but I know that it is possible to bypass this on a jailbroken device. I also know that the ARM processor used by iDevices has an instruction cache that needs to be updated to reflect the change. However, I do not even know where to begin to do this.
So, to answer the question that would surely otherwise be asked, I have not tried anything. This is not because I am lazy; rather, it is because I have absolutely no clue how this could be accomplished. Any help at all would be greatly appreciated.
Edit:
If it helps at all, my ultimate goal is to use this in a Mobile Substrate tweak that hooks an App Store application. Previously, in order to mod this application, one would have to first crack it to decrypt the app so the binary could be patched. I want to make it so people wouldn't have to crack the app, since that can lead to piracy which I am strongly against. I can't use Mobile Substrate normally because all of the work is done in C++, not Objective-C, and the application is stripped, leaving no symbols to use MSHookFunction on.
Completely forgot I asked this question, so I'll show what I ended up with now. The comments should explain how and why it works.
#include <stdio.h>
#include <stdbool.h>
#include <mach/mach.h>
#include <libkern/OSCacheControl.h>
#define kerncall(x) ({ \
kern_return_t _kr = (x); \
if(_kr != KERN_SUCCESS) \
fprintf(stderr, "%s failed with error code: 0x%x\n", #x, _kr); \
_kr; \
})
bool patch32(void* dst, uint32_t data) {
mach_port_t task;
vm_region_basic_info_data_t info;
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT;
vm_region_flavor_t flavor = VM_REGION_BASIC_INFO;
vm_address_t region = (vm_address_t)dst;
vm_size_t region_size = 0;
/* Get region boundaries */
if(kerncall(vm_region(mach_task_self(), ®ion, ®ion_size, flavor, (vm_region_info_t)&info, (mach_msg_type_number_t*)&info_count, (mach_port_t*)&task))) return false;
/* Change memory protections to rw- */
if(kerncall(vm_protect(mach_task_self(), region, region_size, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY))) return false;
/* Actually perform the write */
*(uint32_t*)dst = data;
/* Flush CPU data cache to save write to RAM */
sys_dcache_flush(dst, sizeof(data));
/* Invalidate instruction cache to make the CPU read patched instructions from RAM */
sys_icache_invalidate(dst, sizeof(data));
/* Change memory protections back to r-x */
kerncall(vm_protect(mach_task_self(), region, region_size, false, VM_PROT_EXECUTE | VM_PROT_READ));
return true;
}
vm_protect to w^x, assuming you're jailbroken with a decent jailbreak (e.g. if mobilesubstrate works)
Writing to instruction memory from processor registers is, as others say above, a bit tricky. Especially with iPhones, since Apple tries to keep the processor details secret.
Permissions on memory access are the first problem. Executable memory is not normally writable. However, if this is overcome, then there is a little dance to go through to get data out of the processor registers and into the instruction pipeline. In general, there are synchronisation instructions, which force a specific order on the memory accesses before and after them, and cache commands, which force dirty write data out to memory and flush out clean and possibly stale read data. Both of these are highly dependent on the detailed implementation of the processor.
Arm Has nice manuals on the web that explain these in detail for specific processors. However, whether the processors inside iPhones do what the public Arm manuals say, I have no idea.
Here's a place to start understanding the Arm memory synchronisation model for one processor:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0092b/ch04s03s04.html
and that goes on to tell how to flush the instruction cache by a write to a control register. It certainly is possible to write self-modifying code for Arm processors because somewhere in that manual I found a statement that said that it is sometimes unavoidable and the has to be supported.
(I'm not claiming this is an answer. But it wouldn't fit in a comment.)