Install Redmine on DreamHost VPS Server

Recently we moved to dreamhost VPS server and signed in for 3 year service. We were using redmine in our projects for handling project management activities. After successful installation of latest redmine release on local server, it was time to move on to install and test it on webservers. But when we contacted Dreamhost support they have standard reply,

Thank you for writing into DreamHost Support!

Unfortunately, we cannot assist with custom configs for that application,
My apologies. If you need root access for the install then you would need
to use a dedicated server or DreamCompute and that would not be allowed on your current VPS.

Dreamhost Support Reply

There are multiple resources available across the web about Redmine on Dreamhost, but they’re all quite outdated. Well redmine is flexible project management web application and is free to use opensource software. We did not stop here, as we were so much impressed with capabilities of redmine for project management and reporting. So we have started with installation of ruby on rails on VPS (virtual private server).

Step 0 – Pre-Build

  1. Enable Passenger (Ruby/NodeJS/Python apps only) under ‘domains’->’Manage Domains’ from dreamhost cpanel
  2. Install RVM (Ruby version Manager) using steps mentioned in dreamhost help center
  3. Install ImageMagick current gem as redmine requires it and DreamHost servers don’t have it
    1. mkdir src && cd src
    2. Get latest source from imagemagic website using $ wget http://www.imagemagick.org/download/
    3. mkdir ~/lib
    4. tar xfz ImageMagick-7.0*
    5. Now navigate to ImageMagick-7.0* folder and configure
    6. ./configure –prefix=/home/username/lib/ImageMagick-7.0.8-68
    7. make
    8. make install
    9. export PKG_CONFIG_PATH=’/home/username/lib/ImageMagick-7.0.8-68/lib/pkgconfig’
    10. export C_INCLUDE_PATH=’/home/username/lib/ImageMagick-7.0.8-68/include’
    11. source ~/.bash_profile
  4. Download latest redmine archive and decompress it in /public folder
    1. wget http://www.redmine.org/releases/redmine-4.0.4.tar.gz
    2. tar xfz redmine-4.0.4.tar.gz –strip-components=1
  5. Install dependencies –
    1. $ gem install bundler
    2. $ bundle install
  6. If you are still getting issue with ImageMagick then bypass rmagick and continue
    1. bundle install –without development test rmagick
  7. Generate session store key
    1. $ bundle exec rake generate_secret_token
  8. After this command, if your VPS is Debian 9.12 (aka Stretch) you will get following error, but don’t worry, just run – $ bundle update
$ bundle exec rake generate_secret_token
Could not find gem 'mysql2 (~> 0.5.0)' in any of the gem sources listed in your Gemfile.

All above steps are required if you are using Dreamhost VPS/Shared server, If you are using dedicated servers then above tricks are not required for you.

Step 1 – Create Database

Create empty database using ‘MySQL database’ section of cpanel from dreamhost. This will create database and hostname, Note down these details along with username and password, as these are required in next step.

Step 2 – Configure Database

Configure the database in config/database.yml file, first rename ‘database.yml.example’ to ‘database.yml’. Open this configuration file and enter details as noted in step 1. The ‘database.yml’ file should look as below,

production:
adapter: mysql2
database: <db_name from step1>
host: <host_name from step1>
username: <user_name from step1>
password: <user_password from step1>

Step 3 – Migrate Database and Load Defaults

Create the database structure by running the redmine migrations

$  RAILS_ENV=production rake db:migrate

OR

$ bundle exec rake db:migrate

At this moment, if you see issue with Sprockets, use steps to upgrade sprockets and you are good to go for final rake command.

rake aborted!
Sprockets::Railtie::ManifestNeededError: Expected to find a manifest file in `app/assets/config/manifest.js`

It is easy as mentioned in the error log also, just create ‘ app/assets/config/manifest.js’ and copy below three lines in manifest file

//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css

Step 4 – Final Rake Command

$RAILS_ENV=production bundle exec rake redmine:load_default_data

Now test your redmine server using wbrick command.

