pthread_mutex_lock(&mutex); // read / write shared memory data here pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex); pthread_cond_wait(&cond_variable, &mutex); // read shared memory data here pthread_mutex_unlock(&mutex);
bool led8_on; // led on IO8 bool led13_on; // built-in led
g++ mmap.cpp -lpthread -o mmap
./mmap {0,1}{0,1}
/* * Author: Matthias Hahn <matthias.hahn@intel.com> * Copyright (C) 2014 Intel Corporation * This file is part of mmap IPC sample provided under the MIT license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "mmap.h" using namespace std; /* assume /tmp mounted on /tmpfs -> all operation in memory */ /* we can use just any file in tmpfs. assert(file size not modified && file permissions left readable) */ struct mmapData* p_mmapData; // here our mmapped data will be accessed int led8 = 8; int led13 = 13; void exitError(const char* errMsg) { /* print to the serial Arduino is attached to, ie /dev/ttyGS0 */ string s_cmd("echo 'error: "); s_cmd = s_cmd + errMsg + " - exiting' > /dev/ttyGS0"; system(s_cmd.c_str()); exit(EXIT_FAILURE); } void setup() { int fd_mmapFile; // file descriptor for memory mapped file /* open file and mmap mmapData*/ fd_mmapFile = open(mmapFilePath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fd_mmapFile == -1) exitError("couldn't open mmap file"); /* make the file the right size - exit if this fails*/ if (ftruncate(fd_mmapFile, sizeof(struct mmapData)) == -1) exitError("couldn' modify mmap file"); /* memory map the file to the data */ /* assert(filesize not modified during execution) */ p_mmapData = static_cast<struct mmapData*>(mmap(NULL, sizeof(struct mmapData), PROT_READ | PROT_WRITE, MAP_SHARED, fd_mmapFile, 0)); if (p_mmapData == MAP_FAILED) exitError("couldn't mmap"); /* initialize mutex */ pthread_mutexattr_t mutexattr; if (pthread_mutexattr_init(&mutexattr) == -1) exitError("pthread_mutexattr_init"); if (pthread_mutexattr_setrobust(&mutexattr, PTHREAD_MUTEX_ROBUST) == -1) exitError("pthread_mutexattr_setrobust"); if (pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED) == -1) exitError("pthread_mutexattr_setpshared"); if (pthread_mutex_init(&(p_mmapData->mutex), &mutexattr) == -1) exitError("pthread_mutex_init"); /* initialize condition variable */ pthread_condattr_t condattr; if (pthread_condattr_init(&condattr) == -1) exitError("pthread_condattr_init"); if (pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED) == -1) exitError("pthread_condattr_setpshared"); if (pthread_cond_init(&(p_mmapData->cond), &condattr) == -1) exitError("pthread_mutex_init"); /* for this test we just use 2 LEDs */ pinMode(led8, OUTPUT); pinMode(led13, OUTPUT); } void loop() { /* block until we are signalled from native code */ if (pthread_mutex_lock(&(p_mmapData->mutex)) != 0) exitError("pthread_mutex_lock"); if (pthread_cond_wait(&(p_mmapData->cond), &(p_mmapData->mutex)) != 0) exitError("pthread_cond_wait"); if (p_mmapData->led8_on) { system("echo 8:1 > /dev/ttyGS0"); digitalWrite(led8, HIGH); } else { system("echo 8:0 > /dev/ttyGS0"); digitalWrite(led8, LOW); } if (p_mmapData->led13_on) { system("echo 13:1 > /dev/ttyGS0"); digitalWrite(led13, HIGH); } else { system("echo 13:0 > /dev/ttyGS0"); digitalWrite(led13, LOW); } if (pthread_mutex_unlock(&(p_mmapData->mutex)) != 0) exitError("pthread_mutex_unlock"); }
/* * Author: Matthias Hahn <matthias.hahn@intel.com> * Copyright (C) 2014 Intel Corporation * This file is part of mmap IPC sample provided under the MIT license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* mmap.cpp Linux native program communicating via memory mapped data with Arduino sketch. Compilation: g++ mmap.cpp -lpthread -o mmap Run: ./mmap <LED8><LED13> (eg ./mmap 01 -> LED 8 off, LED 13 on) For "random" blink you may run following commands in the command line: while [ 1 ]; do ./mmap $(($RANDOM % 2))$(($RANDOM % 2)); done */ #include "mmap.h" void exitError(const char* errMsg) { perror(errMsg); exit(EXIT_FAILURE); } using namespace std; /** * @brief: for this example uses a binary string "<led8><led13>"; eg "11": both leds on * if no arg equals "00" * For "random" blink you may run following commands in the command line: * while [ 1 ]; do ./mmap $(($RANDOM % 2))$(($RANDOM % 2)); done */ int main(int argc, char** argv) { struct mmapData* p_mmapData; // here our mmapped data will be accessed int fd_mmapFile; // file descriptor for memory mapped file /* Create shared memory object and set its size */ fd_mmapFile = open(mmapFilePath, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fd_mmapFile == -1) exitError("fd error; check errno for details"); /* Map shared memory object read-writable */ p_mmapData = static_cast<struct mmapData*>(mmap(NULL, sizeof(struct mmapData), PROT_READ | PROT_WRITE, MAP_SHARED, fd_mmapFile, 0)); if (p_mmapData == MAP_FAILED) exitError("mmap error"); /* the Arduino sketch might still be reading - by locking this program will be blocked until the mutex is unlocked from the reading sketch * in order to prevent race conditions */ if (pthread_mutex_lock(&(p_mmapData->mutex)) != 0) exitError("pthread_mutex_lock"); if (argc == 1) { cout << "8:0" << endl; cout << "13:0" << endl; p_mmapData->led8_on = false; p_mmapData->led13_on = false; } else if (argc > 1) { // assert(correct string given) int binNr = atol(argv[1]); if (binNr >= 10) { cout << "8:1" << endl; p_mmapData->led8_on = true; } else { cout << "8:0" << endl; p_mmapData->led8_on = false; } binNr %= 10; if (binNr == 1) { cout << "13:1" << endl; p_mmapData->led13_on = true; } else { cout << "13:0" << endl; p_mmapData->led13_on = false; } } // signal to waiting thread if (pthread_mutex_unlock(&(p_mmapData->mutex)) != 0) exitError("pthread_mutex_unlock"); if (pthread_cond_signal(&(p_mmapData->cond)) != 0) exitError("pthread_cond_signal"); }
/* * Author: Matthias Hahn <matthias.hahn@intel.com> * Copyright (C) 2014 Intel Corporation * This file is part of mmap IPC sample provided under the MIT license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef MMAP_HPP #define MMAP_HPP #include <fcntl.h> #include <unistd.h> #include <sys/mman.h> #include <iostream> #include <string.h> #include <stdlib.h> #include <cstdio> #include <pthread.h> /* assert(/tmp mounted to tmpfs, ie resides in RAM) */ /* just use any file in /tmp */ static const char* mmapFilePath = "/tmp/arduino"; struct mmapData { bool led8_on; // led on IO8 bool led13_on; // built-in led pthread_mutex_t mutex; pthread_cond_t cond; }; #endif
Source: https://habr.com/ru/post/368141/
All Articles