我只是失去了几天,从字面上看,大约25个小时的工作,因为我试图调试我的代码而不是我不知道的简单.
事实证明,在C++中减少单字节数组的元素,在AVR上,ATmega328 8位微控制器(Arduino)不是原子操作,需要原子访问保护(即关闭中断).为什么是这样???此外,在Atmel AVR微控制器上确保原子访问变量的所有C技术是什么?
这是我所做的一个愚蠢的版本:
//global vars:
const uint8_t NUM_INPUT_PORTS = 3;
volatile uint8_t numElementsInBuf[NUM_INPUT_PORTS];
ISR(PCINT0_vect) //external pin change interrupt service routine on input port 0
{
//do stuff here
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
numElementsInBuf[i]++;
}
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
numElementsInBuf[i]--; //<--THIS CAUSES ERRORS!!!!! THE COUNTER GETS CORRUPTED.
}
}
Run Code Online (Sandbox Code Playgroud)
这是循环的版本,没关系:
loop()
{
for (uint8_t i=0; i<NUM_INPUT_PORTS; i++)
{
//do stuff here
noInterrupts(); //globally disable interrupts
numElementsInBuf[i]--; //now it's ok...30 hrs of …Run Code Online (Sandbox Code Playgroud) 我正在尝试将压力传感器(MS5803-14BA)与我的电路板(NUCLEO-STM32L073RZ)连接。
根据数据表(第3页),压力传感器需要几毫秒的时间才能准备好读取测量值。对于我的项目,我对转换原始数据大约需要10 ms的最高分辨率感兴趣。
不幸的是,该压力传感器没有任何可用于查看测量准备就绪时间的中断引脚,因此,我暂时解决了在请求新数据后延迟的问题。
我不喜欢当前的解决方案,因为在这10毫秒内,我可以让单片机工作在其他地方(我的板上还连接了其他几个传感器),但是没有任何中断引脚,我不确定这是什么。解决此问题的最佳方法。
我想到了另一个解决方案:使用计时器,该计时器每20秒触发一次,并执行以下操作:
1.a Read the current value stored in the registers (discarding the first value)
1.b Ask for a new value
Run Code Online (Sandbox Code Playgroud)
这样,在下一次迭代中,我只需要读取上一次迭代结束时请求的值即可。
我不喜欢我的测量结果总是20毫秒。直到延迟保持20毫秒,它应该还是可以的,但是如果我需要降低速率,则解决方案的读数“老化”会增加。
您对如何处理还有其他想法吗?
谢谢。
注意:如果您需要查看我当前的实现,请告诉我。
我正在尝试将一个 cpp 文件添加到具有以下设置的 arduino 项目中...
project
--folder
--foo.h
--foo.cpp
--project.ino
Run Code Online (Sandbox Code Playgroud)
我#include "folder/foo.h在project.ino. 然而,虽然头文件提供了函数的原型,但函数定义在 cpp 文件中。当我尝试使用 Arduino IDE 编译代码时,它失败并显示错误
Undefined reference to 'bar()'
并bar()位于foo.cpp
我看了这个,但我没有设置sketch/import library(但是我有sketch/include library,但是我没有看到任何接近使用自定义文件夹位置的东西)
我也看了这个。但与上述相同,该设置在我的 ide 中不存在。(我最近下载的)
代码
//project.ino
#include "folder/foo.h"
void setup() {
Serial.begin(9600);
}
void loop() {
bar();
}
Run Code Online (Sandbox Code Playgroud)
//folder/foo.h
#include "Arduino.h"
void bar();
Run Code Online (Sandbox Code Playgroud)
//folder/foo.cpp
#include "foo.h"
void bar() {
Serial.println("bar");
}
Run Code Online (Sandbox Code Playgroud)
错误
/tmp/ccNTRFfU.ltrans0.ltrans.o: In function `loop':
/home/temporary/project/project.ino:9: undefined reference to …Run Code Online (Sandbox Code Playgroud) 我正在实施我自己的fast_malloc()来替换malloc(). 我需要在里面调试打印。是否有任何打印调用保证永远不会调用malloc(),或者我是否需要创建自己的安全版本?
以前,我不小心通过调用导致了无限递归malloc(),printf()然后调用malloc(),然后调用printf()...永远。
如果我需要创建自己的安全版本,在后台使用固定大小的静态数组作为要格式化的缓冲区,这就是我需要知道的。我能做到。
puts()或者怎么样putc()?他们应该很安全,不是吗?
我使用的是 Linux Ubuntu 20.04。理想情况下,我所做的一切都将是跨平台兼容的,但我想如果需要低级系统调用,我可以自定义。
snprintf():调用 malloc 的 snprintf 或不调用 malloc 的 snprintf我在 Windows 上工作。我有一个 Python 文件来创建一个新的 CSV 文件,我使用记事本(甚至通过Microsoft Excel)查看该文件。
import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv', 'w') as l:
w = csv.writer(l,delimiter='|', lineterminator='\r')
w.writerows(data)
Run Code Online (Sandbox Code Playgroud)
记事本中的结果文件:
import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv', 'w') as l:
w = csv.writer(l,delimiter='|', lineterminator='\r')
w.writerows(data)
Run Code Online (Sandbox Code Playgroud)
回车是否\r有效?它的工作原理就像lineterminator=''在记事本中。但在 Excel 中,它的工作方式类似于 '\n'。
输出似乎没有实现回车。当我lineterminator用作:
w = csv.writer(l, delimiter='|', lineterminator='*\r*\n')
Run Code Online (Sandbox Code Playgroud)
记事本中的输出是:
fruit|quantityapple|5banana|7mango|8
Run Code Online (Sandbox Code Playgroud)
这在这里也很明显。
'\r'lineterminator在 writer()中是如何工作的?或者那里正在发生其他事情?
我写了以下代码:
#include <stdio.h>
int array[] = {23, 43, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int main()
{
int test = -1;
if (test <= TOTAL_ELEMENTS)
{
printf("Hello, got here!\n");
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译此代码(带有gcc main.c -Wall(无警告!))并运行它时,printf无法执行。我的意思是,test= -1,它肯定小于数组的大小(7 位数字)。错误在哪里?
我需要能够备份并稍后使用(读取和打印以及作为参数传递给另一个命令)所有输入参数到 bash 程序,但无法弄清楚。这是我的尝试:
back_up_all_input_args.sh:
#!/usr/bin/env bash
all_args1="$@"
all_args2="$(printf "%q " "$@")"
# Simulate parsing the input args here
# - see: https://stackoverflow.com/a/14203146/4561887
shift # remove 1st arg
shift # remove 2nd arg
echo "$@"
echo "$all_args1"
echo "$all_args2"
# Do another program call with all input args here
# rg "$all_args1" # FAILS
# rg "$all_args2" # FAILS
Run Code Online (Sandbox Code Playgroud)
示例运行和输出:
Run Code Online (Sandbox Code Playgroud)$ ./backup_all_input_args.sh arg1 "arg 2" "arg 3" arg 3 arg1 arg 2 arg 3 arg1 arg\ 2 arg\ 3
我的第一个方法是用 来支持论点 …
我是这样想的:
read -p "Make this rsync backup session a dry run [Y/n]? " -i '--dry-run' dry_run
echo "$dry_run"
Run Code Online (Sandbox Code Playgroud)
...如果我只是点击回复提示,则会输出--dry-run为其“默认值” 。Enter但是,事实并非如此。它输出一个换行符。
其目的是什么-i以及如何运作?
从help read:
-i text use TEXT as the initial text for Readline
Run Code Online (Sandbox Code Playgroud)
对于任何想了解我在哪里学习如何向用户发出 bash 提示的人:How do I read user input into a variable in Bash?
再次:
std::vector<std::string> someFunction() {
auto vec;
return vec;
}
Run Code Online (Sandbox Code Playgroud)
vec是什么阻止“auto”推断as的类型std::vector<std::string>?
AFAIK,退出代码可能会根据应用程序和项目中采用的约定而有所不同。但是,我想知道是否有 C/C++ 项目的退出代码标准列表。