$bundle exec rails server webrick -e production
http://<host_name>:3000/ 
Redmine on VPS server of Dreamhost

Step 5 – (Optional) Run webrick service as background process

With webrick running in background you need not to start the server again and it runs even after you close the session.

$ruby script/server webrick -e production -du
Or Try following  
$ruby script/server webrick -e development -d

Step 6 – Configuration Steps For Apache Server

1. You need to modify two files for apache. The first is /etc/apache2/mods-available/passenger.conf which needs the text PassengerDefaultUser www-data added as seen below.
<IfModule mod_passenger.c>
PassengerDefaultUser www-data
PassengerRoot /usr
PassengerRuby /usr/bin/ruby
</IfModule>

2. Now create a symlink to connect Redmine into the web document space:

$ sudo ln -s /home/ilmp_redmine/<PWD>/public /var/www/html/redmine
3. And modify /etc/apache2/sites-available/000-default.conf as follows
<Directory /var/www/html/redmine>
RailsBaseURI /redmine
PassengerResolveSymlinksInDocumentRoot on
</Directory>
4. Create and set the ownership of a Gemfile.lock file so that apache’s www-data user can access it:
$ sudo chown www-data:www-data /home/ilmp_redmine/<PWD>/public/Gemfile.lock

5. Now restart apache:

$ sudo service apache2 restart

Feel free to drop a comment or email @ info@blog.neudeep.com, if you get stuck somewhere, we will try to help you as much as possible. Check out our services and offerings at RedmineLab.com

Thank you for reading this post about ‘install redmine on VPS’ happy redmining using dreamhost.

SAME54 I2C Driver Issue Solved

If you are reading this post that means you are using ATMEL or Microchip controller. We are using ATSAME54 micro from microchip, it is ARM based cortex-M4 series controller. In our application we have around eight I2C ( Inter-integrated Circuit) slave devices connected. I2C slave devices includes, RTC, onboard temperature sensor, FRAM, LED drivers etc. Well as you know all I2C slave devices can be addressed using their addresses.

Well as most of guys does we too have downloaded sample code from start.atmel.com and tested. We have SAME54 explained pro and we brought PCA9685 LED driver. This is simple I2C based LED driver and is easily available, its schematic and design also available from adafruit. With sample code and its default address it works like charm, meaning, in first go it starts communicating with LED driver.

Now fun part starts, after verifying this we have incorporated same design in our hardware. After we receive hardware, LED driver is not at all responding, it was not coming out of sleep mode. We have tried all the options, but no luck. Now when we are running same code on explained pro it is working. So only difference was the address. With PCA9685 module connected with explained pro as I2C master, we were using default address ie 0x40. Now when we change this address by shorting address lines, it stops working. We are getting “RXNACK” bit set on (received not acknowledged). Strange thing is if we revert back its address to default address ie 0x40 it works.

When we connected oscilloscope to SDA line we were getting data, ie address then registers.

I2C without driver change

Solution

Well after lot of googling and spending almost two weeks, we found solution, that was issue with ATMEL I2C driver source code generated from start.atmel.com. The solution is very simple once you found out the root cause :-). Yes it is bug in microchip’s I2C driver and its very unique.

I2C is very simple and we suspected hardware. Started with pull up registers for SDA and SCL lines, After trying out with various combinations of pull up registers (4K, 10K, 2.2k) we diverted our attention to I2C drivers. Yes, The culprit is – ‘i2c_m_sync_cmd_read()’ and ‘i2c_m_sync_cmd_write()’ functions from ‘hal\src\hal_i2c_m_sync.c’. The present code it is sending two bytes, but it is expected is to send three bytes. We have modified these read/write commands and it is working. Please note this change is necessary if you are using I2C and code downloaded from atmel start.

Follow below steps to fix this issue,

Open – ‘hal\src\hal_i2c_m_sync.c’

