Reading value of ccount registry on esp8266 returns probably invalid resut - embedded

I'm trying to read the value of ccount register on esp8266. Though the first read after reset seems to be sensible, the rest values seem to be fishy.
Here is a complete code snippet I'm using
/* Hello World Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <stdint.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
static inline uint32_t get_ccount(void)
{
volatile uint32_t r;
__asm__ __volatile__("rsr %0,ccount":"=a" (r));
return r;
}
static void print_ccount()
{
uint32_t c = get_ccount();
printf("ccount: %u\n", c);
}
void app_main()
{
for (int i = 10; i >= 0; i--) {
print_ccount();
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
printf("Restarting now.\n");
fflush(stdout);
esp_restart();
}
First read after reset is usually something like 659430, 110466 etc, but the rest values is usually recurring '1981' value or something similar. Even after reset, all reads after the first read return '1981' value.
Sometimes the output looks like this:
�ccount: 110466
I'm afraid that there is some garbage on the stack but I can't figure out what is the cause.

Related

For the following race condition example, why an inconsistent result comes up only in some environments, but not in some others?

The following code is about the classical producer and consumer problem and there is a race condition here. When I run this example in MinGW in Windows 10, we have a very large probability (e.g., 80%) of having an inconsistent result. However, when I run it in Ubuntu, the probability is extremely low.
Besides, when I run a similar code in Java, the probability of having an inconsistent result is also very high.
So, could anyone explain what is different behind. I think it is because of different scheduling mechanisms and different time slice settings.
#include <stdio.h>
#include <pthread.h>
int count = 0;
void *producer(){
for(int i = 0;i<10000;i++)
count++;
}
void *consumer() {
for(int i = 0;i<10000;i++)
count--;
}
int main(int argc, const char *argv[]){
printf("initial count: %d\n",count);
pthread_t t1, t2;
pthread_create(&t1, NULL, producer,NULL);
pthread_create(&t2, NULL, consumer,NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("final count: %d\n",count);
return 0;
}

How to use write_ply_with_properties() with Point_set_3

I have a CGAL::Point_set_3 point set with point normal and color. I would like to save all properties to a PLY file, using write_ply_with_properties() function.
My goal is to make the full version work (see code below), but even the simple version doesn't compile, with the same error as the full version.
I work on Linux with CGAL release 4.14 and gcc 7.4.0.
Here is the code:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <tuple> // for std::tie
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main(int argc, char*argv[])
{
Point_set points;
points.insert(Point(1., 2., 3.));
points.insert(Point(4., 5., 6.));
// add normal map
points.add_normal_map();
auto normal_map = points.normal_map();
// add color map
typedef Point_set::Property_map< Vector > ColorMap;
bool success = false;
ColorMap color_map;
std::tie(color_map, success) =
points.add_property_map< Vector >("color");
assert(success);
// populate normal and color map
for(auto it = points.begin(); it != points.end(); ++it)
{
normal_map[*it] = Vector(10., 11., 12.);
color_map[*it] = Vector(20., 21., 22.);
}
std::ofstream out("out.ply");
#if 1
// simple version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map())))
#else
// full version
if(!out || !CGAL::write_ply_points_with_properties(
out,
points.points(), // const PointRange
CGAL::make_ply_point_writer(points.point_map()),
CGAL::make_ply_normal_writer(points.normal_map()),
std::make_tuple(color_map,
CGAL::PLY_property< double >("red"),
CGAL::PLY_property< double >("green"),
CGAL::PLY_property< double >("blue"))))
#endif
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
The compilation error is:
...
/usr/include/boost/property_map/property_map.hpp:303:54: error: no match for ‘operator[]’ (operand types are ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >’ and ‘const CGAL::Point_3<CGAL::Epick>’)
Reference v = static_cast<const PropertyMap&>(pa)[k];
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: candidate: CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::operator[](const I&) [with I = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index; T = CGAL::Point_3<CGAL::Epick>; CRTP_derived_class = CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Property_map<CGAL::Point_3<CGAL::Epick> >; CGAL::Properties::Property_map_base<I, T, CRTP_derived_class>::reference = CGAL::Point_3<CGAL::Epick>&]
reference operator[](const I& i)
^~~~~~~~
CGAL-4.14/include/CGAL/Surface_mesh/Properties.h:567:15: note: no known conversion for argument 1 from ‘const CGAL::Point_3<CGAL::Epick>’ to ‘const CGAL::Point_set_3<CGAL::Point_3<CGAL::Epick> >::Index&’
How can I fix it?
The problem in your code is that you are using the method points() of CGAL::Point_set_3 which returns a range of points of type CGAL::Point_set_3::Point_range, whereas the property maps that you use (points.point_map(), etc.) are directly applied to a type CGAL::Point_set_3.
So you should simply call the write_ply_points_with_properties() on points, not on points.points().
Note also that if you store your colors on simple types (for example, using three Point_set_3 properties typed unsigned char), you can take advantage of the function CGAL::write_ply_point_set() that will automatically write all the simply-typed properties it finds, which makes it quite straightforward to use (just do CGAL::write_ply_point_set(out, points) and you're done).
One last thing that is really a detail not related to your problem, but you should avoid using the CGAL::Vector_3 for storing anything else than an actual geometric 3D vector (like colors in your case). That makes your code harder to read and is also quite an ineffective way to store colors if they are encoded as integer values between 0 and 255 (which is what unsigned char is for).

Do constrained refinement with CGAL isotropic_remeshing

I'd like to do refinement of eg a simple cube (from a .off); there are a few ways but the ones suitable for what I want to do next end up with 'wrinkles', ie the object shape gets distorted.
This way below promises to allow the boundaries (shape?) of the object to be preserved, permitting what you'd expect of refinement, to just add more edges and vertices:
http://doc.cgal.org/latest/Polygon_mesh_processing/Polygon_mesh_processing_2isotropic_remeshing_example_8cpp-example.html
I want an edge constraint map (and if that isn't sufficient then I'll want a vertex constraint map as well) but can't figure out the template abstractions well enough. I tried an OpenMesh Constrained_edge_map from a different CGAL example, but that's too different and won't compile. What I'm asking for is an edge map and maybe a vertex map that I can feed to the call:
PMP::isotropic_remeshing(
faces(mesh),
target_edge_length,
mesh,
PMP::parameters::number_of_iterations(nb_iter)
.protect_constraints(true)//i.e. protect border, here
);
I'm using CGAL 4.8.1, the latest at time of writing. Thanks.
Here is a minimal example to remesh a triangulated cube:
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Mesh_3/dihedral_angle_3.h>
#include <boost/foreach.hpp>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
namespace PMP=CGAL::Polygon_mesh_processing;
int main(int, char* argv[])
{
std::ifstream input(argv[1]);
Mesh tmesh;
input >> tmesh;
double target_edge_length = 0.20;
unsigned int nb_iter = 10;
// give each vertex a name, the default is empty
Mesh::Property_map<edge_descriptor,bool> is_constrained =
tmesh.add_property_map<edge_descriptor,bool>("e:is_constrained",false).first;
//detect sharp features
BOOST_FOREACH(edge_descriptor e, edges(tmesh))
{
halfedge_descriptor hd = halfedge(e,tmesh);
if ( !is_border(e,tmesh) ){
double angle = CGAL::Mesh_3::dihedral_angle(tmesh.point(source(hd,tmesh)),
tmesh.point(target(hd,tmesh)),
tmesh.point(target(next(hd,tmesh),tmesh)),
tmesh.point(target(next(opposite(hd,tmesh),tmesh),tmesh)));
if ( CGAL::abs(angle)<100 )
is_constrained[e]=true;
}
}
//remesh
PMP::isotropic_remeshing(
faces(tmesh),
target_edge_length,
tmesh,
PMP::parameters::number_of_iterations(nb_iter)
.edge_is_constrained_map(is_constrained) );
std::ofstream out("out.off");
out << tmesh;
return 0;
}

SC_THREAD does not get triggered by its sensitivity list

I am developing a simple NAND module in SystemC. By specification, it should have a 4 ns delay so I tried to describe it with a process with a "wait" statement and SC_THREAD, as follows:
//file: nand.h
#include "systemc.h"
SC_MODULE(nand2){
sc_in<bool> A, B;
sc_out<bool> F;
void do_nand2(){
bool a, b, f;
a = A.read();
b = B.read();
f = !(a && b);
wait(4, SC_NS);
F.write(f);
}
SC_CTOR(nand2){
SC_THREAD(do_nand2);
sensitive << A << B;
}
};
To simulate I've created another module the outputs the stimulus for the NAND, as follows:
//file: stim.h
#include "systemc.h"
SC_MODULE(stim){
sc_out<bool> A, B;
sc_in<bool> Clk;
void stimGen(){
wait();
A.write(false);
B.write(false);
wait();
A.write(false);
B.write(true);
wait();
A.write(true);
B.write(true);
wait();
A.write(true);
B.write(false);
}
SC_CTOR(stim){
SC_THREAD(stimGen);
sensitive << Clk.pos();
}
};
Having these two modules described, the top module (where sc_main is) looks like this:
//file: top.cpp
#include "systemc.h"
#include "nand.h"
#include "stim.h"
int sc_main(int argc, char* argv[]){
sc_signal<bool> ASig, BSig, FSig;
sc_clock Clk("Clock", 100, SC_NS, 0.5);
stim Stim("Stimulus");
Stim.A(ASig); Stim.B(BSig); Stim.Clk(Clk);
nand2 nand2("nand2");
nand2.A(ASig); nand2.B(BSig); nand2.F(FSig);
sc_trace_file *wf = sc_create_vcd_trace_file("sim");
sc_trace(wf, Stim.Clk, "Clock");
sc_trace(wf, nand2.A, "A");
sc_trace(wf, nand2.B, "B");
sc_trace(wf, nand2.F, "F");
sc_start(400, SC_NS);
sc_close_vcd_trace_file(wf);
return 0;
}
The code was compiled and simulated with no errors, however when visualizing the .vcd file in gtkwave the output (F) gets stuck in 1, only showing the delay in the beginning of the simulation.
To test if there were any errors in the code I removed the "wait" statements and changed SC_THREAD to SC_METHOD in the nand.h file and simulated again, now getting the correct results, but without the delays of course.
What am I doing wrong?
It's best if you use an SC_METHOD for process do_nand2, which is sensitive to the inputs. A thread usually has an infinite loop inside of it and it runs for the entire length of the simulation. A method runs only once from beginning to end when triggered. You use threads mostly for stimulus or concurrent processes and threads may, or may not be sensitive to any events.
Just solved the problem:
instead of using
wait(4, SC_NS);
with SC_THREAD I used
next_trigger(4, SC_NS);
with SC_METHOD and it worked just fine.

API for handling wait queues are not working

I have to make tasks as processes in Linux but I don't want the process to execute until all the processes are created. So I thought of moving the processes to wait queue soon after creation and wait until all processes are created.
#include <unistd.h> /* Symbolic Constants */
#include <sys/types.h> /* Primitive System Data Types */
#include <errno.h> /* Errors */
#include <stdio.h> /* Input/Output */
#include <stdlib.h> /* General Utilities */
#include <pthread.h> /* POSIX Threads */
#include <string.h> /* String handling */
#include <sched.h>
#include <linux/kernel.h>
#include <time.h>
#include <sys/resource.h>
#include <stddef.h>
#include <linux/sched.h>
#include <linux/wait.h> /* for wait_event_interruptible() & wake_up_interruptible() */
int done = 0;
static DECLARE_WAIT_QUEUE_HEAD(queue);
int main()
{
int pid1, pid2;
if ((pid1 = fork()) < 0) //create a child process
exit(1);
if ((pid2 = fork()) < 0) //create a child process
exit(1);
if (pid1 == 0) //child process
{
wait_event_interruptible(queue, done == 2);
printf("child 1\n");
}
else //parent process
{
done = done+1;
wake_up_interruptible(&queue);
}
if (pid2 == 0) //child process
{
wait_event_interruptible(queue, done == 2);
printf("child 2\n");
}
else //parent process
{
done = done+1;
wake_up_interruptible(&queue);
}
return 0;
}
But when I tried this sample code it shows these errors.
$ gcc -Wall try.c
try.c:18:8: warning: type defaults to ‘int’ in declaration of ‘DECLARE_WAIT_QUEUE_HEAD’ [-Wimplicit-int]
try.c:18:1: warning: parameter names (without types) in function declaration [enabled by default]
try.c: In function ‘main’:
try.c:33:6: warning: implicit declaration of function ‘wait_event_interruptible’ [-Wimplicit-function-declaration]
try.c:33:31: error: ‘queue’ undeclared (first use in this function)
try.c:33:31: note: each undeclared identifier is reported only once for each function it appears in
try.c:39:2: warning: implicit declaration of function ‘wake_up_interruptible’ [-Wimplicit-function-declaration]
try.c: At top level:
try.c:18:8: warning: ‘DECLARE_WAIT_QUEUE_HEAD’ declared ‘static’ but never defined [-Wunused-function]
When I checked $ man wait_event_interruptible, it says "No manual entry for wait_event_interruptible". So the API is missing in the library. How can I add it to the library? Thanks in advance.
wait_event_interruptible(), wake_up_interruptible() are some of the Kernel's API to create and use wait queues. You cannot use those from the user-land!
If I understand your purpose correctly, what you need to do is to create N processes barrier. If you know the number of the processes (N), you can easily use semaphores: initialize the semaphore with zero, all processes call down() and the last process calls up() N times. You can also use message queues.
You can also use the Linux API for barriers: pthread_barrier_wait and pthread_barrier_init, but I have not used this before.