Ceedling CMock settings for ARM STM32 - c

I've been setting up Ceedling for STM32. The howto is very scarce, so far I've managed to google next to nothing. Fortunately, the framework is relatively transparent for its size. This is a PIC configuration. I set up something similar (project.yml):
...
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines #[]
- STM32F103xB
- UNITY_INT_WIDTH=32
- CMOCK_MEM_INDEX_TYPE=uint32_t
- UNITY_LINE_TYPE=uint16_t
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
So far so good (no real work is yet attempted). Having added this definition
- CMOCK_MEM_PTR_AS_INT=uint32_t
I'm having a warning:
/vendor/ceedling/vendor/cmock/src/cmock.c:105:40: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
index = *(CMOCK_MEM_INDEX_TYPE*)((CMOCK_MEM_PTR_AS_INT)next - CMOCK_MEM_INDEX_SIZE);
No wonder, as next is a PC platform 64-bit pointer. Still I am not at all sure whether I have to control CMOCK_MEM_PTR_AS_INT or not. It depends on whether CMOCK_MEM_PTR_AS_INT is a critical target (ARM) platform definition.
So far I haven't found an STM32 example.

Here is the hard won sequence, complete with the Eclipse integration:
Install Ceedling:
$ gem install ceedling
Create Ceedling project (troubleshooting #215):
myproject $ cd ..
$ ceedling new myproject
$ cd myproject/vendor/
$ rm -rf ceedling/
$ git clone --recursive https://github.com/throwtheswitch/ceedling.git
Modify vendor/ceedling/plugins/module_generator/config/module_generator.yml:
:module_generator:
:project_root: ./
:source_root: Src/
:inc_root: Inc/
:test_root: test/
Modify project.yml:
...
:paths:
:test:
- +:test/**
- -:test/support
:source:
- Src/**
:include:
- Drivers/**
- Inc/**
:support:
- test/support
...
:defines:
:commmon: &common_defines # A nice typo, next to invisible :)
- STM32F103xB
...
:cmock:
:strippables:
- volatile
...
:plugins:
:load_paths:
- vendor/ceedling/plugins
:enabled:
# - stdout_pretty_tests_report
- stdout_gtestlike_tests_report
- module_generator
Eclipse C/C++ Unit plugin configuration:
Main/Project: myproject
Main/Application: /home/user/.gem/ruby/2.5.0/bin/ceedling
Main/Disable auto build
Arguments/Program arguments: clobber\ntest:all
Testing/Test Runner: Google Test Runner
Environment: Variable TERM Value xterm

Related

How to put kortex_api in requirements file for installation

I am trying to build a docker container that runs a pip install -r requirements.txt command. I need to specify the kortex_api version inside that file for robot arm connection. I am using a kinova robot arm. I was able to build a conda environment with the following statements:
name: vrobot
channels:
- conda-forge
- pytorch
- defaults
dependencies:
- python=3.8
- pip
- mysql-connector-python
- numpy
- pandas
- SpeechRecognition
- playsound
- IPython
- gdown
- openpyxl
- cudatoolkit=11.3
- pytorch::pytorch
- pytorch::torchvision
- pytorch::torchaudio
- pip:
- pyrealsense2==2.51.1.4348
- pytesseract
- pyaudio
- opencv-python==4.5.4.60
- easyocr
- file:kortex_api-2.3.0.post34-py3-none-any.whl
You can see that the environment can use pip to isntall kortex_api from the file:kortex_api-2.3.0.post34-py3-none-any.whl. I want to know if i can do something similar to my requirements.txt file. Here my requirements:
certifi==2022.6.15
Deprecated==1.2.7
docopt==0.6.2
easyocr==1.6.0
et-xmlfile==1.0.1
imageio==2.21.1
mysql-connector-python==8.0.30
networkx==2.8.6
ninja==1.10.2.3
opencv-python==4.5.4.60
opencv-python-headless==4.5.4.60
packaging==21.3
pipreqs==0.4.11
protobuf==3.20.1
PyAudio==0.2.12
pyclipper==1.3.0.post3
pyparsing==3.0.9
python-bidi==0.4.2
PyWavelets==1.3.0
PyYAML==6.0
scikit-image==0.19.3
scipy==1.9.0
Shapely==1.8.4
tifffile==2022.8.12
torch==1.12.1
torchaudio==0.12.1
torchvision==0.13.1
wrapt==1.14.1
yarg==0.1.9
pyrealsense2==2.51.1.4348

Are the added dependencies really been compiled by shadow-cljs? If so, why do the values stay the same?

I am following shadow-cljs Quick Start documentation on a minimal example of a project. Here is the link.
Initially, I had this shadow-cljs.edn file:
;; shadow-cljs configuration
{:source-paths
["src/dev"
"src/main"
"src/test"]
:dev-http {8080 "public"}
:dependencies
[]
:builds
{:frontend
{:target :browser
:modules {:main {:init-fn acme.frontend.app/init}}
}}}
In /Users/pedro/projects/acme-app/src/main/acme/frontend/app.cljs, I also have:
(ns acme.frontend.app)
(defn init []
(println "Hello World"))
I can build and watch it with the command:
$ npx shadow-cljs compile frontend
shadow-cljs - config: /Users/pedro/projects/acme-app/shadow-cljs.edn
shadow-cljs - updating dependencies
shadow-cljs - dependencies updated
[:frontend] Compiling ...
[:frontend] Build completed. (79 files, 0 compiled, 0 warnings, 4.88s)
I have been adding dependencies such as:
:dependencies [[day8.re-frame/re-frame-10x "1.2.1"]
[proto-repl "0.3.1"]
[re-frame "1.2.0"]
[com.degel/re-frame-firebase "0.9.6-SNAPSHOT"]
[bidi "2.1.5"]
[re-com "2.13.2-106-180ea1f-SNAPSHOT-TALLYFOR"]
[com.andrewmcveigh/cljs-time "0.5.2"]
[com.pupeno/free-form "0.6.0"]
[binaryage/dirac "RELEASE"]
[hickory "0.7.1"]
[cljs-hash "0.0.2"]
[medley "1.2.0"]]
But, the build does not change in terms of files, compiled, and warnings. Just the time changes a bit - time is probably somewhat random/stochastic (79 files, 0 compiled, 0 warnings, 5.59s).
Are the dependencies really been compiled? How do I know if the dependencies were compiled too?
If they are being compiled, why does the number of files stay the same?
Obs.: note that I am not invoking the function being used inside the dependencies - and I do not want to invoke them for debugging reasons.
Adding the :dependencies does very little, they'll not be compiled on their own. They are only made available on the classpath.
They will only be compiled and loaded once you add them the :require in the ns forms of your files, or dynamically require at the REPL. Without an explicit request (ie. :require) to load them, they are just passive resources that are unused.

Ceedling project file does not recognize paths and libraries

I wanted to use ceedling for unit testing C Code for STM32 family.
I installed it as shown on their page on GitHub Ceedling and run successfully the example tests.
The project.yml file I have modified the paths because I have a different path for header files (path: include) as the source files (path: src):
:paths:
:test:
- +:test/**
- -:test/support
:source:
- build/STM32F2xx_StdPeriph_Driver/include/**
- build/STM32F2xx_StdPeriph_Driver/src/**
- include/**
- src/**
:support:
- test/support
:defines:
:commmon: &common_defines
#Define for header files
- STM32F2XX
:libraries:
:placement: :end
:flag: "${1}" # or "-L ${1}" for example
:common: &common_libraries []
:test:
- *common_libraries
#toolchain of STM32F2
- build/STM32F2xx_StdPeriph_Driver/include/**
- build/STM32F2xx_StdPeriph_Driver/src/**
- build/STM32F2xx/include/
But somehow the path and libraries does not get recognized and I get error for unknown variables.
Is my .yml file wrong?
for future readers, I switched to cppUTest. Its easy to use, and you have the power of cpp and the mocking is fantastic.

How to compile a basic c file in yocto

I am working on yocto, I want to compile some C files in yocto and install the resulting binary to external filesystem.
Before doing that I tried creating a separate reciepe and compile c code from it.
I am unable to compile it.
I am not sure to understand the question since it is not precise enough.
Including C files in recipe tree
If you want to have the C files in your recipe, having a file tree like this:
recipe-example/example/example_0.1.bb
recipe-example/example/example-0.1/helloworld.c
You can generate this example when you create a new layer using
yocto-layer <your-layer-name>
Your bb file will look like this:
#
# This file was derived from the 'Hello World!' example recipe in the
# Yocto Project Development Manual.
#
SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
It will compile the hello world file and install it into /usr/bin on your image.
From a Git repo
You also can compile from a git repository, I advise you to read the manual and examples in your yocto folder. Here is an example here of wiringPi:
DESCRIPTION = "A library to control Raspberry Pi GPIO channels"
HOMEPAGE = "https://projects.drogon.net/raspberry-pi/wiringpi/"
SECTION = "devel/libs"
LICENSE = "LGPLv3+"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# tag 2.29
SRCREV = "d79506694d7ba1c3da865d095238289d6175057d"
S = "${WORKDIR}/git"
SRC_URI = "git://git.drogon.net/wiringPi \
file://0001-Add-initial-cross-compile-support.patch \
file://0001-include-asm-ioctl.h-directly-for-_IOC_SIZEBITS.patch \
"
COMPATIBLE_MACHINE = "raspberrypi"
CFLAGS_prepend = "-I${S}/wiringPi -I${S}/devLib"
EXTRA_OEMAKE += "'INCLUDE_DIR=${D}${includedir}' 'LIB_DIR=${D}${libdir}'"
EXTRA_OEMAKE += "'DESTDIR=${D}/usr' 'PREFIX=""'"
do_compile() {
oe_runmake -C devLib
oe_runmake -C wiringPi
oe_runmake -C gpio 'LDFLAGS=${LDFLAGS} -L${S}/wiringPi -L${S}/devLib'
}
do_install() {
oe_runmake -C devLib install
oe_runmake -C wiringPi install
oe_runmake -C gpio install
}
It is fetching from a git repository, applying patches generated by git, using oe_runmake to compile with the makefiles.
With devtool
It has been asked in a comment on how to add a recipe with devtool.
We will still use wiringPi as an example again. Download it doing
https://github.com/WiringPi/WiringPi
The Makefile is is the folder wiringPi.
You can then do
devtool add <name_of_recipe> <path_to_Makefile_folder>
Take care of the warning from devtool
NOTE: Creating workspace layer in /home/dbensoussan/new_poky/poky/build/workspace
NOTE: Enabling workspace layer in bblayers.conf
NOTE: Using source tree as build directory since that would be the default for this recipe
NOTE: Recipe /home/dbensoussan/new_poky/poky/build/workspace/recipes/project/project.bb has been automatically created; further editing may be required to make it fully functional
This is generating the recipe as follow:
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)
#
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "Unknown"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""
# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
# recipe automatically - you will need to examine the Makefile yourself and ensure
# that the appropriate arguments are passed in.
do_configure () {
# Specify any needed configure commands here
:
}
do_compile () {
# You will almost certainly need to add additional arguments here
oe_runmake
}
do_install () {
# This is a guess; additional arguments may be required
oe_runmake install 'DESTDIR=${D}'
}
You can then edit your recipe to suit your configuration
With externalsrc
It is possible to use a directory present on the filesystem by using externalsrc.
I did not try it myself, nor have I the workspace ready to do, but #71GA in the comment tested the tutorial from the Koan software company https://wiki.koansoftware.com/index.php/Building_Software_from_an_External_Source and it worked. I will copy the content here:
in this case use the externalsrc class - you can inherit this in the original bb recipe or a bbappend:
inherit externalsrc
EXTERNALSRC = "/path/to/sources"
Depending on the type of build (eg, 'inherit module' for out of tree Linux kernel modules) you may or may not need to set EXTERNALSRC_BUILD.
inherit externalsrc
EXTERNALSRC = "/some/path"
EXTERNALSRC_BUILD = "/some/path"
If you're going to use it across a number of recipes you can inherit it globally at the configuration level (perhaps via an inc file that you include/require there):
INHERIT += "externalsrc"
EXTERNALSRC_pn-<recipename> = "/path/to/sources"
Recipe example using an external source for nInvaders package
#
# Recipe example with externalsrc
#
# (C)2019 Marco Cavallini - KOAN - <https://koansoftware.com>
#
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
inherit externalsrc
EXTERNALSRC = "/home/koan/yocto-qemuarm-sumo/ninvaders-0.1.1"
EXTERNALSRC_BUILD = "${EXTERNALSRC}"
DEPENDS = "ncurses"
EXTRA_OEMAKE = "-e"
do_install() {
install -d ${D}${bindir}
install -m 0755 nInvaders ${D}${bindir}
}
FILES_${PN} = "${bindir}/*"
You can just go to the official documentation to find your answer.
In the chapter 7.3 Writting a New Recipe of the yocto mega-manual, the very first example is exactly is what you need (Single .c File Package (Hello World!)).

Ceedling how to pass defines to CMock

I am somewhat new to TDD, although I have been using C for some time. As a result, I am using ceedling to test my embedded project.
I can rake test:all in gcc, but I am now trying to move that to an embedded target simulator. I am specifying my cross-compiler, linker, etc. through the 'project.yml' file.
When I rake test:all, I get an error when "compiling cmock.c" (several other files compile without problems):
< path_to_cmock >/cmock.c:17:31: error: size of array 'CMock_Guts_Buffer' is too large
There are other errors after this, but this is the one that kicks them off.
When I go to cmock.c, I see this at the top of the file:
#ifdef CMOCK_MEM_DYNAMIC
static unsigned char* CMock_Guts_Buffer = NULL;
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_ALIGN_SIZE;
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr;
#else
static unsigned char CMock_Guts_Buffer[CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE];
static CMOCK_MEM_INDEX_TYPE CMock_Guts_BufferSize = CMOCK_MEM_SIZE + CMOCK_MEM_ALIGN_SIZE;
static CMOCK_MEM_INDEX_TYPE CMock_Guts_FreePtr;
#endif
Perfect, so I just need to find where these are declared. I do a text search only to find that they aren't declared anywhere... so I suspect that they are coming from the defaults within ceedling.
I found the documentation for CMOCK and, under "Compiled Options",
A number of #defines also exist for customizing the cmock experience...
It goes on to list the #defines that I have found in the source code, but it does not state where to find them. I have tried to make an include file with the appropriate defines and pass the include file through the 'project.yml' with no luck.
I suspect that the answer is unbelievably simple, it just isn't outlined anywhere that I have searched. Thank you for your time,
Of course, the answer was staring me in the face.
In the 'project.yml' file, there is a section called 'defines'. The default defines are:
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines []
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
I simply added the defines for my target:
:defines:
# in order to add common defines:
# 1) remove the trailing [] from the :common: section
# 2) add entries to the :common: section (e.g. :test: has TEST defined)
:commmon: &common_defines
- __dsPIC33EP32MC204__
- UNITY_INT_WIDTH=16
- CMOCK_MEM_INDEX_TYPE=uint16_t
- CMOCK_MEM_PTR_AS_INT=uint16_t
- CMOCK_MEM_ALIGN=1
- CMOCK_MEM_SIZE=1024
- CMOCK_MEM_STATIC
:test:
- *common_defines
- TEST
:test_preprocess:
- *common_defines
- TEST
The proper way to setup the cmock for your prohect is as slightlynybbled pointed in previous answer, bu you could also provide a hidden setup for your cmocks into your project.yml file as follow:
:cmock:
:mock_prefix: mock_
:when_no_prototypes:
:warn
:enforce_strict_ordering: TRUE
:includes_h_pre_orig_header:
- ../<cmock_headers_includes>.h
:plugins:
- :ignore
- :ignore_arg
- :callback
- :expect
- :expect_any_args
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
This setup have been tested with Ceedling 0.27, 0.28 and 0.28.1

Resources