In function ‘i2c_m_sync_cmd_read()’ and ‘i2c_m_sync_cmd_write()’ comment out following code, so after commenting out the functions should look as below,

	struct _i2c_m_msg msg;
int32_t           ret;
#if 0
msg.addr   = i2c->slave_addr;
msg.len    = 1;
msg.flags  = 0;
msg.buffer = ®
ret = _i2c_m_sync_transfer(&i2c->device, &msg);
if (ret != 0) {
/* error occurred */
return ret;
}
#endif
msg.addr   = i2c->slave_addr;
msg.flags  = I2C_M_STOP;
msg.buffer = buffer;
msg.len    = length;
ret = _i2c_m_sync_transfer(&i2c->device, &msg);
if (ret != 0) {
/* error occurred */
return ret;
}
return ERR_NONE;

Now connect oscilloscope and check SDA line, it gives results as expected.

I2C after change in driver

If your I2C slave devices are configured with default addresses ie 0x00, then this change is not required, but remember to make this change every time you download I2C driver code from start.atmel.com. Share your findings on I2C issues while using ATMEL SAME54P20A controller.

Modbus Master Stack On ATSAME54 With RTOS

In previous post we discussed about how to port modbus slave stack on ATSAME54. This post we will discuss on how to port modbus master stack on SAME microcontroller. You can download example freemodbus master stack for reference from FreeModbus. We have referred the ‘AT91SAM7X_FREETROS’ example project. You can follow the steps from previous post for creating directory of project files. Instead of modbus slave stack, add modbus master stack. In addition, We are using FreeRTOS in our project. So In top level directory we have added FreeRTOS V9.0.0 . Please refer to modifications in port specific files described in previous post.

So lets begin with issues while port modbus master stack on SAME, Without an operating systems there are normally no queues available. In case of modbus stack without using RTOS, the queue sending and receiving functions are implemented using a static variable which is set to TRUE when an event is posted. The receive function checks the variable and if TRUE returns the previously stored event. But in case of an RTOS the functions should use a real event queue. We Changed the function xMBPortEventPost() to post an event to a queue. This function will be called from an ISR so we have used xMBPortEventPostFromISR() API for that. This is the interrupt safe version of xMBPortEventPost() provided in FreeRTOS.

We changd the function xMBPortEventGet( ) to retrieve an event from that queue . The function should block until an event has been posted to the queue.

Like this we are calling xQueueCreateStatic() API from vQueueCreate and vQueueDelete() API from vMBPEventDelete .

Next step is to define the functions vMBPEnterCritical( ) and vMBPExitCritical( ) in file portother.c. A switch to another task cannot occur between the calls to vMBPEnterCritical and vMBPExitCritical . Only interrupts whose logical priority is above the value assigned to the configMAX_SYSCALL_INTERRUPT_PRIORITY constant can execute in critical section and interrupts are not permitted to call FreeRTOS API functions. In FreeRTOS there are API’s portENTER_CRITICAL() and portEXIT_CRITICAL() which we have used respectively in above two functions.

Note that if we are calling portENTER_CRITICAL() and portEXIT_CRITICAL() functions from ISR, the following assertion will get fail: configASSERT((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0);

If you are also stuck here, means you are calling these APIs from ISR. In FreeRTOS there are interrupt safe APIs which can be used inside ISR. So here in this case we found following two interrupt safe versions for above functions:

portSET_INTERRUPT_MASK_FROM_ISR() and portCLEAR_INTERRUPT_MASK_FROM_ISR()

Use thses APIs where the function is called from ISR:

In main function, we created two tasks using xTaskCreateStatic() API from FreeRTOS , one is application task and another is for modbus task .

TESTING ON SIMULATOR:

We have now created the modbus master workpace. For testing it, we have to run the modbus slave program on PC side. We are developing the stack on linux system. For this system we found out the Diagslave Modbus Slave Simulator . Install it in your system then execute ‘linux_x86-64/diagslave -h’ It will show the options you can configure. We executed simulator by giving the following command:

After running modbus master program, the simulator showing this output:

Happy to help you during your port modbus master stack on SAME controllers.

Install wxPython With Solved ImportError

This post describes how to install wxPython on ubuntu system and helps with solved build errors while installation. This post assumes you have bare Ubuntu 18.04.3 LTS system and it is newly installed. wxPython is a opensource, cross platform, GUI toolkit for the Python programming.

This post describes in detail for how to install wxpython ubuntu 18.04 for python2 and python3. wxPython allows Python programmers to create programs highly functional graphical

user interface, simply and easily. Being cross platform with little changes it works on Microsoft windows and Linux systems. So if you have GUI application that requires to be executed on both windows and Linux wxPython is right choice for python programmers.

‘pip’ is required as a prior condition for installation of wxPython, install ‘pip’ by running following command

$ sudo apt install python-pip

As per How to install wxPython wiki guide, to install wxPython using ‘pip’ you will need to execute following command

$  pip install -U \
-f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 \
wxPython

This command after successful execution says –

Installing collected packages: six, numpy, pillow, wxPython
Successfully installed numpy-1.16.5 pillow-6.1.0 six-1.12.0 wxPython-4.0.6

Now to test the installation execute below commands

$python2
>>> import wx
>>> wx.VERSION_STRING
'4.0.1'

After executing ‘import wx’ it gives following error

Python 2.7.15+ (default, Nov 27 2018, 23:36:35) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bhagwat/.local/lib/python2.7/site-packages/wx/__init__.py", line 17, in <module>
from wx.core import *
File "/home/bhagwat/.local/lib/python2.7/site-packages/wx/core.py", line 12, in <module>
from ._core import *
ImportError: libpng12.so.0: cannot open shared object file: No such file or directory

Problem is with above installation it is pointing to ‘ubuntu-16.04’ and we are using ‘ubuntu-18.04’, so to fix this issue just execute below command and it will install for ‘ubuntu-18.04’

$ pip install -U  -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04/ wxPython

Verify installation

$ python
Python 2.7.15+ (default, Nov 27 2018, 23:36:35) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
>>> wx.VERSION_STRING
'4.0.6'
>>> 

Install wxPython for python 3

Above steps works for Python 2, but how to install wxPython on python 3 or higher version. so, It seems wxPython is not fully ported for python 3 and above. But, First you will need ‘pip3’ to install wxPython for python 3.

$ sudo apt install python3-pip

So, This will install python3.6-dev and python3-dev, and once ‘pip3’ is installed simply execute following command

$  pip3 install wxPython

This command is failing with following error

    File "build.py", line 30, in <module>
import pathlib2
ModuleNotFoundError: No module named 'pathlib2'
Command '"/usr/bin/python3" -u build.py build' failed with exit code 1.
----------------------------------------
Failed building wheel for wxPython
Running setup.py clean for wxPython
so install 'pathlib2' by running following command
$ pip3 install pathlib2
If above command fails use below command to upgrade 'wxPython' 
$ python3 -m pip install --upgrade --pre -f https://wxpython.org/Phoenix/snapshot-builds/ wxPython

Now if you got following errors:
python-config : not found
Checking for library python3.7m in LIBDIR : not found
Checking for library python3.7m in python_LIBPL : not found
Checking for library python3.7m in $prefix/libs : not found
Checking for library python3.7m in LIBDIR : not found
Checking for library python3.7m in python_LIBPL : not found
Checking for library python3.7m in $prefix/libs : not found
Checking for library python37 in LIBDIR : not found
Checking for library python37 in python_LIBPL : not found
Checking for library python37 in $prefix/libs : not found
Checking for header Python.h : Distutils not installed? Broken python installation? Get python-config now!
The configuration failed

Install new python3.7.4 if above error still there then uninstall wxpython.

$sudo apt-get install python-dev
$pip uninstall wxpython
$sudo apt install libgtk-3-dev

Still, If you are getting following error:
File “/home/.local/lib/python3.8/site-packages/wx/core.py”, line 12, in <module>
from ._core import *
ImportError: libSDL2-2.0.so.0: cannot open shared object file: No such file or directory
To solve:

$sudo apt-get install git curl libsdl2-mixer-2.0-0 libsdl2-image-2.0-0 libsdl2-2.0-0
$pip install -U -f https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04 wxPython

Thats it happy to help you during install wxpython ubuntu 18.04 for python2 and python3. Keep reading and comment out your experiences.

How To Install Ionic Cordova With First Application

Ionic framework is one of the popular development environment for mobile applications. Ionic is popular because of its open source mobile UI toolkit for developing rich cross-platform mobile applications. Cross platform meaning, apps developed using Ionic with single codebase can be executed from iOS(iPhones, iPad), Android and webserver(desktop Applications). It uses technologies like HTML, CSS, Javascript, NodeJS, To start with your first Ionic Application, you need to install Ionic framework. This post describes about installation of Ionic and its required components, running first Ionic application and how to run android application in ionic framework.

Installation

Follow below steps for Ionic framework installation. Assuming you are using fresh Ubuntu system and ‘npm’ is not installed on system, first install ‘npm’ – node package manager for javascript.

$sudo apt-get install npm 

This will install ‘npm’ package. Now download and install Ionic framework on your Ubuntu machine.

$sudo npm install -g ionic
$ionic -v 
5.2.5

We will need node.js, installation step for nodejs is as follows

$sudo apt-get install nodejs

Now install cordova- Apache Cordova is a mobile application development framework and runs on node.js

$sudo npm install -g cordova

Hello Ionic

For creating your first Ionic application follow below steps.

ionic start myapp tabs      #for creating tabs application
ionic start myapp blank     #for creating blank application
ionic start myapp slidemenu #for creating slidemenu application

Now navigate to ‘myapp’ directory and publish your first ionic application. It is as simple as that but for the first time you might encounter following errors – ‘ng run app:serve –host=localhost –port=8100 [ng] An unhandled exception occurred: Could not find module “@angular-devkit/build-angular” from “/home/hello/hello”. [ng] See “/tmp/ng-SmeTji/angular-errors.log” for further details.’

If you get so just un-install and re-install Ionic framework with above mentioned steps.

Now publish application on web-browser

$ionic serve

Run Android Application in Ionic Framework

While there advantages of using Ionic framework over android SDK, but lets not go there and stick to Ionic framework for the simplicity of this post :-).

First step is we need to add platform to the application ie in ‘myapp’ folder execute following command to add android platform

$ionic cordova  platform add android

ionic cordova run android
[ERROR] Sorry! ionic cordova run can only be run in an Ionic project directory.

If this is a project you'd like to integrate with Ionic, run ionic init.
$ionic init
Then build application and execute it 
$ionic cordova build android
$ionic cordova run android
or 
$ionic cordova emulate android

ng run app:ionic-cordova-build –platform=android An unhandled exception occurred: EACCES: permission denied, unlink ‘/home/myapp/www/0-es2015.js’ See “/tmp/ng-QTKII3/angular-errors.log” for further details. [ERROR] An error occurred while running subprocess ng. ng run app:ionic-cordova-build –platform=android exited with exit code 127. Re-running this command with the –verbose flag may provide more information.

These are first time errors and occurred because we have not sent $PATH.

Adding SDK,JDK and Gradle path in ionic project

1. export ANDROID_HOME=/home/Android/Sdk

2. export JAVA_HOME=/home/android-studio-ide-182.5264788-linux/android-studio/jre export

3. export GRADLE_HOME=”/home/gradle/gradle-5.5.1/bin”

4. export PATH=”$PATH:$ANDROID_HOME:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$GRADLE_HOME”

5. echo $ANDROID_HOME

6. echo $JAVA_HOME

7. echo $PATH

With this now you can execute android application in Ionic Framework.

Port Modbus Slave Stack On ATSAME54

We are referring modbus server stack implementation for SAM3X and We want to port it on SAME54P20A. First we have downloaded the example project for SAME54P20A which is using Usart_Asynchrnous module from Atmel START. Then create new top level directory for project files. Following files needs modification while porting, they are present in sub directory named ‘port’ which will contain all port specific files,

  • portserial.c
  • porttimer.c
  • portevent.c
  • portother.c
  • port.h

Atmel start project is having makefile in sub-directory ‘gcc’. Add these port specific files paths in makefile. Then add modbus stack folder to top level directory which is having all the modbus specific functions. For compilation we hav to add these all file paths in makefile which is in gcc directory. We have to first check the ‘port.h’ file whether it is suitable for our platform. If not ,then we have to define platform specific functions for serial interface,timer driver.

portserial.c: In this file there are functions for initializing USART, enabling and disabling USART module, enabling and disabling the receiver and transmitter. For enabling and disabling transmitter and receiver, we need to use corresponding low level API’s of ATSAME54P20A from ‘hri’ folder. The reference code for ATSAm3S:

Changes we have to do for ATSAME54:

In reference program for SAM3X they are using vUSARTHandler() interrupt handler in which they are checking for Rx or Tx interrupt invoked according to that respective xMBPortSerialGetByte(), xMBPortSerialPutByte() functions are called.

For SAME54P20A, there is an API- ‘usart_async_register_callback()’ so instead of ‘vUSARTHandler’, we have to create two different interrupt service routines one is for Rx interrupt and another for Tx interrupt.

portimer.c: The modbus protocol stack requires timer for detection of end of the frame. There are API’s available in SAME54P20A timer driver for initializing ,enabling and disabling the timer. For SAM3X they are using timer interrupt function TCX_IRQHANDLER() which is calling pxMBPortCBTimerExpired() function.

For ATSAME54P20A, there is timer task structure. So instead of using timer_handler we have to initialize timer structure which is having callback function in which we will call ‘pxMBPortCBTimerExpired()’ function.

If you are using FreeRTOS in your project then you need to modify ‘portevent.c’, We are not using rtos in our project so will not discuss on updating portevent functions. In next section we will update on it.

How To Use Two Timers In Same Project

If you are using SAM series controller you probably have came across this question, How do i implement two timer which generate two interrupt at different time in same project? or How we can use two timer in same project in SAME54 controller? Well SAM series controller are ARM-based MCUs and MPUs from ATMEL now Microchip.

We are using ATSAME54P20A ie SAME54 explained pro board to evaluate the functionality of it. So created new project using start.atmel.com with TC0 and TC1 along with WDT and interrputs. The project tree looks as below,

This project works well and TC0 timer interrupt is working but TC1 timer interrupt is not working. Following is code for initialization and using timer.

	TIMER_1_task1.interval = 50;
TIMER_1_task1.cb       = TIMER_1_task1_cb;
TIMER_1_task1.mode     = TIMER_TASK_REPEAT;
timer_add_task(&TIMER_1, &TIMER_1_task1);
TIMER_0_task1.interval = 10;
TIMER_0_task1.cb       = TIMER_0_task1_cb;
TIMER_0_task1.mode     = TIMER_TASK_REPEAT;
timer_add_task(&TIMER_0, &TIMER_0_task1);
timer_start(&TIMER_0);
timer_start(&TIMER_1);

Put breakpoint in ‘TIMER_1_task1_cb’ function and it never hits breakpoint, but it hits breakpoint in ‘TIMER_0_task1_cb’ function. When we check out status flag of timer1, as soon as it initializes TC0 using ‘TIMER_0_init()’ from driver_init.c it sets ‘STOP’ and ‘SLAVE’ bit.

Bit 1 – SLAVE Slave Status Flag
This bit is only available in 32-bit mode on the slave TC (i.e., TC1 and/or TC3). The bit is set when the associated master TC (TC0 and TC2, respectively) is set to run in 32-bit mode.
Bit 0 – STOP Stop Status Flag
This bit is set when the TC is disabled, on a Stop command, or on an overflow/underflow condition when the One-Shot bit in the Control B Set register (CTRLBSET.ONESHOT) is ‘1’.

Problem is while using start.atmel.com configuration there is no option to set timer in 8 bit or 16 bit or 32 bit mode. By default when we create project it sets in 32-bit mode.

Solution to this issue is set both timers in either 16-bit or 8 bit mode. The settings can be found in “Config\hpl_tc_config.h” file. The change should look like as below

#ifndef CONF_TC0_MODE
#define CONF_TC0_MODE TC_CTRLA_MODE_COUNT16_Val
#endif
#ifndef CONF_TC1_MODE
#define CONF_TC1_MODE TC_CTRLA_MODE_COUNT16_Val
#endif

With this change both timers are working.

How To Write RTOS Safe ISR For ATSAME

In our application it is required to use FreeRTOS API functions from an interrupt service routine(ISR). Good thing about FreeRTOS is it has provided interrupt safe API, meaning one can use FreeRTOS API functions from ISR, as they have provided two versions of some API. Functions intended for use from ISRs have “FromISR” appended to their name eg. xQueueSendFromISR

In our application we were using xQueueSendFromISR() from IRQ10 ie ‘EIC_10_IRQn’, to send message to other task, code snippet is as below

void sendMsgToIoTaskFromISR(int eventId, int data)
{
Task_EventMsg_t evtMsg;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;   	// wake up the higher priority task
evtMsg.eventId = eventId;
evtMsg.iData = data;    
if( xQueueSendFromISR( gIo.ioMgrQHandle, ( void * ) &evtMsg, &xHigherPriorityTaskWoken ) != pdPASS )
{
}
/* If the task with handle xTaskToNotify was blocked waiting for the notification
then sending the notification will have removed the task from the Blocked
state.  If the task left the Blocked state, and if the priority of the task
is higher than the current Running state task (the task that this interrupt
interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE
internally within vTaskNotifyGiveFromISR().  Passing pdTRUE into the
portEND_SWITCHING_ISR() macro will result in a context switch being pended to
ensure this interrupt returns directly to the unblocked, higher priority,
task.  Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */	
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}

With this it is calling assert using function “portASSERT_IF_INTERRUPT_PRIORITY_INVALID();” when we did some digging it is failing because of the condition ‘ucCurrentPriority >= ucMaxSysCallPriority’ . The reason to fail this condition is ‘ ucCurrentPriority’ is ‘0’ and ucMaxSysCallPriority is 128 (0x80). After reading FreeRTOS documentation on how ISR priorities are set. It is understood that ISR priorities are set to ‘0’ by controller and RTOS expects the priority to be ‘128’ or above, as recommended below:

 Remember that ARM Cortex-M cores use numerically low priority numbers to represent HIGH priority interrupts. This can seem counter-intuitive and is easy to forget! If you wish to assign an interrupt a low priority do NOT assign it a priority of 0 (or other low numeric value) as this will result in the interrupt actually having the highest priority in the system – and therefore potentially make your system crash if this priority is above configMAX_SYSCALL_INTERRUPT_PRIORITY. Also, do not leave interrupt priorities unassigned, as by default they will have a priority of 0 and therefore the highest priority possible.

That is suggestion from FreeRTOS, but how to change priority of interrupts, To solve this issue we have done workaround, probably it might help someone. In ‘hpl_eic.c’ file from “hpl\eic” folder, in function “_ext_irq_init” change the priority of IRQ10 to 128 or more that that. Simply add below line

#define NVIC_SIGNAL_PRI_80		(configKERNEL_INTERRUPT_PRIORITY+4)
NVIC_SetPriority(EIC_10_IRQn, NVIC_SIGNAL_PRI_80);

Your new code should look like

	NVIC_DisableIRQ(EIC_10_IRQn);
NVIC_ClearPendingIRQ(EIC_10_IRQn);
NVIC_EnableIRQ(EIC_10_IRQn);
NVIC_SetPriority(EIC_10_IRQn, NVIC_SIGNAL_PRI_80);

Compile and test this new code and you will see interrupts are working in your RTOS.

This trick of setting interrupt priority to 0x80 works well for other interrupts as well, like timer interrupt, External interrupts etc. Just make sure that in init function for that I/O you are calling NVIC_SetPriority() function… Happy RTOS safe ISRing..

Further Reading [PDF]Mastering the FreeRTOS™ Real Time Kernel

How To Use WDT On Free RTOS Running ATSAMEx

After doing some google and spending almost 4 hours on choosing right place to start WDT, we have decided to share our learning here. Well we are using ATSAME54P19/20 controller from Microchip formally Atmel. Watchdog timer – WDT works well without Free RTOS (10.0) but when WDT is enabled along with RTOS it simply does not work well.

In big while(1) embedded applications with no RTOS you can always initialize WDT after peripheral initialization and feed/touch WDT in while/main loop. In case of RTOS there are multiple tasks/threads and to be specific in case for Free RTOS when you try to enable WDT right before vTaskStartScheduler(); call it simply does not work.

Tried with following solutions – like configure WDT for 20 sec reset time. And enable WDT just before scheduler starts. WDT is not waiting till expiry it is immediately resetting. Then tried enabling WDT after scheduler has started but no luck.

So tried with the RTOS Hook functions . Every RTOS provides hook functions for user application. There are few hook functions in Free RTOS as well. First tried with Idle Hook function by setting configUSE_IDLE_HOOK to 1 within FreeRTOSConfig.h, but it seems this vApplicationIdleHook() function gets called only when there is nothing to be done by other tasks. In our application we have 4 tasks, along with timers enabled in it. This is reason the vApplicationIdleHook() function was not getting executed.

There is other hook function ie tick hook function vApplicationTickHook(), but that is getting called at every tick. Enabling WDT at every tick is not right place. So we need some hook function which will be called once after the RTOS scheduler is initialized. And vApplicationDaemonTaskStartupHook() is the right function. Initialize this hook by setting configUSE_DAEMON_TASK_STARTUP_HOOK to 1 in FreeRTOSConfig.h , put your WDT initialization and enable code here. From any other task or timer task you can feed WDT (wdt_feed(&WDT_0);).

void vApplicationDaemonTaskStartupHook(void)
{
#ifdef WDT_IN_USE 
uint32_t clk_rate;
uint16_t timeout_period;
clk_rate       = 1000;
timeout_period = 4096;
wdt_set_timeout_period(&WDT_0, clk_rate, timeout_period);
wdt_enable(&WDT_0);
#endif
}

Happy WDT testing with RTOS on ATMEL controllers 🙂

Ceedling Unit Testing With ATSAME54

This post is continuation of previous post on how to mock local variable in ceedling, please check out previous post before continuing with this article. Another issue is having to add all the microchip files.

When CMock gets a hold of the header file it looks at all the functions defined there and generates several mock functions for each.

In one program, we are dealing with 4 pins of microcontroller. The pin numbers and its functions are defined in file ‘atmel_start_pins.h’ which is included in our project. But inside this file there are definitions for all the pins and ‘hal.gpio.h’ file is included. Inside ‘hal.gpio.h’ file, another files are included. The original atmel_start_pins.h file is like below, We need only 4 pins from this file:

The function under test is :

Solution:

Instead of wasting memory we can create our own file ‘atmel_start_pins.h’ for unit testing. The file will contain The function declarations we want to mock and only the required data.

In above function INPUT_ENTER_KEY,INPUT_BACK_KEY etc are having values as follwing :

These PB_1,PB_2,PB_3,PB_4 are defined in file ‘atmel_start_pins.h’. So we can create our own ‘atmel_start_pins.h’ file which is having only requied data .The new file is like:

Now we can mock this required function and interfaces. We can just assign any numbers for PB_1,PB_2,PB_3,PB_4 . Pass these pin numbers in test cases.

we able to unit test without memory wastage.